Chromium Code Reviews| Index: content/renderer/webcrypto/platform_crypto_nss.cc |
| diff --git a/content/renderer/webcrypto/platform_crypto_nss.cc b/content/renderer/webcrypto/platform_crypto_nss.cc |
| index 4cc7b3722e9d48f0ac1e8dcf44dd04e044b6f265..3d3b1bcdc0f7f9babd188a0fc18b3408241c445a 100644 |
| --- a/content/renderer/webcrypto/platform_crypto_nss.cc |
| +++ b/content/renderer/webcrypto/platform_crypto_nss.cc |
| @@ -19,6 +19,9 @@ |
| #include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
| #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
| #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
| +#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| +#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
| +#endif |
| #if defined(USE_NSS) |
| #include <dlfcn.h> |
| @@ -367,7 +370,11 @@ CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( |
| case blink::WebCryptoAlgorithmIdAesKw: |
| return CKM_AES_KEY_GEN; |
| case blink::WebCryptoAlgorithmIdHmac: |
| +#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| + return WebCryptoHashToHMACMechanism(algorithm.hmacKeyGenParams()->hash()); |
| +#else |
| return WebCryptoHashToHMACMechanism(algorithm.hmacKeyParams()->hash()); |
| +#endif |
| default: |
| return CKM_INVALID_MECHANISM; |
| } |
| @@ -375,22 +382,18 @@ CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( |
| // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, |
| // to unsigned long. |
| -bool BigIntegerToLong(const uint8* data, |
| - unsigned int data_size, |
| - unsigned long* result) { |
| - // TODO(padolph): Is it correct to say that empty data is an error, or does it |
| - // mean value 0? See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23655 |
| - if (data_size == 0) |
| +bool BigIntegerToLong(const CryptoData& data, unsigned long* result) { |
| + if (!data.byte_length()) |
| return false; |
| *result = 0; |
| - for (size_t i = 0; i < data_size; ++i) { |
| - size_t reverse_i = data_size - i - 1; |
| + for (size_t i = 0; i < data.byte_length(); ++i) { |
| + size_t reverse_i = data.byte_length() - i - 1; |
| - if (reverse_i >= sizeof(unsigned long) && data[i]) |
| + if (reverse_i >= sizeof(unsigned long) && data.bytes()[i]) |
| return false; // Too large for a long. |
| - *result |= data[i] << 8 * reverse_i; |
| + *result |= data.bytes()[i] << 8 * reverse_i; |
| } |
| return true; |
| } |
| @@ -401,6 +404,54 @@ bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { |
| algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; |
| } |
| +#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| +bool CreatePublicKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, |
| + SECKEYPublicKey* key, |
| + blink::WebCryptoKeyAlgorithm* key_algorithm) { |
| + if (!key || key->keyType != rsaKey) |
|
Ryan Sleevi
2014/02/25 22:26:26
rsaPssKey
rsaOaepKey
eroman
2014/02/25 23:26:47
Added a TODO.
I don't want to add that handling u
|
| + return false; |
| + |
| + unsigned int modulus_length_bits = SECKEY_PublicKeyStrength(key) * 8; |
| + CryptoData public_exponent(key->u.rsa.publicExponent.data, |
| + key->u.rsa.publicExponent.len); |
| + |
| + if (algorithm.paramsType() == |
| + blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams || |
| + algorithm.paramsType() == |
| + blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams) { |
| + *key_algorithm = blink::WebCryptoKeyAlgorithm::adoptParamsAndCreate( |
| + algorithm.id(), |
| + new blink::WebCryptoRsaHashedKeyAlgorithmParams( |
| + modulus_length_bits, |
| + public_exponent.bytes(), |
| + public_exponent.byte_length(), |
| + GetInnerHashAlgorithm(algorithm))); |
| + return true; |
| + } |
| + |
| + if (algorithm.paramsType() == |
| + blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams || |
| + algorithm.paramsType() == blink::WebCryptoAlgorithmParamsTypeNone) { |
|
Ryan Sleevi
2014/02/25 22:26:26
Does it make sense to make these a set of switch s
eroman
2014/02/25 23:26:47
Yes, that makes more sense.
Done.
Thanks
|
| + *key_algorithm = blink::WebCryptoKeyAlgorithm::adoptParamsAndCreate( |
| + algorithm.id(), |
| + new blink::WebCryptoRsaKeyAlgorithmParams( |
| + modulus_length_bits, |
| + public_exponent.bytes(), |
| + public_exponent.byte_length())); |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| +bool CreatePrivateKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, |
| + SECKEYPrivateKey* key, |
| + blink::WebCryptoKeyAlgorithm* key_algorithm) { |
| + return CreatePublicKeyAlgorithm( |
| + algorithm, SECKEY_ConvertToPublicKey(key), key_algorithm); |
| +} |
| +#endif |
| + |
| } // namespace |
| Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
| @@ -420,16 +471,13 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
| switch (algorithm.id()) { |
| case blink::WebCryptoAlgorithmIdHmac: { |
| - const blink::WebCryptoHmacParams* params = algorithm.hmacParams(); |
| - if (!params) |
| - return Status::ErrorUnexpected(); |
| + const blink::WebCryptoAlgorithm& hash = GetInnerHashAlgorithm(algorithm); |
| - mechanism = WebCryptoHashToHMACMechanism(params->hash()); |
| + mechanism = WebCryptoHashToHMACMechanism(hash); |
| if (mechanism == CKM_INVALID_MECHANISM) |
| return Status::ErrorUnsupported(); |
| flags |= CKF_SIGN | CKF_VERIFY; |
| - |
| break; |
| } |
| case blink::WebCryptoAlgorithmIdAesCbc: { |
| @@ -471,10 +519,19 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
| if (!pk11_sym_key.get()) |
| return Status::Error(); |
| +#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| + blink::WebCryptoKeyAlgorithm key_algorithm; |
| + if (!CreateSecretKeyAlgorithm( |
| + algorithm, key_data.byte_length(), &key_algorithm)) |
| + return Status::ErrorUnexpected(); |
| +#else |
| + const blink::WebCryptoAlgorithm& key_algorithm = algorithm; |
| +#endif |
| + |
| *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), |
| blink::WebCryptoKeyTypeSecret, |
| extractable, |
| - algorithm, |
| + key_algorithm, |
| usage_mask); |
| return Status::Success(); |
| } |
| @@ -533,7 +590,6 @@ blink::WebCryptoAlgorithm ResolveNssKeyTypeWithInputAlgorithm( |
| Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm_or_null, |
| const CryptoData& key_data, |
| - bool extractable, |
| blink::WebCryptoKeyUsageMask usage_mask, |
| blink::WebCryptoKey* key) { |
| @@ -562,10 +618,19 @@ Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm_or_null, |
| if (algorithm.isNull()) |
| return Status::Error(); |
| +#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| + blink::WebCryptoKeyAlgorithm key_algorithm; |
| + if (!CreatePublicKeyAlgorithm( |
| + algorithm, sec_public_key.get(), &key_algorithm)) |
| + return Status::ErrorUnexpected(); |
| +#else |
| + const blink::WebCryptoAlgorithm& key_algorithm = algorithm; |
| +#endif |
| + |
| *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), |
| blink::WebCryptoKeyTypePublic, |
| - extractable, |
| - algorithm, |
| + true, |
| + key_algorithm, |
| usage_mask); |
| return Status::Success(); |
| @@ -623,10 +688,18 @@ Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm_or_null, |
| if (algorithm.isNull()) |
| return Status::Error(); |
| +#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| + blink::WebCryptoKeyAlgorithm key_algorithm; |
| + if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) |
| + return Status::ErrorUnexpected(); |
| +#else |
| + const blink::WebCryptoAlgorithm& key_algorithm = algorithm; |
| +#endif |
| + |
| *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), |
| blink::WebCryptoKeyTypePrivate, |
| extractable, |
| - algorithm, |
| + key_algorithm, |
| usage_mask); |
| return Status::Success(); |
| @@ -840,30 +913,24 @@ Status EncryptDecryptAesGcm(EncryptOrDecrypt mode, |
| Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
| bool extractable, |
| blink::WebCryptoKeyUsageMask usage_mask, |
| + unsigned int modulus_length_bits, |
| + const CryptoData& public_exponent, |
| + const blink::WebCryptoAlgorithm& hash_or_null, |
| blink::WebCryptoKey* public_key, |
| blink::WebCryptoKey* private_key) { |
| - const blink::WebCryptoRsaKeyGenParams* const params = |
| - algorithm.rsaKeyGenParams(); |
| - DCHECK(params); |
| - |
| crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
| if (!slot) |
| return Status::Error(); |
| - unsigned long public_exponent; |
| - if (!params->modulusLengthBits()) |
| - return Status::ErrorGenerateRsaZeroModulus(); |
| - |
| - if (!BigIntegerToLong(params->publicExponent().data(), |
| - params->publicExponent().size(), |
| - &public_exponent) || |
| - !public_exponent) { |
| + unsigned long public_exponent_long; |
| + if (!BigIntegerToLong(public_exponent, &public_exponent_long) || |
| + !public_exponent_long) { |
| return Status::ErrorGenerateKeyPublicExponent(); |
| } |
| PK11RSAGenParams rsa_gen_params; |
| - rsa_gen_params.keySizeInBits = params->modulusLengthBits(); |
| - rsa_gen_params.pe = public_exponent; |
| + rsa_gen_params.keySizeInBits = modulus_length_bits; |
| + rsa_gen_params.pe = public_exponent_long; |
| // Flags are verified at the Blink layer; here the flags are set to all |
| // possible operations for the given key type. |
| @@ -899,17 +966,25 @@ Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
| if (!private_key) |
| return Status::Error(); |
| +#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| + blink::WebCryptoKeyAlgorithm key_algorithm; |
| + if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) |
| + return Status::ErrorUnexpected(); |
| +#else |
| + const blink::WebCryptoAlgorithm& key_algorithm = algorithm; |
| +#endif |
| + |
| *public_key = blink::WebCryptoKey::create( |
| new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), |
| blink::WebCryptoKeyTypePublic, |
| true, |
| - algorithm, |
| + key_algorithm, |
| usage_mask); |
| *private_key = |
| blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()), |
| blink::WebCryptoKeyTypePrivate, |
| extractable, |
| - algorithm, |
| + key_algorithm, |
| usage_mask); |
| return Status::Success(); |
| @@ -970,10 +1045,18 @@ Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, |
| if (!pk11_key) |
| return Status::Error(); |
| +#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| + blink::WebCryptoKeyAlgorithm key_algorithm; |
| + if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm)) |
| + return Status::ErrorUnexpected(); |
| +#else |
| + const blink::WebCryptoAlgorithm& key_algorithm = algorithm; |
| +#endif |
| + |
| *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), |
| key_type, |
| extractable, |
| - algorithm, |
| + key_algorithm, |
| usage_mask); |
| return Status::Success(); |
| } |
| @@ -1029,10 +1112,18 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
| if (!pubkey) |
| return Status::Error(); |
| +#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| + blink::WebCryptoKeyAlgorithm key_algorithm; |
| + if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) |
| + return Status::ErrorUnexpected(); |
| +#else |
| + const blink::WebCryptoAlgorithm& key_algorithm = algorithm; |
| +#endif |
| + |
| *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()), |
| blink::WebCryptoKeyTypePublic, |
| extractable, |
| - algorithm, |
| + key_algorithm, |
| usage_mask); |
| return Status::Success(); |
| } |