OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "entd/pkcs11.h" | 5 #include "entd/pkcs11.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iostream> | 8 #include <iostream> |
9 #include <map> | 9 #include <map> |
10 #include <string> | 10 #include <string> |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 private: | 107 private: |
108 // The certificate may contain binary data, so store it as an array of bytes | 108 // The certificate may contain binary data, so store it as an array of bytes |
109 // instead of a string. | 109 // instead of a string. |
110 chromeos::Blob certificate_; | 110 chromeos::Blob certificate_; |
111 std::string subject_; | 111 std::string subject_; |
112 static Pkcs11CertificateHandler* certificate_handler_; | 112 static Pkcs11CertificateHandler* certificate_handler_; |
113 | 113 |
114 DISALLOW_COPY_AND_ASSIGN(Certificate); | 114 DISALLOW_COPY_AND_ASSIGN(Certificate); |
115 }; | 115 }; |
116 | 116 |
117 // class Pkcs11CertificateHandlerLocalFile | 117 // class Pkcs11TestCertificateHandler |
118 // Test Certificate handler that returns the contents of a file. | 118 // Test Certificate handler |
119 // | 119 class Pkcs11TestCertificateHandler : public Pkcs11CertificateHandler { |
120 // If the csr or cert file exists, the contents of the file is returned | |
121 // in BuildCSR or BuildCertificate; subject or content arguments are ignored. | |
122 // If the filename is empty or the file does not exist, a string | |
123 // containing the subject or content is returned instead. | |
124 class Pkcs11CertificateHandlerLocalFile : public Pkcs11CertificateHandler { | |
125 public: | 120 public: |
126 Pkcs11CertificateHandlerLocalFile(const std::string& csr, | 121 Pkcs11TestCertificateHandler() {} |
127 const std::string& cert) | 122 virtual ~Pkcs11TestCertificateHandler() {} |
128 : csr_filename_(csr), certificate_filename_(cert) { | |
129 if (!csr_filename_.empty()) | |
130 LOG(INFO) << "Using local CSR file: " << csr_filename_; | |
131 if (!certificate_filename_.empty()) | |
132 LOG(INFO) << "Using local Cert file: " << certificate_filename_; | |
133 } | |
134 virtual ~Pkcs11CertificateHandlerLocalFile() {} | |
135 virtual bool Initialize() { return true; } | 123 virtual bool Initialize() { return true; } |
136 | 124 |
137 virtual bool BuildCSR(const std::string& label, | 125 virtual bool BuildCSR(const std::string& label, |
138 const std::string& subject, | 126 const std::string& subject, |
139 std::string* csr) { | 127 std::string* csr) { |
140 if (!csr_filename_.empty()) | 128 // Use the subject as the CSR string. |
141 file_util::ReadFileToString(FilePath(csr_filename_), csr); | 129 *csr = subject; |
142 if (csr->empty()) { | |
143 // Default CSR string if not read from a file | |
144 *csr = std::string("<CSR subject=") + subject + " />"; | |
145 } | |
146 return true; | 130 return true; |
147 } | 131 } |
148 | 132 |
149 virtual bool BuildCertificate(const std::string& content, | 133 virtual bool BuildCertificate(const std::string& content, |
150 chromeos::Blob* certificate, | 134 chromeos::Blob* certificate, |
151 std::string* subject) { | 135 std::string* subject) { |
152 std::string subjectstr; | 136 // Use the unmodified content for the certificate. |
| 137 certificate->resize(content.length()); |
| 138 memcpy(&(certificate->front()), content.c_str(), content.length()); |
| 139 *subject = "Test"; |
153 | 140 |
154 if (!certificate_filename_.empty()) { | |
155 // Try reading the certificate from the filename set at construction. | |
156 FilePath filepath(certificate_filename_); | |
157 int64 filesize; | |
158 bool file_read = file_util::GetFileSize(filepath, &filesize); | |
159 if (file_read) { | |
160 certificate->resize(filesize); | |
161 char* dest = reinterpret_cast<char*>(&(certificate->front())); | |
162 int res = file_util::ReadFile(filepath, dest, filesize); | |
163 if (res == filesize) { | |
164 *subject = std::string("File: ") + certificate_filename_; | |
165 } else { | |
166 file_read = false; | |
167 } | |
168 } | |
169 if (!file_read) { | |
170 LOG(ERROR) << "Error reading file: " << filepath.value(); | |
171 return false; | |
172 } | |
173 } else { | |
174 // Use a test string for debugging. | |
175 std::string certstr = | |
176 std::string("<Certificate content=") + content + " />"; | |
177 certificate->resize(certstr.length()); | |
178 memcpy(&(certificate->front()), certstr.c_str(), certstr.length()); | |
179 *subject = "Content"; | |
180 } | |
181 return true; | 141 return true; |
182 } | 142 } |
183 | 143 |
184 private: | 144 private: |
185 std::string csr_filename_; | 145 DISALLOW_COPY_AND_ASSIGN(Pkcs11TestCertificateHandler); |
186 std::string certificate_filename_; | |
187 }; | |
188 | |
189 // Class Pkcs11CertificateHandlerOpenSsl | |
190 // Implements CSR generation using 'system("openssl req...")'. | |
191 class Pkcs11CertificateHandlerOpenSsl : public Pkcs11CertificateHandler { | |
192 public: | |
193 Pkcs11CertificateHandlerOpenSsl() : use_DER_format_(false) {} | |
194 | |
195 virtual ~Pkcs11CertificateHandlerOpenSsl() {} | |
196 | |
197 virtual bool Initialize() { return true; } | |
198 | |
199 // If called, openssl will be told to convert the certificate to DER format. | |
200 // DER is the format that opencryptoki expects. | |
201 void SetOutputDER() { use_DER_format_ = true; } | |
202 | |
203 virtual bool BuildCSR(const std::string& label, | |
204 const std::string& subject, | |
205 std::string* csr) { | |
206 // temporary filenames | |
207 FilePath temp_dir; | |
208 file_util::GetTempDir(&temp_dir); | |
209 FilePath private_key_fp = temp_dir.Append("privkey"); | |
210 FilePath csr_fp = temp_dir.Append("csr"); | |
211 | |
212 // Get the passphrase for the private key from the slot handler | |
213 std::string passphrase = slot_handler()->GetPassphrase(label); | |
214 | |
215 // *TODO: replace with calls to libopenssl to avoid system() call. | |
216 if (!CheckString(subject) || | |
217 !CheckString(passphrase)) { | |
218 return false; | |
219 } | |
220 std::string cmd = | |
221 std::string("openssl req -new -batch -newkey rsa:2048") | |
222 + " -keyout " + private_key_fp.value() | |
223 + " -subj \"" + subject + "\"" | |
224 + " -pubkey -out " + csr_fp.value(); | |
225 if (!passphrase.empty()) | |
226 cmd += " -passout pass:" + passphrase; | |
227 else | |
228 cmd += " -nodes"; | |
229 CallSystem(cmd); | |
230 | |
231 // get the results from the temporary files | |
232 std::string csr_output; | |
233 if (file_util::ReadFileToString(csr_fp, &csr_output)) { | |
234 csr_ = GetCertSection(csr_output, | |
235 "-----BEGIN CERTIFICATE REQUEST-----", | |
236 "-----END CERTIFICATE REQUEST-----"); | |
237 public_key_ = GetCertSection(csr_output, | |
238 "-----BEGIN PUBLIC KEY-----", | |
239 "-----END PUBLIC KEY-----"); | |
240 } | |
241 file_util::ReadFileToString(private_key_fp, &private_key_); | |
242 | |
243 // remove temporary files | |
244 file_util::Delete(private_key_fp, false); | |
245 file_util::Delete(csr_fp, false); | |
246 | |
247 // Convert the pivate key to DER format and pass it to the slot handler. | |
248 if (use_DER_format_ && !private_key_.empty()) { | |
249 chromeos::Blob key_der; | |
250 if (!ConvertToDER(private_key_, passphrase, &key_der)) | |
251 return false; | |
252 if (!slot_handler()->AddPrivateKey(label, subject, key_der)) | |
253 return false; | |
254 } | |
255 | |
256 *csr = csr_; | |
257 | |
258 return true; | |
259 } | |
260 | |
261 // Include the private key (encoded with the SlotObject's passphrase) | |
262 // with the certificate so that it can be decoded with the passphrase. | |
263 virtual bool BuildCertificate(const std::string& content, | |
264 chromeos::Blob* certificate, | |
265 std::string* subject) { | |
266 FilePath temp_dir; | |
267 file_util::GetTempDir(&temp_dir); | |
268 FilePath cert_pem_fp = temp_dir.Append("cert.pem"); | |
269 FilePath cert_der_fp = temp_dir.Append("cert.der"); | |
270 FilePath subject_fp = temp_dir.Append("subject"); | |
271 | |
272 if (content.empty()) { | |
273 LOG(ERROR) << "BuildCertificate called with empty content"; | |
274 return false; | |
275 } | |
276 | |
277 // Write the content string to a temporary file | |
278 // to use as the certificate contents. | |
279 int res = file_util::WriteFile( | |
280 cert_pem_fp, content.c_str(), content.length()); | |
281 if (res < 0) { | |
282 LOG(ERROR) << "Unable to write temporary file: " << cert_pem_fp.value(); | |
283 return false; | |
284 } | |
285 | |
286 { | |
287 // Use openssl to write the subject and (if needed) | |
288 // the DER version of the certificate | |
289 // *TODO: replace with calls to libopenssl to avoid system() call. | |
290 std::string cmd("openssl x509"); | |
291 cmd += " -inform PEM -in " + cert_pem_fp.value(); | |
292 if (use_DER_format_) | |
293 cmd += " -outform DER -out " + cert_der_fp.value(); | |
294 else | |
295 cmd += " -noout"; | |
296 cmd += " -subject > " + subject_fp.value(); | |
297 bool res = CallSystem(cmd); | |
298 | |
299 file_util::Delete(cert_pem_fp, false); | |
300 if (!res) { | |
301 file_util::Delete(cert_der_fp, false); | |
302 file_util::Delete(subject_fp, false); | |
303 return false; | |
304 } | |
305 } | |
306 | |
307 if (use_DER_format_) { | |
308 // read in the DER version of the certificate. | |
309 int64 certlen; | |
310 int res = -1; | |
311 if (file_util::GetFileSize(cert_der_fp, &certlen)) { | |
312 certificate->resize(certlen); | |
313 char* dest = reinterpret_cast<char*>(&(certificate->front())); | |
314 res = file_util::ReadFile(cert_der_fp, dest, certlen); | |
315 } | |
316 file_util::Delete(cert_der_fp, false); | |
317 if (res != certlen) { | |
318 LOG(ERROR) << "Unable to read DER file: " << cert_der_fp.value(); | |
319 file_util::Delete(subject_fp, false); | |
320 certificate->clear(); | |
321 return false; | |
322 } | |
323 } else { | |
324 std::string certstr; | |
325 if (!content.empty()) { | |
326 // Include content provided by script. | |
327 certstr = content; | |
328 } else { | |
329 // Include the (test) certificate file. | |
330 int64 certlen; | |
331 int res = -1; | |
332 if (file_util::GetFileSize(cert_pem_fp, &certlen)) { | |
333 const int cert_max_length = 256*1024; | |
334 if (certlen < cert_max_length) { | |
335 char* certvec = new char[certlen]; | |
336 res = file_util::ReadFile(cert_pem_fp, &certvec[0], certlen); | |
337 if (res == certlen) { | |
338 certstr = std::string(certvec, certlen); | |
339 } | |
340 } | |
341 } | |
342 } | |
343 // Append the private key. | |
344 certstr += private_key_; | |
345 // Copy to certificate. | |
346 certificate->resize(certstr.length()); | |
347 memcpy(&(certificate->front()), certstr.c_str(), certstr.length()); | |
348 } | |
349 | |
350 { | |
351 // read in the subject | |
352 int64 subjectlen; | |
353 int res = -1; | |
354 if (file_util::GetFileSize(subject_fp, &subjectlen)) { | |
355 const int subject_max_length = 4096; | |
356 if (subjectlen < subject_max_length) { | |
357 char* subjectvec = new char[subjectlen]; | |
358 res = file_util::ReadFile(subject_fp, &subjectvec[0], subjectlen); | |
359 if (res == subjectlen) { | |
360 const std::string headerstr("subject= "); | |
361 std::string subjstr(subjectvec, subjectlen); | |
362 std::string::size_type idx = subjstr.find(headerstr); | |
363 if (idx != std::string::npos) | |
364 subject->assign(subjstr.substr(idx + headerstr.length())); | |
365 else | |
366 subject->assign(subjstr); | |
367 } | |
368 } | |
369 } | |
370 file_util::Delete(subject_fp, false); | |
371 if (res != subjectlen) { | |
372 LOG(ERROR) << "Unable to read subject file: " << subject_fp.value(); | |
373 return false; | |
374 } | |
375 } | |
376 | |
377 return true; | |
378 } | |
379 | |
380 protected: | |
381 bool ConvertToDER(const std::string& key, | |
382 const std::string& passphrase, | |
383 chromeos::Blob* key_der) { | |
384 FilePath temp_dir; | |
385 file_util::GetTempDir(&temp_dir); | |
386 FilePath key_pem_fp = temp_dir.Append("key.pem"); | |
387 FilePath key_der_fp = temp_dir.Append("key.der"); | |
388 | |
389 // Write the key to a temporary file | |
390 int res = file_util::WriteFile(key_pem_fp, key.c_str(), key.length()); | |
391 if (res < 0) { | |
392 LOG(ERROR) << "Unable to write temporary file: " << key_pem_fp.value(); | |
393 return false; | |
394 } | |
395 | |
396 // Use openssl to write the the DER version of the key | |
397 // *TODO: replace with calls to libopenssl to avoid system() call. | |
398 if (!CheckString(passphrase)) { | |
399 return false; | |
400 } | |
401 std::string cmd = std::string("openssl rsa") | |
402 + " -inform PEM -in " + key_pem_fp.value() | |
403 + " -outform DER -out " + key_der_fp.value(); | |
404 if (!passphrase.empty()) | |
405 cmd += " -passin pass:" + passphrase; | |
406 CallSystem(cmd); | |
407 | |
408 // read in the DER version of the key. | |
409 int64 keylen; | |
410 res = -1; | |
411 if (file_util::GetFileSize(key_der_fp, &keylen)) { | |
412 key_der->resize(keylen); | |
413 char* dest = reinterpret_cast<char*>(&(key_der->front())); | |
414 res = file_util::ReadFile(key_der_fp, dest, keylen); | |
415 } | |
416 | |
417 file_util::Delete(key_pem_fp, false); | |
418 file_util::Delete(key_der_fp, false); | |
419 | |
420 if (res != keylen) { | |
421 LOG(ERROR) << "Unable to read key DER file: " << key_der_fp.value(); | |
422 return false; | |
423 } | |
424 return true; | |
425 } | |
426 | |
427 // Return the substring of 's' | |
428 // starting with 'begin' and ending with 'end' (inclusive) | |
429 std::string GetCertSection(const std::string& s, | |
430 const std::string& begin, | |
431 const std::string& end) { | |
432 std::string::size_type idx0 = s.find(begin); | |
433 std::string::size_type idx1 = s.find(end); | |
434 if (idx0 == std::string::npos || idx1 == std::string::npos) { | |
435 LOG(WARNING) << "Unable to find section: [" | |
436 << begin << ", " << end << "]"; | |
437 LOG(WARNING) << "In:\n" << s; | |
438 return std::string(); | |
439 } | |
440 return s.substr(idx0, (idx1 + end.length()) - idx0); | |
441 } | |
442 | |
443 bool CheckString(const std::string& instr) { | |
444 for (std::string::const_iterator iter = instr.begin(); | |
445 iter != instr.end(); ++iter) { | |
446 char c = *iter; | |
447 if (c == '"') { | |
448 LOG(ERROR) << "Invalid string: " << instr; | |
449 return false; | |
450 } | |
451 } | |
452 return true; | |
453 } | |
454 | |
455 bool CallSystem(const std::string& cmd) { | |
456 LOG(INFO) << "Calling system(" << cmd << ");"; | |
457 int res = system(cmd.c_str()); | |
458 if (res != 0) { | |
459 LOG(WARNING) << "Error executing command: '" << cmd << "'\n" | |
460 << " result = " << res; | |
461 return false; | |
462 } | |
463 return true; | |
464 } | |
465 | |
466 bool use_DER_format_; | |
467 | |
468 std::string csr_; | |
469 std::string certificate_; | |
470 std::string private_key_; | |
471 std::string public_key_; | |
472 }; | |
473 | |
474 // In this implementation, instead of generating a public/private key pair, | |
475 // use engine_pkcs11 to get the keys from the TPM. | |
476 class Pkcs11CertificateHandlerOpenSslPkcs11Engine : | |
477 public Pkcs11CertificateHandlerOpenSsl { | |
478 | |
479 public: | |
480 void SetEngineConfigFile(const std::string& filename) { | |
481 engine_config_file_ = filename; | |
482 } | |
483 | |
484 virtual bool BuildCSR(const std::string& label, | |
485 const std::string& subject, | |
486 std::string* csr) { | |
487 FilePath temp_dir; | |
488 file_util::GetTempDir(&temp_dir); | |
489 FilePath csr_fp = temp_dir.Append("csr"); | |
490 | |
491 csr_.clear(); | |
492 | |
493 if (engine_config_file_.empty()) { | |
494 LOG(ERROR) << "BuildCSR called with no engine config file specified."; | |
495 return false; | |
496 } | |
497 | |
498 // *TODO: replace with calls to libopenssl to avoid system() call. | |
499 std::string keyid = slot_handler()->GetKeyIdentifier(label); | |
500 std::stringstream cmd; | |
501 if (!CheckString(subject)) { | |
502 return false; | |
503 } | |
504 cmd << "openssl req -new -batch" | |
505 << " -config " << engine_config_file_ << " -engine pkcs11" | |
506 << " -key " << keyid << " -keyform engine" | |
507 << " -subj \"" << subject << "\"" | |
508 << " -out " << csr_fp.value(); | |
509 CallSystem(cmd.str()); | |
510 | |
511 bool res = file_util::ReadFileToString(csr_fp, &csr_); | |
512 if (!res) { | |
513 LOG(ERROR) << "Unable to read CSR file: " << csr_fp.value(); | |
514 return false; | |
515 } | |
516 | |
517 // remove temporary files | |
518 file_util::Delete(csr_fp, false); | |
519 | |
520 *csr = csr_; | |
521 | |
522 return true; | |
523 } | |
524 | |
525 // BuildCertificate() is the same as in the parent class, | |
526 // but note that private_key_ will be empty, so nothing will be | |
527 // appended to the certificate contents (as desired). | |
528 | |
529 private: | |
530 std::string engine_config_file_; | |
531 }; | 146 }; |
532 | 147 |
533 // Class Pkcs11CertificateHandlerLibOpenSsl | 148 // Class Pkcs11CertificateHandlerLibOpenSsl |
534 // Implements CSR generation using the openssl crypto library | 149 // Implements CSR generation using the openssl crypto library |
535 class Pkcs11CertificateHandlerLibOpenSsl : public Pkcs11CertificateHandler { | 150 class Pkcs11CertificateHandlerLibOpenSsl : public Pkcs11CertificateHandler { |
536 public: | 151 public: |
537 Pkcs11CertificateHandlerLibOpenSsl() {} | 152 Pkcs11CertificateHandlerLibOpenSsl() {} |
538 | 153 |
539 virtual ~Pkcs11CertificateHandlerLibOpenSsl() {} | 154 virtual ~Pkcs11CertificateHandlerLibOpenSsl() {} |
540 | 155 |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 } | 503 } |
889 | 504 |
890 static const long kRsaKeyLength; | 505 static const long kRsaKeyLength; |
891 static const long kRsaKeyExponent; | 506 static const long kRsaKeyExponent; |
892 static const long kMaxFilePath; | 507 static const long kMaxFilePath; |
893 | 508 |
894 std::string csr_; | 509 std::string csr_; |
895 std::string certificate_; | 510 std::string certificate_; |
896 std::string public_key_; | 511 std::string public_key_; |
897 chromeos::Blob private_key_der_; | 512 chromeos::Blob private_key_der_; |
| 513 |
| 514 DISALLOW_COPY_AND_ASSIGN(Pkcs11CertificateHandlerLibOpenSsl); |
898 }; | 515 }; |
899 | 516 |
900 // Use 2048 bits for the key length, and an exponent of 0x10001. | 517 // Use 2048 bits for the key length, and an exponent of 0x10001. |
901 const long Pkcs11CertificateHandlerLibOpenSsl::kRsaKeyLength = 2048; | 518 const long Pkcs11CertificateHandlerLibOpenSsl::kRsaKeyLength = 2048; |
902 const long Pkcs11CertificateHandlerLibOpenSsl::kRsaKeyExponent = 0x10001; | 519 const long Pkcs11CertificateHandlerLibOpenSsl::kRsaKeyExponent = 0x10001; |
903 // Max number of chars for local array allocation for file paths. | 520 // Max number of chars for local array allocation for file paths. |
904 const long Pkcs11CertificateHandlerLibOpenSsl::kMaxFilePath = 1024; | 521 const long Pkcs11CertificateHandlerLibOpenSsl::kMaxFilePath = 1024; |
905 | 522 |
906 | 523 |
907 // Class Pkcs11SlotHandlerInMemory | 524 // Class Pkcs11SlotHandlerInMemory |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1059 ObjectMap::iterator iter = objects_.find(label); | 676 ObjectMap::iterator iter = objects_.find(label); |
1060 if (iter == objects_.end()) { | 677 if (iter == objects_.end()) { |
1061 return false; | 678 return false; |
1062 } else { | 679 } else { |
1063 objects_.erase(iter); // Will delete Object | 680 objects_.erase(iter); // Will delete Object |
1064 return true; | 681 return true; |
1065 } | 682 } |
1066 } | 683 } |
1067 | 684 |
1068 ObjectMap objects_; | 685 ObjectMap objects_; |
| 686 |
1069 DISALLOW_COPY_AND_ASSIGN(Pkcs11SlotHandlerInMemory); | 687 DISALLOW_COPY_AND_ASSIGN(Pkcs11SlotHandlerInMemory); |
1070 }; | 688 }; |
1071 | 689 |
1072 | 690 |
1073 // Class Pkcs11SlotHandlerOpenCryptoki | 691 // Class Pkcs11SlotHandlerOpenCryptoki |
1074 // Inherits from Pkcs11SlotHandlerInMemory to share memory mapping of objects | 692 // Inherits from Pkcs11SlotHandlerInMemory to share memory mapping of objects |
1075 class Pkcs11SlotHandlerOpenCryptoki : public Pkcs11SlotHandlerInMemory { | 693 class Pkcs11SlotHandlerOpenCryptoki : public Pkcs11SlotHandlerInMemory { |
1076 public: | 694 public: |
1077 Pkcs11SlotHandlerOpenCryptoki() | 695 Pkcs11SlotHandlerOpenCryptoki() |
1078 : user_pin_(""), slot_index_(0), slot_id_(0) { } | 696 : user_pin_(""), slot_index_(0), slot_id_(0) { } |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1760 return chromeos::AsciiEncode(bytes); | 1378 return chromeos::AsciiEncode(bytes); |
1761 } | 1379 } |
1762 | 1380 |
1763 std::string user_pin_; | 1381 std::string user_pin_; |
1764 CK_ULONG slot_index_; | 1382 CK_ULONG slot_index_; |
1765 CK_SLOT_ID slot_id_; | 1383 CK_SLOT_ID slot_id_; |
1766 | 1384 |
1767 DISALLOW_COPY_AND_ASSIGN(Pkcs11SlotHandlerOpenCryptoki); | 1385 DISALLOW_COPY_AND_ASSIGN(Pkcs11SlotHandlerOpenCryptoki); |
1768 }; | 1386 }; |
1769 | 1387 |
1770 // In "GLaptop mode" we generate the key pair using openssl, and call | 1388 // Pkcs11CertificateHandlerLibOpenSsl generates its own key pair, |
1771 // AddPrivateKey() instead, so GenerateKeyPair() needs to be a no-op. | 1389 // which is what we would prefer to use. However, engine_pkcs11 |
1772 class Pkcs11SlotHandlerGLaptop : public Pkcs11SlotHandlerOpenCryptoki { | 1390 // is not currently working correctly, and there is no known |
| 1391 // implementation that can generate a CSR using the TPM generated key pair. |
| 1392 // (The current implementaiton of Pkcs11CertificateHandlerLibOpenSsl calls |
| 1393 // AddPrivateKey() instead). |
| 1394 // Rather than eliminate the poentially useful (and non-trivial) code in |
| 1395 // Pkcs11SlotHandlerOpenCryptoki, override the class with a GenerateKeyPair() |
| 1396 // method that just sets the passphrase and ensures that the object exists. |
| 1397 class Pkcs11SlotHandlerOpenCryptokiNoKeyGen : |
| 1398 public Pkcs11SlotHandlerOpenCryptoki { |
1773 public: | 1399 public: |
1774 Pkcs11SlotHandlerGLaptop() {} | 1400 Pkcs11SlotHandlerOpenCryptokiNoKeyGen() {} |
1775 | 1401 |
| 1402 // Don't actually generate a key pair; rely on AddPrivateKey() getting |
| 1403 // called instead. |
1776 virtual bool GenerateKeyPair(const std::string& label, | 1404 virtual bool GenerateKeyPair(const std::string& label, |
1777 const std::string& passphrase) { | 1405 const std::string& passphrase) { |
1778 Object* obj = GetObject(label); | 1406 Object* obj = GetObject(label); |
1779 if (!obj) { | 1407 if (!obj) { |
1780 LOG(WARNING) << "BuildSlotObject must be called before GenerateKeyPair"; | 1408 LOG(WARNING) << "BuildSlotObject must be called before GenerateKeyPair"; |
1781 return false; | 1409 return false; |
1782 } | 1410 } |
1783 obj->passphrase_ = passphrase; | 1411 obj->passphrase_ = passphrase; |
1784 return true; | 1412 return true; |
1785 }; | 1413 }; |
1786 | 1414 |
1787 private: | 1415 private: |
1788 DISALLOW_COPY_AND_ASSIGN(Pkcs11SlotHandlerGLaptop); | 1416 DISALLOW_COPY_AND_ASSIGN(Pkcs11SlotHandlerOpenCryptokiNoKeyGen); |
1789 }; | 1417 }; |
1790 | 1418 |
1791 // Class CSR | 1419 // Class CSR |
1792 // CSR JavaScript interface wrapper around Pkcs11CertificateHandler. | 1420 // CSR JavaScript interface wrapper around Pkcs11CertificateHandler. |
1793 class CSR : public JSObjectWrapper<CSR> { | 1421 class CSR : public JSObjectWrapper<CSR> { |
1794 public: | 1422 public: |
1795 CSR() { } | 1423 CSR() { } |
1796 virtual ~CSR() {} | 1424 virtual ~CSR() {} |
1797 | 1425 |
1798 // JSObjectWrapper Interface | 1426 // JSObjectWrapper Interface |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 // Called any time slot_handler_ or certificate_handler_ gets set. | 1702 // Called any time slot_handler_ or certificate_handler_ gets set. |
2075 void Pkcs11::SetupHandlers() { | 1703 void Pkcs11::SetupHandlers() { |
2076 // The certificate handler may need access to the slot handler | 1704 // The certificate handler may need access to the slot handler |
2077 certificate_handler()->SetSlotHandler(slot_handler()); | 1705 certificate_handler()->SetSlotHandler(slot_handler()); |
2078 | 1706 |
2079 // Set up the CSR and Certificate sub-classes with the certificate handler. | 1707 // Set up the CSR and Certificate sub-classes with the certificate handler. |
2080 CSR::InitCertificateHandler(certificate_handler()); | 1708 CSR::InitCertificateHandler(certificate_handler()); |
2081 Certificate::InitCertificateHandler(certificate_handler()); | 1709 Certificate::InitCertificateHandler(certificate_handler()); |
2082 } | 1710 } |
2083 | 1711 |
2084 // This always gets called first by InitializeXXX() | |
2085 // so that obj() is available for other initialization | |
2086 // functions (e.g. ReadObjectsFromSlot()) | |
2087 bool Pkcs11::Initialize() { | 1712 bool Pkcs11::Initialize() { |
2088 if (slot_handler_.get() == NULL) { | 1713 // Initialize the SlotObject template here so that we can embed 'this'. |
2089 // Default slot handler | |
2090 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); | |
2091 if (!slot_handler_->Initialize()) | |
2092 return false; | |
2093 } | |
2094 if (certificate_handler_.get() == NULL) { | |
2095 // Default certificate handler. | |
2096 certificate_handler_.reset(new Pkcs11CertificateHandlerLocalFile("", "")); | |
2097 if (!certificate_handler_->Initialize()) | |
2098 return false; | |
2099 } | |
2100 | |
2101 SetupHandlers(); | |
2102 | |
2103 // Initialize the pkcs11 template specially | |
2104 v8::Handle<v8::FunctionTemplate> t = GetTemplate(); | 1714 v8::Handle<v8::FunctionTemplate> t = GetTemplate(); |
2105 v8::Handle<v8::ObjectTemplate> t_obj = t->InstanceTemplate(); | 1715 v8::Handle<v8::ObjectTemplate> t_obj = t->InstanceTemplate(); |
2106 t_obj->Set(v8::String::NewSymbol("SlotObject"), | 1716 t_obj->Set(v8::String::NewSymbol("SlotObject"), |
2107 v8::FunctionTemplate::New(SlotObject::Construct, | 1717 v8::FunctionTemplate::New(SlotObject::Construct, |
2108 v8::External::Wrap(this)), | 1718 v8::External::Wrap(this)), |
2109 v8::ReadOnly); | 1719 v8::ReadOnly); |
2110 | 1720 |
2111 // Build and initialize the V8 object. | 1721 // Build and initialize the V8 object. |
2112 return JSObjectWrapper<Pkcs11>::Initialize(); | 1722 if (!JSObjectWrapper<Pkcs11>::Initialize()) |
| 1723 return false; |
| 1724 |
| 1725 // Default handlers |
| 1726 if (certificate_handler_.get() == NULL) { |
| 1727 certificate_handler_.reset(new Pkcs11TestCertificateHandler()); |
| 1728 if (!certificate_handler_->Initialize()) |
| 1729 return false; |
| 1730 } |
| 1731 if (slot_handler_.get() == NULL) { |
| 1732 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); |
| 1733 if (!slot_handler_->Initialize()) |
| 1734 return false; |
| 1735 } |
| 1736 SetupHandlers(); |
| 1737 |
| 1738 return true; |
2113 } | 1739 } |
2114 | 1740 |
2115 bool Pkcs11::InitializeOpenCryptoki(const std::string& engine) { | 1741 // Used for testing the OpenSSL functionality without requiring |
2116 LOG(INFO) << "Initializing pkcs11 with opencryptoki and engine:" << engine; | 1742 // opencryptoki to be configured in the OS. |
2117 | 1743 bool Pkcs11::SetOpenSSLHandlers() { |
2118 if (!Initialize()) | |
2119 return false; | |
2120 | |
2121 Pkcs11SlotHandlerOpenCryptoki* slot_handler = | |
2122 new Pkcs11SlotHandlerOpenCryptoki(); | |
2123 slot_handler_.reset(slot_handler); | |
2124 if (!slot_handler->Initialize()) | |
2125 return false; | |
2126 slot_handler->ReadObjectsFromSlot(this); | |
2127 | |
2128 Pkcs11CertificateHandlerOpenSslPkcs11Engine* cert_handler = | |
2129 new Pkcs11CertificateHandlerOpenSslPkcs11Engine(); | |
2130 if (!cert_handler->Initialize()) | |
2131 return false; | |
2132 cert_handler->SetEngineConfigFile(engine); | |
2133 cert_handler->SetOutputDER(); | |
2134 certificate_handler_.reset(cert_handler); | |
2135 | |
2136 SetupHandlers(); | |
2137 | |
2138 return true;; | |
2139 } | |
2140 | |
2141 bool Pkcs11::InitializeGLaptop() { | |
2142 LOG(INFO) << "Initializing pkcs11 with opencryptoki and openssl:libcrypto."; | |
2143 | |
2144 if (!Initialize()) | |
2145 return false; | |
2146 | |
2147 Pkcs11SlotHandlerGLaptop* slot_handler = | |
2148 new Pkcs11SlotHandlerGLaptop(); | |
2149 slot_handler_.reset(slot_handler); | |
2150 if (!slot_handler->Initialize()) | |
2151 return false; | |
2152 slot_handler->ReadObjectsFromSlot(this); | |
2153 | |
2154 Pkcs11CertificateHandlerLibOpenSsl* cert_handler = | 1744 Pkcs11CertificateHandlerLibOpenSsl* cert_handler = |
2155 new Pkcs11CertificateHandlerLibOpenSsl(); | 1745 new Pkcs11CertificateHandlerLibOpenSsl(); |
2156 if (!cert_handler->Initialize()) | 1746 if (!cert_handler->Initialize()) |
2157 return false; | 1747 return false; |
2158 certificate_handler_.reset(cert_handler); | 1748 certificate_handler_.reset(cert_handler); |
2159 | 1749 |
2160 SetupHandlers(); | 1750 SetupHandlers(); |
2161 | 1751 |
2162 return true; | 1752 return true; |
2163 } | 1753 } |
2164 | 1754 |
2165 bool Pkcs11::InitializeOpenSSL() { | 1755 // Requires opencryptoki to be configured properly in the OS, |
2166 LOG(INFO) << "Initializing pkcs11 with openssl."; | 1756 // otherwise C_Initialize() will fail. |
2167 | 1757 bool Pkcs11::SetOpenCryptokiHandlers() { |
2168 if (!Initialize()) | 1758 Pkcs11CertificateHandlerLibOpenSsl* cert_handler = |
2169 return false; | 1759 new Pkcs11CertificateHandlerLibOpenSsl(); |
2170 | |
2171 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); | |
2172 if (!slot_handler_->Initialize()) | |
2173 return false; | |
2174 | |
2175 Pkcs11CertificateHandlerOpenSsl* cert_handler = | |
2176 new Pkcs11CertificateHandlerOpenSsl(); | |
2177 if (!cert_handler->Initialize()) | 1760 if (!cert_handler->Initialize()) |
2178 return false; | 1761 return false; |
2179 certificate_handler_.reset(cert_handler); | 1762 certificate_handler_.reset(cert_handler); |
2180 | 1763 |
2181 SetupHandlers(); | 1764 Pkcs11SlotHandlerOpenCryptokiNoKeyGen* slot_handler = |
2182 | 1765 new Pkcs11SlotHandlerOpenCryptokiNoKeyGen(); |
2183 return true; | 1766 slot_handler_.reset(slot_handler); |
2184 } | 1767 if (!slot_handler->Initialize()) |
2185 | |
2186 bool Pkcs11::InitializeLocalFiles(const std::string& csr, | |
2187 const std::string& cert) { | |
2188 if (!Initialize()) | |
2189 return false; | 1768 return false; |
2190 | 1769 slot_handler->ReadObjectsFromSlot(this); |
2191 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); | |
2192 if (!slot_handler_->Initialize()) | |
2193 return false; | |
2194 | |
2195 certificate_handler_.reset( | |
2196 new Pkcs11CertificateHandlerLocalFile(csr, cert)); | |
2197 if (!certificate_handler_->Initialize()) | |
2198 return false; | |
2199 | 1770 |
2200 SetupHandlers(); | 1771 SetupHandlers(); |
2201 | 1772 |
2202 return true; | 1773 return true; |
2203 } | 1774 } |
2204 | 1775 |
2205 // pkcs11[slot_object->label()] = slot_object->obj() | 1776 // pkcs11[slot_object->label()] = slot_object->obj() |
2206 bool Pkcs11::AddJSSlotObject(const SlotObject* slot_object) { | 1777 bool Pkcs11::AddJSSlotObject(const SlotObject* slot_object) { |
2207 v8::Local<v8::Value> slotsvalue = obj()->Get(v8::String::NewSymbol("slots")); | 1778 v8::Local<v8::Value> slotsvalue = obj()->Get(v8::String::NewSymbol("slots")); |
2208 if (slotsvalue.IsEmpty() || !slotsvalue->IsObject()) { | 1779 if (slotsvalue.IsEmpty() || !slotsvalue->IsObject()) { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2290 v8::ReadOnly); | 1861 v8::ReadOnly); |
2291 template_object->Set(v8::String::NewSymbol("remove"), | 1862 template_object->Set(v8::String::NewSymbol("remove"), |
2292 v8::FunctionTemplate::New(dispatch_removeSlotObject), | 1863 v8::FunctionTemplate::New(dispatch_removeSlotObject), |
2293 v8::ReadOnly); | 1864 v8::ReadOnly); |
2294 template_object->Set(v8::String::NewSymbol("slots"), | 1865 template_object->Set(v8::String::NewSymbol("slots"), |
2295 v8::Object::New(), | 1866 v8::Object::New(), |
2296 v8::ReadOnly); | 1867 v8::ReadOnly); |
2297 } | 1868 } |
2298 | 1869 |
2299 } // namespace entd | 1870 } // namespace entd |
OLD | NEW |