Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Side by Side Diff: content/child/webcrypto/platform_crypto_nss.cc

Issue 282903002: [webcrypto] Remove RSA-ES support (2 of 3) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase and merge conflicts (yuck) Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/child/webcrypto/platform_crypto.h ('k') | content/child/webcrypto/platform_crypto_openssl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698