| 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 |