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 10 matching lines...) Expand all Loading... |
21 #include <openssl/bn.h> | 21 #include <openssl/bn.h> |
22 | 22 |
23 #include "entd/utils.h" | 23 #include "entd/utils.h" |
24 | 24 |
25 namespace entd { | 25 namespace entd { |
26 | 26 |
27 // Class SlotObject declaration (implementation below) | 27 // Class SlotObject declaration (implementation below) |
28 // SlotObject JavaScript interface wrapper around Pkcs11SlotHandler. | 28 // SlotObject JavaScript interface wrapper around Pkcs11SlotHandler. |
29 class SlotObject : public JSObjectWrapper<SlotObject> { | 29 class SlotObject : public JSObjectWrapper<SlotObject> { |
30 public: | 30 public: |
31 SlotObject() : slot_handler_(NULL) { } | 31 SlotObject() : slot_handler_(NULL) {} |
| 32 SlotObject(const std::string& label, const std::string& key_id) |
| 33 : label_(label), key_identifier_(key_id), slot_handler_(NULL) {} |
32 virtual ~SlotObject() {} | 34 virtual ~SlotObject() {} |
33 | 35 |
34 virtual bool Initialize(); | 36 virtual bool Initialize(); |
35 | 37 |
36 // JSObjectWrapper Interface | 38 // JSObjectWrapper Interface |
37 virtual void ParseConstructorArgs( | 39 virtual void ParseConstructorArgs( |
38 v8::Handle<v8::Object> obj, const v8::Arguments& args); | 40 v8::Handle<v8::Object> obj, const v8::Arguments& args); |
39 static void SetTemplateBindings( | 41 static void SetTemplateBindings( |
40 v8::Handle<v8::ObjectTemplate> template_object); | 42 v8::Handle<v8::ObjectTemplate> template_object); |
41 static const char* GetClassName() { return "SlotObject"; } | 43 static const char* GetClassName() { return "SlotObject"; } |
42 | 44 |
43 // Accessors | 45 // Accessors |
44 const std::string& label() const { return label_; } | 46 const std::string& label() const { return label_; } |
45 const std::string& key_identifier() const { return key_identifier_; } | 47 const std::string& key_identifier() const { return key_identifier_; } |
46 const std::string& passphrase() const { return passphrase_; } | 48 const std::string& passphrase() const { return passphrase_; } |
47 std::string GetPublicKey() const { | 49 std::string GetPublicKey() const { |
48 return slot_handler()->GetPublicKey(label_); | 50 return slot_handler()->GetPublicKey(label_); |
49 } | 51 } |
50 Pkcs11SlotHandler* slot_handler() const { return slot_handler_; } | 52 Pkcs11SlotHandler* slot_handler() const { return slot_handler_; } |
51 | 53 |
52 // Setters | 54 // Setters |
53 | 55 |
54 // Stores the key identifier and passes it to the slot handler. | 56 // Stores the key identifier and passes it to the slot handler. |
55 const bool SetKeyIdentifier(const std::string& id) { | 57 bool SetKeyIdentifier(const std::string& id) { |
56 key_identifier_ = id; | 58 key_identifier_ = id; |
57 return slot_handler_->SetKeyIdentifier(label_, id); | 59 return slot_handler_->SetKeyIdentifier(label_, id); |
58 } | 60 } |
59 const void SetPassphrase(const std::string& passphrase) { | 61 const void SetPassphrase(const std::string& passphrase) { |
60 passphrase_ = passphrase; | 62 passphrase_ = passphrase; |
61 } | 63 } |
62 void SetSlotHandler(Pkcs11SlotHandler* slot_handler) { | 64 void SetSlotHandler(Pkcs11SlotHandler* slot_handler) { |
63 slot_handler_ = slot_handler; | 65 slot_handler_ = slot_handler; |
64 } | 66 } |
65 | 67 |
66 private: | 68 private: |
67 std::string label_; | 69 std::string label_; |
68 std::string key_identifier_; | 70 std::string key_identifier_; |
69 std::string passphrase_; | 71 std::string passphrase_; |
70 Pkcs11SlotHandler* slot_handler_; | 72 Pkcs11SlotHandler* slot_handler_; |
71 | 73 |
72 DISALLOW_COPY_AND_ASSIGN(SlotObject); | 74 DISALLOW_COPY_AND_ASSIGN(SlotObject); |
73 }; | 75 }; |
74 | 76 |
| 77 // Class Certificate declaration (implementation below) |
| 78 // Certificate JavaScript interface wrapper around Pkcs11CertificateHandler. |
| 79 class Certificate : public JSObjectWrapper<Certificate> { |
| 80 public: |
| 81 Certificate() {} |
| 82 virtual ~Certificate() {} |
| 83 |
| 84 // JSObjectWrapper Interface |
| 85 virtual void ParseConstructorArgs( |
| 86 v8::Handle<v8::Object> obj, const v8::Arguments& args); |
| 87 static void SetTemplateBindings( |
| 88 v8::Handle<v8::ObjectTemplate> template_object); |
| 89 static const char* GetClassName() { return "Certificate"; } |
| 90 |
| 91 // Accessors |
| 92 const chromeos::Blob& certificate() const { return certificate_; } |
| 93 const std::string& subject() const { return subject_; } |
| 94 |
| 95 // Certificate handler management |
| 96 static void InitCertificateHandler(Pkcs11CertificateHandler* handler) { |
| 97 certificate_handler_ = handler; |
| 98 } |
| 99 static Pkcs11CertificateHandler* certificate_handler() { |
| 100 return certificate_handler_; |
| 101 } |
| 102 |
| 103 private: |
| 104 // The certificate may contain binary data, so store it as an array of bytes |
| 105 // instead of a string. |
| 106 chromeos::Blob certificate_; |
| 107 std::string subject_; |
| 108 static Pkcs11CertificateHandler* certificate_handler_; |
| 109 |
| 110 DISALLOW_COPY_AND_ASSIGN(Certificate); |
| 111 }; |
75 | 112 |
76 // class Pkcs11CertificateHandlerLocalFile | 113 // class Pkcs11CertificateHandlerLocalFile |
77 // Test Certificate handler that returns the contents of a file. | 114 // Test Certificate handler that returns the contents of a file. |
78 // | 115 // |
79 // If the csr or cert file exists, the contents of the file is returned | 116 // If the csr or cert file exists, the contents of the file is returned |
80 // in BuildCSR or BuildCertificate; subject or content arguments are ignored. | 117 // in BuildCSR or BuildCertificate; subject or content arguments are ignored. |
81 // If the filename is empty or the file does not exist, a string | 118 // If the filename is empty or the file does not exist, a string |
82 // containing the subject or content is returned instead. | 119 // containing the subject or content is returned instead. |
83 class Pkcs11CertificateHandlerLocalFile : public Pkcs11CertificateHandler { | 120 class Pkcs11CertificateHandlerLocalFile : public Pkcs11CertificateHandler { |
84 public: | 121 public: |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 LOG(INFO) << "Pkcs11SlotHandlerOpenCryptoki Initialized. Using slot: " | 805 LOG(INFO) << "Pkcs11SlotHandlerOpenCryptoki Initialized. Using slot: " |
769 << slot_index_; | 806 << slot_index_; |
770 res = true; | 807 res = true; |
771 } | 808 } |
772 | 809 |
773 free(slot_list); | 810 free(slot_list); |
774 if (res) { | 811 if (res) { |
775 res = Pkcs11SlotHandlerInMemory::Initialize(); | 812 res = Pkcs11SlotHandlerInMemory::Initialize(); |
776 } | 813 } |
777 | 814 |
778 // TODO(stevenjb): read existing objects into objects_ | 815 return res; |
| 816 } |
779 | 817 |
780 return res; | 818 bool ReadObjectsFromSlot(Pkcs11* pkcs11) { |
| 819 CK_SESSION_HANDLE session_handle = NULL; |
| 820 CK_RV rv = C_OpenSession(slot_id_, |
| 821 CKF_SERIAL_SESSION|CKF_RW_SESSION, NULL, NULL, |
| 822 &session_handle); |
| 823 if (rv != CKR_OK) { |
| 824 LOG(ERROR) << "C_OpenSession failed, error: " << rv |
| 825 << ", slot: " << slot_index_; |
| 826 return false; |
| 827 } |
| 828 |
| 829 // Gather a list of objects in the slot |
| 830 int num_objects = 0; |
| 831 |
| 832 rv = C_FindObjectsInit(session_handle, NULL, 0); |
| 833 if (rv != CKR_OK) { |
| 834 LOG(ERROR) << "C_FindObjectsInit failed: " << rv; |
| 835 return false; |
| 836 } |
| 837 |
| 838 while (1) { |
| 839 CK_ULONG count; |
| 840 CK_OBJECT_HANDLE object; |
| 841 rv = C_FindObjects(session_handle, &object, 1, &count); |
| 842 if (rv != CKR_OK) { |
| 843 LOG(ERROR) << "C_FindObjects failed: " << rv; |
| 844 return false; |
| 845 } |
| 846 if (count == 0) { |
| 847 // No more objects to read, exit loop. |
| 848 break; |
| 849 } |
| 850 ++num_objects; |
| 851 |
| 852 const size_t LABEL_MAX_LENGTH = 256; |
| 853 const size_t IDSTR_MAX_LENGTH = 8; |
| 854 const size_t SUBJECT_MAX_LENGTH = 1024; |
| 855 |
| 856 // Define a template with the values we are interested in |
| 857 CK_OBJECT_CLASS obj_class; |
| 858 char obj_label[LABEL_MAX_LENGTH]; |
| 859 CK_BYTE idstr[IDSTR_MAX_LENGTH]; |
| 860 CK_BYTE subject[SUBJECT_MAX_LENGTH]; |
| 861 |
| 862 CK_ATTRIBUTE obj_template[] = { |
| 863 { CKA_CLASS, &obj_class, sizeof(obj_class) }, |
| 864 { CKA_LABEL, obj_label, LABEL_MAX_LENGTH }, |
| 865 { CKA_ID, idstr, IDSTR_MAX_LENGTH }, |
| 866 { CKA_SUBJECT, subject, SUBJECT_MAX_LENGTH }, |
| 867 }; |
| 868 int n_attr = sizeof(obj_template) / sizeof(CK_ATTRIBUTE); |
| 869 |
| 870 // Read values into obj_template |
| 871 rv = C_GetAttributeValue(session_handle, object, obj_template, n_attr); |
| 872 if (rv != CKR_OK) { |
| 873 LOG(ERROR) << "C_GetAttributeValue failed: " << rv |
| 874 << " obj: " << num_objects; |
| 875 } |
| 876 obj_class = *(static_cast<CK_OBJECT_CLASS*>(obj_template[0].pValue)); |
| 877 if (obj_class == CKO_CERTIFICATE || |
| 878 obj_class == CKO_PUBLIC_KEY || |
| 879 obj_class == CKO_PRIVATE_KEY) { |
| 880 if (obj_template[1].ulValueLen > 0) { |
| 881 // Only parse certificate and key objects with a valid label |
| 882 std::string label = TemplateToString(obj_template[1]); |
| 883 std::string idstr = GetKeyFromId( |
| 884 static_cast<CK_BYTE*>(obj_template[2].pValue), |
| 885 obj_template[2].ulValueLen); |
| 886 std::string subject = TemplateToString(obj_template[3]); |
| 887 Object* obj = AddObject(label); |
| 888 if (!obj->key_identifier_.empty() && obj->key_identifier_ != idstr) { |
| 889 LOG(WARNING) << "Object '" << label << "' " |
| 890 << "with mismatched key identifers: " |
| 891 << "'" << obj->key_identifier_ << "'" |
| 892 << " != '" << idstr << "'"; |
| 893 } else { |
| 894 obj->key_identifier_ = idstr; |
| 895 obj->subject_ = subject; |
| 896 } |
| 897 } |
| 898 } |
| 899 } |
| 900 |
| 901 C_FindObjectsFinal(session_handle); |
| 902 |
| 903 LOG(INFO) << "Found " << num_objects << " objects in slot."; |
| 904 |
| 905 // Iterate through the list of objects and generate |
| 906 // SlotObject objects and insert them into pkcs11.slots. |
| 907 for (ObjectMap::iterator iter = objects_.begin(); |
| 908 iter != objects_.end(); ++iter) { |
| 909 Object* object = iter->second.get(); |
| 910 |
| 911 // Build a slot object |
| 912 SlotObject* slot_object = new SlotObject(object->label_, |
| 913 object->key_identifier_); |
| 914 slot_object->Initialize(); |
| 915 slot_object->SetSlotHandler(pkcs11->slot_handler()); |
| 916 slot_object->obj()->Set(v8::String::NewSymbol("label"), |
| 917 v8::String::New(object->label_.c_str()), |
| 918 v8::ReadOnly); |
| 919 slot_object->obj()->Set(v8::String::NewSymbol("keyIdentifier"), |
| 920 v8::String::New(object->key_identifier_.c_str())); |
| 921 |
| 922 // Build a certificate |
| 923 Certificate* certificate = new Certificate(); |
| 924 certificate->Initialize(); |
| 925 certificate->obj()->Set(v8::String::NewSymbol("subject"), |
| 926 v8::String::New(object->subject_.c_str())); |
| 927 |
| 928 // Add the certificate to the slot object |
| 929 slot_object->obj()->Set(v8::String::NewSymbol("certificate"), |
| 930 certificate->obj()); |
| 931 |
| 932 // Add the object to pkcs11.slots ("slots[label] = obj") |
| 933 pkcs11->AddJSSlotObject(slot_object); |
| 934 } |
| 935 return true; |
781 } | 936 } |
782 | 937 |
783 // Returns false if the key is longer than a reasonable maximum length. | 938 // Returns false if the key is longer than a reasonable maximum length. |
784 virtual bool SetKeyIdentifier(const std::string& label, | 939 virtual bool SetKeyIdentifier(const std::string& label, |
785 const std::string& keyid) { | 940 const std::string& keyid) { |
786 const std::size_t MAX_KEY_LENGTH = 16; | 941 const std::size_t MAX_KEY_LENGTH = 16; |
787 if (keyid.length() > MAX_KEY_LENGTH) | 942 if (keyid.length() > MAX_KEY_LENGTH) |
788 return false; | 943 return false; |
789 return Pkcs11SlotHandlerInMemory::SetKeyIdentifier(label, keyid); | 944 return Pkcs11SlotHandlerInMemory::SetKeyIdentifier(label, keyid); |
790 } | 945 } |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 rv = C_Login(handle, CKU_USER, | 1271 rv = C_Login(handle, CKU_USER, |
1117 pin_ptr, user_pin_.length()); | 1272 pin_ptr, user_pin_.length()); |
1118 if (rv != CKR_OK) { | 1273 if (rv != CKR_OK) { |
1119 LOG(ERROR) << "C_Login failed, error: " << rv | 1274 LOG(ERROR) << "C_Login failed, error: " << rv |
1120 << " label: " << label << " pin: " << user_pin_; | 1275 << " label: " << label << " pin: " << user_pin_; |
1121 } | 1276 } |
1122 | 1277 |
1123 return handle; | 1278 return handle; |
1124 } | 1279 } |
1125 | 1280 |
| 1281 std::string TemplateToString(const CK_ATTRIBUTE& attr) { |
| 1282 const char* value = static_cast<const char*>(attr.pValue); |
| 1283 return std::string(value, attr.ulValueLen); |
| 1284 } |
| 1285 |
1126 // openssl crypto library interface | 1286 // openssl crypto library interface |
1127 | 1287 |
1128 struct RsaKeyInfo { | 1288 struct RsaKeyInfo { |
1129 unsigned char *modulus; | 1289 unsigned char *modulus; |
1130 int modulus_len; | 1290 int modulus_len; |
1131 unsigned char *public_exp; | 1291 unsigned char *public_exp; |
1132 int public_exp_len; | 1292 int public_exp_len; |
1133 unsigned char *private_exp; | 1293 unsigned char *private_exp; |
1134 int private_exp_len; | 1294 int private_exp_len; |
1135 unsigned char *prime_1; | 1295 unsigned char *prime_1; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 if (bytes.size() > max_length) { | 1377 if (bytes.size() > max_length) { |
1218 LOG(ERROR) << "Too many characters in key: " << keyid; | 1378 LOG(ERROR) << "Too many characters in key: " << keyid; |
1219 *idstrlenp = 0; | 1379 *idstrlenp = 0; |
1220 return false; | 1380 return false; |
1221 } | 1381 } |
1222 memcpy(idstrp, &bytes.front(), bytes.size()); | 1382 memcpy(idstrp, &bytes.front(), bytes.size()); |
1223 *idstrlenp = bytes.size(); | 1383 *idstrlenp = bytes.size(); |
1224 return true; | 1384 return true; |
1225 } | 1385 } |
1226 | 1386 |
| 1387 // Inverse of GetKeyIdStr |
| 1388 std::string GetKeyFromId(CK_BYTE* idstrp, CK_ULONG idstrlen) { |
| 1389 chromeos::Blob bytes = chromeos::Blob(idstrp, idstrp+idstrlen); |
| 1390 return chromeos::AsciiEncode(bytes); |
| 1391 } |
| 1392 |
1227 std::string user_pin_; | 1393 std::string user_pin_; |
1228 CK_ULONG slot_index_; | 1394 CK_ULONG slot_index_; |
1229 CK_SLOT_ID slot_id_; | 1395 CK_SLOT_ID slot_id_; |
1230 | 1396 |
1231 DISALLOW_COPY_AND_ASSIGN(Pkcs11SlotHandlerOpenCryptoki); | 1397 DISALLOW_COPY_AND_ASSIGN(Pkcs11SlotHandlerOpenCryptoki); |
1232 }; | 1398 }; |
1233 | 1399 |
1234 // In "GLaptop mode" we generate the key pair using openssl, and call | 1400 // In "GLaptop mode" we generate the key pair using openssl, and call |
1235 // AddPrivateKey() instead, so GenerateKeyPair() needs to be a no-op. | 1401 // AddPrivateKey() instead, so GenerateKeyPair() needs to be a no-op. |
1236 class Pkcs11SlotHandlerGLaptop : public Pkcs11SlotHandlerOpenCryptoki { | 1402 class Pkcs11SlotHandlerGLaptop : public Pkcs11SlotHandlerOpenCryptoki { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 | 1445 |
1280 private: | 1446 private: |
1281 std::string request_; | 1447 std::string request_; |
1282 | 1448 |
1283 static Pkcs11CertificateHandler* certificate_handler_; | 1449 static Pkcs11CertificateHandler* certificate_handler_; |
1284 | 1450 |
1285 DISALLOW_COPY_AND_ASSIGN(CSR); | 1451 DISALLOW_COPY_AND_ASSIGN(CSR); |
1286 }; | 1452 }; |
1287 | 1453 |
1288 // static | 1454 // static |
1289 Pkcs11CertificateHandler* CSR::certificate_handler_; | 1455 Pkcs11CertificateHandler* CSR::certificate_handler_ = NULL; |
1290 | 1456 |
1291 // Base64 encoded version of the CSR | 1457 // Base64 encoded version of the CSR |
1292 static v8::Handle<v8::Value> dispatch_CSRToString(const v8::Arguments& args) { | 1458 static v8::Handle<v8::Value> dispatch_CSRToString(const v8::Arguments& args) { |
1293 CSR* csr = CSR::Unwrap(args.This()); | 1459 CSR* csr = CSR::Unwrap(args.This()); |
1294 if (csr == NULL) { | 1460 if (csr == NULL) { |
1295 utils::ThrowV8Exception("Method called on incorrect object type."); | 1461 utils::ThrowV8Exception("Method called on incorrect object type."); |
1296 return v8::False(); | 1462 return v8::False(); |
1297 } | 1463 } |
1298 v8::Local<v8::String> res = v8::String::New(csr->request().c_str()); | 1464 v8::Local<v8::String> res = v8::String::New(csr->request().c_str()); |
1299 return res; | 1465 return res; |
(...skipping 30 matching lines...) Expand all Loading... |
1330 // Build the CSR request | 1496 // Build the CSR request |
1331 if (!certificate_handler()->BuildCSR(slot_object->label(), | 1497 if (!certificate_handler()->BuildCSR(slot_object->label(), |
1332 utils::ValueAsUtf8String(subject), | 1498 utils::ValueAsUtf8String(subject), |
1333 &request_)) { | 1499 &request_)) { |
1334 utils::ThrowV8Exception("Error building CSR."); | 1500 utils::ThrowV8Exception("Error building CSR."); |
1335 return; | 1501 return; |
1336 } | 1502 } |
1337 } | 1503 } |
1338 | 1504 |
1339 | 1505 |
1340 // Class Certificate | 1506 // Class Certificate Implementation |
1341 // Certificate JavaScript interface wrapper around Pkcs11CertificateHandler. | |
1342 class Certificate : public JSObjectWrapper<Certificate> { | |
1343 public: | |
1344 Certificate() {} | |
1345 virtual ~Certificate() {} | |
1346 | |
1347 // JSObjectWrapper Interface | |
1348 virtual void ParseConstructorArgs( | |
1349 v8::Handle<v8::Object> obj, const v8::Arguments& args); | |
1350 static void SetTemplateBindings( | |
1351 v8::Handle<v8::ObjectTemplate> template_object); | |
1352 static const char* GetClassName() { return "Certificate"; } | |
1353 | |
1354 // Accessors | |
1355 const chromeos::Blob& certificate() const { return certificate_; } | |
1356 const std::string& subject() const { return subject_; } | |
1357 | |
1358 // Certificate handler management | |
1359 static void InitCertificateHandler(Pkcs11CertificateHandler* handler) { | |
1360 certificate_handler_ = handler; | |
1361 } | |
1362 static Pkcs11CertificateHandler* certificate_handler() { | |
1363 return certificate_handler_; | |
1364 } | |
1365 | |
1366 private: | |
1367 // The certificate may contain binary data, so store it as an array of bytes | |
1368 // instead of a string. | |
1369 chromeos::Blob certificate_; | |
1370 std::string subject_; | |
1371 static Pkcs11CertificateHandler* certificate_handler_; | |
1372 | |
1373 DISALLOW_COPY_AND_ASSIGN(Certificate); | |
1374 }; | |
1375 | 1507 |
1376 // static | 1508 // static |
1377 Pkcs11CertificateHandler* Certificate::certificate_handler_; | 1509 Pkcs11CertificateHandler* Certificate::certificate_handler_ = NULL; |
1378 | 1510 |
1379 // Returns the contents of the Certificate as a string. | 1511 // Returns the contents of the Certificate as a string. |
1380 // Note: if this is binary and not Base64, results may be unexpected. | 1512 // Note: if this is binary and not Base64, results may be unexpected. |
1381 // (i.e. don't call this unles you expect the contents to be a string) | 1513 // (i.e. don't call this unles you expect the contents to be a string) |
1382 static v8::Handle<v8::Value> dispatch_CertificateToString( | 1514 static v8::Handle<v8::Value> dispatch_CertificateToString( |
1383 const v8::Arguments& args) { | 1515 const v8::Arguments& args) { |
1384 Certificate* cert = Certificate::Unwrap(args.This()); | 1516 Certificate* cert = Certificate::Unwrap(args.This()); |
1385 const chromeos::Blob& certdata = cert->certificate(); | 1517 const chromeos::Blob& certdata = cert->certificate(); |
1386 const char* certstrptr = reinterpret_cast<const char*>(&(certdata.front())); | 1518 const char* certstrptr = reinterpret_cast<const char*>(&(certdata.front())); |
1387 v8::Local<v8::String> res = v8::String::New(certstrptr); | 1519 v8::Local<v8::String> res = v8::String::New(certstrptr); |
(...skipping 19 matching lines...) Expand all Loading... |
1407 v8::Handle<v8::Value> content = args[0]; | 1539 v8::Handle<v8::Value> content = args[0]; |
1408 | 1540 |
1409 // Generate the Certificate data | 1541 // Generate the Certificate data |
1410 bool res = certificate_handler()->BuildCertificate( | 1542 bool res = certificate_handler()->BuildCertificate( |
1411 utils::ValueAsUtf8String(content), &certificate_, &subject_); | 1543 utils::ValueAsUtf8String(content), &certificate_, &subject_); |
1412 if (!res) { | 1544 if (!res) { |
1413 utils::ThrowV8Exception("Unable to build certificate."); | 1545 utils::ThrowV8Exception("Unable to build certificate."); |
1414 return; | 1546 return; |
1415 } | 1547 } |
1416 | 1548 |
1417 // Set the 'content' property to the input content | |
1418 obj->Set(v8::String::NewSymbol("content"), | |
1419 content->ToString()); | |
1420 // Set the 'subject' property to the certificate subject | 1549 // Set the 'subject' property to the certificate subject |
1421 obj->Set(v8::String::NewSymbol("subject"), | 1550 obj->Set(v8::String::NewSymbol("subject"), |
1422 v8::String::New(subject_.c_str())); | 1551 v8::String::New(subject_.c_str())); |
1423 } | 1552 } |
1424 | 1553 |
1425 | 1554 |
1426 // Class SlotObject Implementation | 1555 // Class SlotObject Implementation |
1427 | 1556 |
1428 bool SlotObject::Initialize() { | 1557 bool SlotObject::Initialize() { |
1429 // Bind "CSR" here so we can associate this with it | 1558 // Bind "CSR" here so we can associate this with it |
(...skipping 16 matching lines...) Expand all Loading... |
1446 utils::ThrowV8Exception("Method called on incorrect object type."); | 1575 utils::ThrowV8Exception("Method called on incorrect object type."); |
1447 return v8::False(); | 1576 return v8::False(); |
1448 } | 1577 } |
1449 if (args.Length() < 1) { | 1578 if (args.Length() < 1) { |
1450 utils::ThrowV8Exception("Not enough parameters."); | 1579 utils::ThrowV8Exception("Not enough parameters."); |
1451 return v8::False(); | 1580 return v8::False(); |
1452 } | 1581 } |
1453 | 1582 |
1454 // Argument 0 is the key identifier | 1583 // Argument 0 is the key identifier |
1455 v8::Handle<v8::String> v8keyid = args[0]->ToString(); | 1584 v8::Handle<v8::String> v8keyid = args[0]->ToString(); |
1456 slot->obj()->Set(v8::String::NewSymbol("keyIdentifier"), v8keyid); | |
1457 std::string keyid = std::string(*v8::String::Utf8Value(v8keyid)); | 1585 std::string keyid = std::string(*v8::String::Utf8Value(v8keyid)); |
1458 bool res = slot->SetKeyIdentifier(keyid); | 1586 bool res = slot->SetKeyIdentifier(keyid); |
1459 if (!res) { | 1587 if (!res) { |
1460 utils::ThrowV8Exception(std::string("Invalid key id: ") + keyid); | 1588 utils::ThrowV8Exception(std::string("Invalid key id: ") + keyid); |
1461 return v8::False(); | 1589 return v8::False(); |
1462 } | 1590 } |
| 1591 // Set the JS keyIdentifier property |
| 1592 slot->obj()->Set(v8::String::NewSymbol("keyIdentifier"), v8keyid); |
1463 | 1593 |
1464 // Argumnet 1 is the passphrase (optional) | 1594 // Argumnet 1 is the passphrase (optional) |
1465 std::string passphrase; // defaults to empty | 1595 std::string passphrase; // defaults to empty |
1466 if (!args[1]->IsUndefined()) { | 1596 if (!args[1]->IsUndefined()) { |
1467 passphrase = utils::ValueAsUtf8String(args[1]); | 1597 passphrase = utils::ValueAsUtf8String(args[1]); |
1468 slot->SetPassphrase(passphrase); | 1598 slot->SetPassphrase(passphrase); |
1469 } | 1599 } |
1470 | 1600 |
1471 // Access the slot handler and generate the public/private key pair | 1601 // Access the slot handler and generate the public/private key pair |
1472 res = slot->slot_handler()->GenerateKeyPair(slot->label(), | 1602 res = slot->slot_handler()->GenerateKeyPair(slot->label(), |
1473 slot->passphrase()); | 1603 slot->passphrase()); |
1474 if (!res) { | 1604 if (!res) { |
1475 LOG(ERROR) << "Unable to build key pair with id: " << keyid; | 1605 LOG(ERROR) << "Unable to build key pair with id: " << keyid; |
1476 return v8::False(); | 1606 return v8::False(); |
1477 } | 1607 } |
1478 | 1608 |
1479 // Set the JS publicKey property | |
1480 v8::Handle<v8::String> v8_public_key = | |
1481 v8::String::New(slot->GetPublicKey().c_str()); | |
1482 slot->obj()->Set(v8::String::NewSymbol("publicKey"), v8_public_key); | |
1483 | |
1484 return v8::True(); | 1609 return v8::True(); |
1485 } | 1610 } |
1486 | 1611 |
1487 static v8::Handle<v8::Value> dispatch_addCertificate( | 1612 static v8::Handle<v8::Value> dispatch_addCertificate( |
1488 const v8::Arguments& args) { | 1613 const v8::Arguments& args) { |
1489 // Get the arguments. | 1614 // Get the arguments. |
1490 SlotObject* slot = SlotObject::Unwrap(args.This()); | 1615 SlotObject* slot = SlotObject::Unwrap(args.This()); |
1491 if (slot == NULL) { | 1616 if (slot == NULL) { |
1492 utils::ThrowV8Exception("Method called on incorrect object type."); | 1617 utils::ThrowV8Exception("Method called on incorrect object type."); |
1493 return v8::False(); | 1618 return v8::False(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1550 obj->Set(v8::String::NewSymbol("label"), v8label, v8::ReadOnly); | 1675 obj->Set(v8::String::NewSymbol("label"), v8label, v8::ReadOnly); |
1551 label_ = std::string(*v8::String::Utf8Value(v8label)); | 1676 label_ = std::string(*v8::String::Utf8Value(v8label)); |
1552 | 1677 |
1553 // Build the SlotObject | 1678 // Build the SlotObject |
1554 bool res = pkcs11->slot_handler()->BuildSlotObject(label_); | 1679 bool res = pkcs11->slot_handler()->BuildSlotObject(label_); |
1555 if (!res) { | 1680 if (!res) { |
1556 LOG(ERROR) << "Unable to build SlotObject with label: " << label_; | 1681 LOG(ERROR) << "Unable to build SlotObject with label: " << label_; |
1557 return; | 1682 return; |
1558 } | 1683 } |
1559 | 1684 |
1560 // Add a this to pkcs11.slots ("slots.{label} = {cert}") | 1685 // Add this to pkcs11.slots ("slots[label] = obj") |
1561 v8::Local<v8::Value> slotsvalue = | 1686 pkcs11->AddJSSlotObject(this); |
1562 pkcs11->obj()->Get(v8::String::NewSymbol("slots")); | |
1563 if (slotsvalue.IsEmpty() || !slotsvalue->IsObject()) { | |
1564 LOG(ERROR) << "'slots' is not an object in pkcs11"; | |
1565 return; | |
1566 } | |
1567 v8::Local<v8::Object> slots = v8::Local<v8::Object>::Cast(slotsvalue); | |
1568 slots->Set(v8label->ToString(), obj); | |
1569 } | 1687 } |
1570 | 1688 |
1571 | 1689 |
1572 // Class Pkcs11 | 1690 // Class Pkcs11 |
1573 Pkcs11::Pkcs11(Pkcs11CertificateHandler* cert_handler, | 1691 Pkcs11::Pkcs11(Pkcs11CertificateHandler* cert_handler, |
1574 Pkcs11SlotHandler* slot_handler) | 1692 Pkcs11SlotHandler* slot_handler) |
1575 : JSObjectWrapper<Pkcs11>(), | 1693 : JSObjectWrapper<Pkcs11>(), |
1576 certificate_handler_(cert_handler), | 1694 certificate_handler_(cert_handler), |
1577 slot_handler_(slot_handler) { | 1695 slot_handler_(slot_handler) { |
1578 } | 1696 } |
1579 | 1697 |
1580 Pkcs11::~Pkcs11() { | 1698 Pkcs11::~Pkcs11() { |
1581 CleanupTemplate(); // We only have one Pkcs11 instance. | 1699 CleanupTemplate(); // We only have one Pkcs11 instance. |
1582 } | 1700 } |
1583 | 1701 |
| 1702 // Called any time slot_handler_ or certificate_handler_ gets set. |
| 1703 void Pkcs11::SetupHandlers() { |
| 1704 // The certificate handler may need access to the slot handler |
| 1705 certificate_handler()->SetSlotHandler(slot_handler()); |
| 1706 |
| 1707 // Set up the CSR and Certificate sub-classes with the certificate handler. |
| 1708 CSR::InitCertificateHandler(certificate_handler()); |
| 1709 Certificate::InitCertificateHandler(certificate_handler()); |
| 1710 } |
| 1711 |
| 1712 // This always gets called first by InitializeXXX() |
| 1713 // so that obj() is available for other initialization |
| 1714 // functions (e.g. ReadObjectsFromSlot()) |
1584 bool Pkcs11::Initialize() { | 1715 bool Pkcs11::Initialize() { |
1585 if (slot_handler_.get() == NULL) { | 1716 if (slot_handler_.get() == NULL) { |
1586 // Default slot handler | 1717 // Default slot handler |
1587 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); | 1718 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); |
1588 slot_handler_->Initialize(); | 1719 slot_handler_->Initialize(); |
1589 } | 1720 } |
1590 if (certificate_handler_.get() == NULL) { | 1721 if (certificate_handler_.get() == NULL) { |
1591 // Default certificate handler. | 1722 // Default certificate handler. |
1592 certificate_handler_.reset(new Pkcs11CertificateHandlerLocalFile("", "")); | 1723 certificate_handler_.reset(new Pkcs11CertificateHandlerLocalFile("", "")); |
1593 certificate_handler_->Initialize(); | 1724 certificate_handler_->Initialize(); |
1594 } | 1725 } |
1595 // The certificate handler may need access to the slot handler | |
1596 certificate_handler()->SetSlotHandler(slot_handler()); | |
1597 | 1726 |
1598 // Set up the CSR and Certificate sub-classes with the certificate handler. | 1727 SetupHandlers(); |
1599 CSR::InitCertificateHandler(certificate_handler()); | |
1600 Certificate::InitCertificateHandler(certificate_handler()); | |
1601 | 1728 |
1602 // Initialize the pkcs11 template specially | 1729 // Initialize the pkcs11 template specially |
1603 v8::Handle<v8::FunctionTemplate> t = GetTemplate(); | 1730 v8::Handle<v8::FunctionTemplate> t = GetTemplate(); |
1604 v8::Handle<v8::ObjectTemplate> t_obj = t->InstanceTemplate(); | 1731 v8::Handle<v8::ObjectTemplate> t_obj = t->InstanceTemplate(); |
1605 t_obj->Set(v8::String::NewSymbol("SlotObject"), | 1732 t_obj->Set(v8::String::NewSymbol("SlotObject"), |
1606 v8::FunctionTemplate::New(SlotObject::Construct, | 1733 v8::FunctionTemplate::New(SlotObject::Construct, |
1607 v8::External::Wrap(this)), | 1734 v8::External::Wrap(this)), |
1608 v8::ReadOnly); | 1735 v8::ReadOnly); |
1609 | 1736 |
1610 // Build and initialize the V8 object. | 1737 // Build and initialize the V8 object. |
1611 return JSObjectWrapper<Pkcs11>::Initialize(); | 1738 return JSObjectWrapper<Pkcs11>::Initialize(); |
1612 } | 1739 } |
1613 | 1740 |
1614 bool Pkcs11::InitializeOpenCryptoki(const std::string& test_cert, | 1741 bool Pkcs11::InitializeOpenCryptoki(const std::string& test_cert, |
1615 const std::string& engine) { | 1742 const std::string& engine) { |
1616 LOG(INFO) << "Initializing pkcs11 with opencryptoki and engine:" << engine; | 1743 LOG(INFO) << "Initializing pkcs11 with opencryptoki and engine:" << engine; |
1617 | 1744 |
1618 slot_handler_.reset(new Pkcs11SlotHandlerOpenCryptoki()); | 1745 bool res = Initialize(); |
1619 slot_handler_->Initialize(); | 1746 |
| 1747 Pkcs11SlotHandlerOpenCryptoki* slot_handler = |
| 1748 new Pkcs11SlotHandlerOpenCryptoki(); |
| 1749 slot_handler_.reset(slot_handler); |
| 1750 slot_handler->Initialize(); |
| 1751 slot_handler->ReadObjectsFromSlot(this); |
1620 | 1752 |
1621 Pkcs11CertificateHandlerOpenSslPkcs11Engine* cert_handler = | 1753 Pkcs11CertificateHandlerOpenSslPkcs11Engine* cert_handler = |
1622 new Pkcs11CertificateHandlerOpenSslPkcs11Engine(); | 1754 new Pkcs11CertificateHandlerOpenSslPkcs11Engine(); |
1623 cert_handler->Initialize(); | 1755 cert_handler->Initialize(); |
1624 cert_handler->SetTestCertificate(test_cert); | 1756 cert_handler->SetTestCertificate(test_cert); |
1625 cert_handler->SetEngineConfigFile(engine); | 1757 cert_handler->SetEngineConfigFile(engine); |
1626 cert_handler->SetOutputDER(); | 1758 cert_handler->SetOutputDER(); |
1627 certificate_handler_.reset(cert_handler); | 1759 certificate_handler_.reset(cert_handler); |
1628 | 1760 |
1629 return Initialize(); | 1761 SetupHandlers(); |
| 1762 |
| 1763 return res; |
1630 } | 1764 } |
1631 | 1765 |
1632 bool Pkcs11::InitializeGLaptop(const std::string& test_cert) { | 1766 bool Pkcs11::InitializeGLaptop(const std::string& test_cert) { |
1633 LOG(INFO) << "Initializing pkcs11 with opencryptoki, no ssl engine."; | 1767 LOG(INFO) << "Initializing pkcs11 with opencryptoki, no ssl engine."; |
1634 | 1768 |
1635 slot_handler_.reset(new Pkcs11SlotHandlerGLaptop()); | 1769 bool res = Initialize(); |
1636 slot_handler_->Initialize(); | 1770 |
| 1771 Pkcs11SlotHandlerGLaptop* slot_handler = |
| 1772 new Pkcs11SlotHandlerGLaptop(); |
| 1773 slot_handler_.reset(slot_handler); |
| 1774 slot_handler->Initialize(); |
| 1775 slot_handler->ReadObjectsFromSlot(this); |
1637 | 1776 |
1638 Pkcs11CertificateHandlerOpenSsl* cert_handler = | 1777 Pkcs11CertificateHandlerOpenSsl* cert_handler = |
1639 new Pkcs11CertificateHandlerOpenSsl(); | 1778 new Pkcs11CertificateHandlerOpenSsl(); |
1640 cert_handler->Initialize(); | 1779 cert_handler->Initialize(); |
1641 cert_handler->SetTestCertificate(test_cert); | 1780 cert_handler->SetTestCertificate(test_cert); |
1642 cert_handler->SetOutputDER(); | 1781 cert_handler->SetOutputDER(); |
1643 certificate_handler_.reset(cert_handler); | 1782 certificate_handler_.reset(cert_handler); |
1644 | 1783 |
1645 return Initialize(); | 1784 SetupHandlers(); |
| 1785 |
| 1786 return res; |
1646 } | 1787 } |
1647 | 1788 |
1648 bool Pkcs11::InitializeOpenSSL(const std::string& test_cert) { | 1789 bool Pkcs11::InitializeOpenSSL(const std::string& test_cert) { |
1649 LOG(INFO) << "Initializing pkcs11 with openssl."; | 1790 LOG(INFO) << "Initializing pkcs11 with openssl."; |
1650 | 1791 |
| 1792 bool res = Initialize(); |
| 1793 |
1651 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); | 1794 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); |
1652 slot_handler_->Initialize(); | 1795 slot_handler_->Initialize(); |
1653 | 1796 |
1654 Pkcs11CertificateHandlerOpenSsl* cert_handler = | 1797 Pkcs11CertificateHandlerOpenSsl* cert_handler = |
1655 new Pkcs11CertificateHandlerOpenSsl(); | 1798 new Pkcs11CertificateHandlerOpenSsl(); |
1656 cert_handler->Initialize(); | 1799 cert_handler->Initialize(); |
1657 cert_handler->SetTestCertificate(test_cert); | 1800 cert_handler->SetTestCertificate(test_cert); |
1658 certificate_handler_.reset(cert_handler); | 1801 certificate_handler_.reset(cert_handler); |
1659 | 1802 |
1660 return Initialize(); | 1803 SetupHandlers(); |
| 1804 |
| 1805 return res; |
1661 } | 1806 } |
1662 | 1807 |
1663 bool Pkcs11::InitializeLocalFiles(const std::string& csr, | 1808 bool Pkcs11::InitializeLocalFiles(const std::string& csr, |
1664 const std::string& cert) { | 1809 const std::string& cert) { |
| 1810 bool res = Initialize(); |
| 1811 |
1665 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); | 1812 slot_handler_.reset(new Pkcs11SlotHandlerInMemory()); |
1666 slot_handler_->Initialize(); | 1813 slot_handler_->Initialize(); |
1667 | 1814 |
1668 certificate_handler_.reset( | 1815 certificate_handler_.reset( |
1669 new Pkcs11CertificateHandlerLocalFile(csr, cert)); | 1816 new Pkcs11CertificateHandlerLocalFile(csr, cert)); |
1670 certificate_handler_->Initialize(); | 1817 certificate_handler_->Initialize(); |
1671 | 1818 |
1672 return Initialize(); | 1819 SetupHandlers(); |
| 1820 |
| 1821 return res; |
| 1822 } |
| 1823 |
| 1824 // pkcs11[slot_object->label()] = slot_object->obj() |
| 1825 bool Pkcs11::AddJSSlotObject(const SlotObject* slot_object) { |
| 1826 v8::Local<v8::Value> slotsvalue = obj()->Get(v8::String::NewSymbol("slots")); |
| 1827 if (slotsvalue.IsEmpty() || !slotsvalue->IsObject()) { |
| 1828 LOG(ERROR) << "'slots' is not an object in pkcs11"; |
| 1829 return false; |
| 1830 } |
| 1831 v8::Local<v8::Object> slots = v8::Local<v8::Object>::Cast(slotsvalue); |
| 1832 v8::Local<v8::String> v8label = v8::String::New(slot_object->label().c_str()); |
| 1833 slots->Set(v8label, slot_object->obj()); |
| 1834 return true; |
1673 } | 1835 } |
1674 | 1836 |
1675 static v8::Handle<v8::Value> dispatch_setUserPin( | 1837 static v8::Handle<v8::Value> dispatch_setUserPin( |
1676 const v8::Arguments& args) { | 1838 const v8::Arguments& args) { |
1677 // Get the arguments. | 1839 // Get the arguments. |
1678 Pkcs11* pkcs11 = Pkcs11::Unwrap(args.This()); | 1840 Pkcs11* pkcs11 = Pkcs11::Unwrap(args.This()); |
1679 if (pkcs11 == NULL) { | 1841 if (pkcs11 == NULL) { |
1680 utils::ThrowV8Exception("Method called on incorrect object type."); | 1842 utils::ThrowV8Exception("Method called on incorrect object type."); |
1681 return v8::False(); | 1843 return v8::False(); |
1682 } | 1844 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 v8::ReadOnly); | 1898 v8::ReadOnly); |
1737 template_object->Set(v8::String::NewSymbol("clear"), | 1899 template_object->Set(v8::String::NewSymbol("clear"), |
1738 v8::FunctionTemplate::New(dispatch_clearSlotObject), | 1900 v8::FunctionTemplate::New(dispatch_clearSlotObject), |
1739 v8::ReadOnly); | 1901 v8::ReadOnly); |
1740 template_object->Set(v8::String::NewSymbol("slots"), | 1902 template_object->Set(v8::String::NewSymbol("slots"), |
1741 v8::Object::New(), | 1903 v8::Object::New(), |
1742 v8::ReadOnly); | 1904 v8::ReadOnly); |
1743 } | 1905 } |
1744 | 1906 |
1745 } // namespace entd | 1907 } // namespace entd |
OLD | NEW |