OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium 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 "content/child/webcrypto/platform_crypto.h" | 5 #include "content/child/webcrypto/platform_crypto.h" |
6 | 6 |
7 #include <cryptohi.h> | 7 #include <cryptohi.h> |
8 #include <pk11pub.h> | 8 #include <pk11pub.h> |
9 #include <secerr.h> | 9 #include <secerr.h> |
10 #include <sechash.h> | 10 #include <sechash.h> |
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 size_t reverse_i = data_size - i - 1; | 546 size_t reverse_i = data_size - i - 1; |
547 | 547 |
548 if (reverse_i >= sizeof(unsigned long) && data[i]) | 548 if (reverse_i >= sizeof(unsigned long) && data[i]) |
549 return false; // Too large for a long. | 549 return false; // Too large for a long. |
550 | 550 |
551 *result |= data[i] << 8 * reverse_i; | 551 *result |= data[i] << 8 * reverse_i; |
552 } | 552 } |
553 return true; | 553 return true; |
554 } | 554 } |
555 | 555 |
556 bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { | |
557 return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || | |
558 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep || | |
559 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; | |
560 } | |
561 | |
562 bool CreatePublicKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, | 556 bool CreatePublicKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, |
563 SECKEYPublicKey* key, | 557 SECKEYPublicKey* key, |
564 blink::WebCryptoKeyAlgorithm* key_algorithm) { | 558 blink::WebCryptoKeyAlgorithm* key_algorithm) { |
565 // TODO(eroman): What about other key types rsaPss, rsaOaep. | 559 // TODO(eroman): What about other key types rsaPss, rsaOaep. |
566 if (!key || key->keyType != rsaKey) | 560 if (!key || key->keyType != rsaKey) |
567 return false; | 561 return false; |
568 | 562 |
569 unsigned int modulus_length_bits = SECKEY_PublicKeyStrength(key) * 8; | 563 unsigned int modulus_length_bits = SECKEY_PublicKeyStrength(key) * 8; |
570 CryptoData public_exponent(key->u.rsa.publicExponent.data, | 564 CryptoData public_exponent(key->u.rsa.publicExponent.data, |
571 key->u.rsa.publicExponent.len); | 565 key->u.rsa.publicExponent.len); |
572 | 566 |
573 switch (algorithm.paramsType()) { | 567 switch (algorithm.paramsType()) { |
574 case blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams: | 568 case blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams: |
575 case blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams: | 569 case blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams: |
576 *key_algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed( | 570 *key_algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed( |
577 algorithm.id(), | 571 algorithm.id(), |
578 modulus_length_bits, | 572 modulus_length_bits, |
579 public_exponent.bytes(), | 573 public_exponent.bytes(), |
580 public_exponent.byte_length(), | 574 public_exponent.byte_length(), |
581 GetInnerHashAlgorithm(algorithm).id()); | 575 GetInnerHashAlgorithm(algorithm).id()); |
582 return true; | 576 return true; |
583 case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams: | |
584 case blink::WebCryptoAlgorithmParamsTypeNone: | |
585 *key_algorithm = blink::WebCryptoKeyAlgorithm::createRsa( | |
586 algorithm.id(), | |
587 modulus_length_bits, | |
588 public_exponent.bytes(), | |
589 public_exponent.byte_length()); | |
590 return true; | |
591 default: | 577 default: |
592 return false; | 578 return false; |
593 } | 579 } |
594 } | 580 } |
595 | 581 |
596 bool CreatePrivateKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, | 582 bool CreatePrivateKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, |
597 SECKEYPrivateKey* key, | 583 SECKEYPrivateKey* key, |
598 blink::WebCryptoKeyAlgorithm* key_algorithm) { | 584 blink::WebCryptoKeyAlgorithm* key_algorithm) { |
599 crypto::ScopedSECKEYPublicKey public_key(SECKEY_ConvertToPublicKey(key)); | 585 crypto::ScopedSECKEYPublicKey public_key(SECKEY_ConvertToPublicKey(key)); |
600 return CreatePublicKeyAlgorithm(algorithm, public_key.get(), key_algorithm); | 586 return CreatePublicKeyAlgorithm(algorithm, public_key.get(), key_algorithm); |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, | 966 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, |
981 SECKEY_DestroySubjectPublicKeyInfo> > | 967 SECKEY_DestroySubjectPublicKeyInfo> > |
982 ScopedCERTSubjectPublicKeyInfo; | 968 ScopedCERTSubjectPublicKeyInfo; |
983 | 969 |
984 // Validates an NSS KeyType against a WebCrypto import algorithm. | 970 // Validates an NSS KeyType against a WebCrypto import algorithm. |
985 bool ValidateNssKeyTypeAgainstInputAlgorithm( | 971 bool ValidateNssKeyTypeAgainstInputAlgorithm( |
986 KeyType key_type, | 972 KeyType key_type, |
987 const blink::WebCryptoAlgorithm& algorithm) { | 973 const blink::WebCryptoAlgorithm& algorithm) { |
988 switch (key_type) { | 974 switch (key_type) { |
989 case rsaKey: | 975 case rsaKey: |
990 return IsAlgorithmRsa(algorithm); | 976 return IsAlgorithmRsa(algorithm.id()); |
991 case dsaKey: | 977 case dsaKey: |
992 case ecKey: | 978 case ecKey: |
993 case rsaPssKey: | 979 case rsaPssKey: |
994 case rsaOaepKey: | 980 case rsaOaepKey: |
995 // TODO(padolph): Handle other key types. | 981 // TODO(padolph): Handle other key types. |
996 break; | 982 break; |
997 default: | 983 default: |
998 break; | 984 break; |
999 } | 985 } |
1000 return false; | 986 return false; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 AssignVectorFromSecItem(key_props.exponent2, exponent2); | 1093 AssignVectorFromSecItem(key_props.exponent2, exponent2); |
1108 AssignVectorFromSecItem(key_props.coefficient, coefficient); | 1094 AssignVectorFromSecItem(key_props.coefficient, coefficient); |
1109 | 1095 |
1110 return Status::Success(); | 1096 return Status::Success(); |
1111 } | 1097 } |
1112 | 1098 |
1113 Status ExportKeyPkcs8(PrivateKey* key, | 1099 Status ExportKeyPkcs8(PrivateKey* key, |
1114 const blink::WebCryptoKeyAlgorithm& key_algorithm, | 1100 const blink::WebCryptoKeyAlgorithm& key_algorithm, |
1115 std::vector<uint8>* buffer) { | 1101 std::vector<uint8>* buffer) { |
1116 // TODO(eroman): Support other RSA key types as they are added to Blink. | 1102 // TODO(eroman): Support other RSA key types as they are added to Blink. |
1117 if (key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 && | 1103 if (key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 && |
1118 key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 && | |
1119 key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaOaep) | 1104 key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaOaep) |
1120 return Status::ErrorUnsupported(); | 1105 return Status::ErrorUnsupported(); |
1121 | 1106 |
1122 // TODO(rsleevi): Implement OAEP support according to the spec. | 1107 // TODO(rsleevi): Implement OAEP support according to the spec. |
1123 | 1108 |
1124 #if defined(USE_NSS) | 1109 #if defined(USE_NSS) |
1125 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. | 1110 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. |
1126 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; | 1111 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; |
1127 const int kPrivateKeyInfoVersion = 0; | 1112 const int kPrivateKeyInfoVersion = 0; |
1128 | 1113 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1260 &signature_item, | 1245 &signature_item, |
1261 &data_item) != SECSuccess) { | 1246 &data_item) != SECSuccess) { |
1262 return Status::OperationError(); | 1247 return Status::OperationError(); |
1263 } | 1248 } |
1264 | 1249 |
1265 DCHECK_EQ(buffer->size(), signature_item.len); | 1250 DCHECK_EQ(buffer->size(), signature_item.len); |
1266 return Status::Success(); | 1251 return Status::Success(); |
1267 } | 1252 } |
1268 | 1253 |
1269 // ----------------------------------- | 1254 // ----------------------------------- |
1270 // RsaEsPkcs1v1_5 | |
1271 // ----------------------------------- | |
1272 | |
1273 Status EncryptRsaEsPkcs1v1_5(PublicKey* key, | |
1274 const CryptoData& data, | |
1275 std::vector<uint8>* buffer) { | |
1276 const unsigned int encrypted_length_bytes = | |
1277 SECKEY_PublicKeyStrength(key->key()); | |
1278 | |
1279 // RSAES can operate on messages up to a length of k - 11, where k is the | |
1280 // octet length of the RSA modulus. | |
1281 if (encrypted_length_bytes < 11 || | |
1282 encrypted_length_bytes - 11 < data.byte_length()) | |
1283 return Status::ErrorDataTooLarge(); | |
1284 | |
1285 buffer->resize(encrypted_length_bytes); | |
1286 unsigned char* const buffer_data = Uint8VectorStart(buffer); | |
1287 | |
1288 if (PK11_PubEncryptPKCS1(key->key(), | |
1289 buffer_data, | |
1290 const_cast<unsigned char*>(data.bytes()), | |
1291 data.byte_length(), | |
1292 NULL) != SECSuccess) { | |
1293 return Status::OperationError(); | |
1294 } | |
1295 return Status::Success(); | |
1296 } | |
1297 | |
1298 Status DecryptRsaEsPkcs1v1_5(PrivateKey* key, | |
1299 const CryptoData& data, | |
1300 std::vector<uint8>* buffer) { | |
1301 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); | |
1302 if (modulus_length_bytes <= 0) | |
1303 return Status::ErrorUnexpected(); | |
1304 const unsigned int max_output_length_bytes = modulus_length_bytes; | |
1305 | |
1306 buffer->resize(max_output_length_bytes); | |
1307 unsigned char* const buffer_data = Uint8VectorStart(buffer); | |
1308 | |
1309 unsigned int output_length_bytes = 0; | |
1310 if (PK11_PrivDecryptPKCS1(key->key(), | |
1311 buffer_data, | |
1312 &output_length_bytes, | |
1313 max_output_length_bytes, | |
1314 const_cast<unsigned char*>(data.bytes()), | |
1315 data.byte_length()) != SECSuccess) { | |
1316 return Status::OperationError(); | |
1317 } | |
1318 DCHECK_LE(output_length_bytes, max_output_length_bytes); | |
1319 buffer->resize(output_length_bytes); | |
1320 return Status::Success(); | |
1321 } | |
1322 | |
1323 // ----------------------------------- | |
1324 // RsaOaep | 1255 // RsaOaep |
1325 // ----------------------------------- | 1256 // ----------------------------------- |
1326 | 1257 |
1327 Status EncryptRsaOaep(PublicKey* key, | 1258 Status EncryptRsaOaep(PublicKey* key, |
1328 const blink::WebCryptoAlgorithm& hash, | 1259 const blink::WebCryptoAlgorithm& hash, |
1329 const CryptoData& label, | 1260 const CryptoData& label, |
1330 const CryptoData& data, | 1261 const CryptoData& data, |
1331 std::vector<uint8>* buffer) { | 1262 std::vector<uint8>* buffer) { |
1332 if (!g_nss_runtime_support.Get().IsRsaOaepSupported()) | 1263 if (!g_nss_runtime_support.Get().IsRsaOaepSupported()) |
1333 return Status::ErrorUnsupported(); | 1264 return Status::ErrorUnsupported(); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 | 1436 |
1506 // ----------------------------------- | 1437 // ----------------------------------- |
1507 // Key generation | 1438 // Key generation |
1508 // ----------------------------------- | 1439 // ----------------------------------- |
1509 | 1440 |
1510 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, | 1441 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
1511 bool extractable, | 1442 bool extractable, |
1512 blink::WebCryptoKeyUsageMask usage_mask, | 1443 blink::WebCryptoKeyUsageMask usage_mask, |
1513 unsigned int modulus_length_bits, | 1444 unsigned int modulus_length_bits, |
1514 const CryptoData& public_exponent, | 1445 const CryptoData& public_exponent, |
1515 const blink::WebCryptoAlgorithm& hash_or_null, | |
1516 blink::WebCryptoKey* public_key, | 1446 blink::WebCryptoKey* public_key, |
1517 blink::WebCryptoKey* private_key) { | 1447 blink::WebCryptoKey* private_key) { |
1518 if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep && | 1448 if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep && |
1519 !g_nss_runtime_support.Get().IsRsaOaepSupported()) { | 1449 !g_nss_runtime_support.Get().IsRsaOaepSupported()) { |
1520 return Status::ErrorUnsupported(); | 1450 return Status::ErrorUnsupported(); |
1521 } | 1451 } |
1522 | 1452 |
1523 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 1453 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
1524 if (!slot) | 1454 if (!slot) |
1525 return Status::OperationError(); | 1455 return Status::OperationError(); |
1526 | 1456 |
1527 unsigned long public_exponent_long; | 1457 unsigned long public_exponent_long; |
1528 if (!BigIntegerToLong(public_exponent.bytes(), | 1458 if (!BigIntegerToLong(public_exponent.bytes(), |
1529 public_exponent.byte_length(), | 1459 public_exponent.byte_length(), |
1530 &public_exponent_long) || | 1460 &public_exponent_long) || |
1531 !public_exponent_long) { | 1461 !public_exponent_long) { |
1532 return Status::ErrorGenerateKeyPublicExponent(); | 1462 return Status::ErrorGenerateKeyPublicExponent(); |
1533 } | 1463 } |
1534 | 1464 |
1535 PK11RSAGenParams rsa_gen_params; | 1465 PK11RSAGenParams rsa_gen_params; |
1536 rsa_gen_params.keySizeInBits = modulus_length_bits; | 1466 rsa_gen_params.keySizeInBits = modulus_length_bits; |
1537 rsa_gen_params.pe = public_exponent_long; | 1467 rsa_gen_params.pe = public_exponent_long; |
1538 | 1468 |
1539 // Flags are verified at the Blink layer; here the flags are set to all | 1469 // Flags are verified at the Blink layer; here the flags are set to all |
1540 // possible operations for the given key type. | 1470 // possible operations for the given key type. |
1541 CK_FLAGS operation_flags; | 1471 CK_FLAGS operation_flags; |
1542 switch (algorithm.id()) { | 1472 switch (algorithm.id()) { |
1543 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | |
1544 case blink::WebCryptoAlgorithmIdRsaOaep: | 1473 case blink::WebCryptoAlgorithmIdRsaOaep: |
1545 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; | 1474 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; |
1546 break; | 1475 break; |
1547 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 1476 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: |
1548 operation_flags = CKF_SIGN | CKF_VERIFY; | 1477 operation_flags = CKF_SIGN | CKF_VERIFY; |
1549 break; | 1478 break; |
1550 default: | 1479 default: |
1551 NOTREACHED(); | 1480 NOTREACHED(); |
1552 return Status::ErrorUnexpected(); | 1481 return Status::ErrorUnexpected(); |
1553 } | 1482 } |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1928 if (PK11_ExtractKeyValue(decrypted.get()) != SECSuccess) | 1857 if (PK11_ExtractKeyValue(decrypted.get()) != SECSuccess) |
1929 return Status::OperationError(); | 1858 return Status::OperationError(); |
1930 const SECItem* const key_data = PK11_GetKeyData(decrypted.get()); | 1859 const SECItem* const key_data = PK11_GetKeyData(decrypted.get()); |
1931 if (!key_data) | 1860 if (!key_data) |
1932 return Status::OperationError(); | 1861 return Status::OperationError(); |
1933 buffer->assign(key_data->data, key_data->data + key_data->len); | 1862 buffer->assign(key_data->data, key_data->data + key_data->len); |
1934 | 1863 |
1935 return Status::Success(); | 1864 return Status::Success(); |
1936 } | 1865 } |
1937 | 1866 |
1938 Status WrapSymKeyRsaEs(SymKey* key, | |
1939 PublicKey* wrapping_key, | |
1940 std::vector<uint8>* buffer) { | |
1941 // Check the raw length of the key to be wrapped against the max size allowed | |
1942 // by the RSA wrapping key. With PKCS#1 v1.5 padding used in this function, | |
1943 // the maximum data length that can be encrypted is the wrapping_key's modulus | |
1944 // byte length minus eleven bytes. | |
1945 const unsigned int input_length_bytes = PK11_GetKeyLength(key->key()); | |
1946 const unsigned int modulus_length_bytes = | |
1947 SECKEY_PublicKeyStrength(wrapping_key->key()); | |
1948 if (modulus_length_bytes < 11 || | |
1949 modulus_length_bytes - 11 < input_length_bytes) | |
1950 return Status::ErrorDataTooLarge(); | |
1951 | |
1952 buffer->resize(modulus_length_bytes); | |
1953 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); | |
1954 | |
1955 if (SECSuccess != | |
1956 PK11_PubWrapSymKey( | |
1957 CKM_RSA_PKCS, wrapping_key->key(), key->key(), &wrapped_key_item)) { | |
1958 return Status::OperationError(); | |
1959 } | |
1960 if (wrapped_key_item.len != modulus_length_bytes) | |
1961 return Status::ErrorUnexpected(); | |
1962 | |
1963 return Status::Success(); | |
1964 } | |
1965 | |
1966 Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data, | |
1967 PrivateKey* wrapping_key, | |
1968 const blink::WebCryptoAlgorithm& algorithm, | |
1969 bool extractable, | |
1970 blink::WebCryptoKeyUsageMask usage_mask, | |
1971 blink::WebCryptoKey* key) { | |
1972 // Verify wrapped_key_data size does not exceed the modulus of the RSA key. | |
1973 const int modulus_length_bytes = | |
1974 PK11_GetPrivateModulusLen(wrapping_key->key()); | |
1975 if (modulus_length_bytes <= 0) | |
1976 return Status::ErrorUnexpected(); | |
1977 if (wrapped_key_data.byte_length() > | |
1978 static_cast<unsigned int>(modulus_length_bytes)) | |
1979 return Status::ErrorDataTooLarge(); | |
1980 | |
1981 // Determine the proper NSS key properties from the input algorithm. | |
1982 CK_MECHANISM_TYPE mechanism; | |
1983 CK_FLAGS flags; | |
1984 Status status = | |
1985 WebCryptoAlgorithmToNssMechFlags(algorithm, &mechanism, &flags); | |
1986 if (status.IsError()) | |
1987 return status; | |
1988 | |
1989 SECItem wrapped_key_item = MakeSECItemForBuffer(wrapped_key_data); | |
1990 | |
1991 crypto::ScopedPK11SymKey unwrapped_key( | |
1992 PK11_PubUnwrapSymKeyWithFlagsPerm(wrapping_key->key(), | |
1993 &wrapped_key_item, | |
1994 mechanism, | |
1995 CKA_DECRYPT, | |
1996 0, | |
1997 flags, | |
1998 false)); | |
1999 if (!unwrapped_key) | |
2000 return Status::OperationError(); | |
2001 | |
2002 const unsigned int key_length = PK11_GetKeyLength(unwrapped_key.get()); | |
2003 | |
2004 blink::WebCryptoKeyAlgorithm key_algorithm; | |
2005 if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm)) | |
2006 return Status::ErrorUnexpected(); | |
2007 | |
2008 scoped_ptr<SymKey> key_handle; | |
2009 status = SymKey::Create(unwrapped_key.Pass(), &key_handle); | |
2010 if (status.IsError()) | |
2011 return status; | |
2012 | |
2013 *key = blink::WebCryptoKey::create(key_handle.release(), | |
2014 blink::WebCryptoKeyTypeSecret, | |
2015 extractable, | |
2016 key_algorithm, | |
2017 usage_mask); | |
2018 return Status::Success(); | |
2019 } | |
2020 | |
2021 } // namespace platform | 1867 } // namespace platform |
2022 | 1868 |
2023 } // namespace webcrypto | 1869 } // namespace webcrypto |
2024 | 1870 |
2025 } // namespace content | 1871 } // namespace content |
OLD | NEW |