Chromium Code Reviews| 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 "components/webcrypto/algorithms/rsa.h" | 5 #include "components/webcrypto/algorithms/rsa.h" |
| 6 | 6 |
| 7 #include <openssl/evp.h> | 7 #include <openssl/evp.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "components/webcrypto/algorithms/asymmetric_key_util.h" | 11 #include "components/webcrypto/algorithms/asymmetric_key_util.h" |
| 12 #include "components/webcrypto/algorithms/util.h" | 12 #include "components/webcrypto/algorithms/util.h" |
| 13 #include "components/webcrypto/blink_key_handle.h" | 13 #include "components/webcrypto/blink_key_handle.h" |
| 14 #include "components/webcrypto/crypto_data.h" | 14 #include "components/webcrypto/crypto_data.h" |
| 15 #include "components/webcrypto/generate_key_result.h" | 15 #include "components/webcrypto/generate_key_result.h" |
| 16 #include "components/webcrypto/jwk.h" | 16 #include "components/webcrypto/jwk.h" |
| 17 #include "components/webcrypto/status.h" | 17 #include "components/webcrypto/status.h" |
| 18 #include "crypto/openssl_util.h" | 18 #include "crypto/openssl_util.h" |
| 19 #include "crypto/scoped_openssl_types.h" | 19 #include "crypto/scoped_openssl_types.h" |
| 20 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 20 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
| 21 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 21 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
| 22 #include "third_party/WebKit/public/platform/WebCryptoUtil.h" | |
| 22 | 23 |
| 23 namespace webcrypto { | 24 namespace webcrypto { |
| 24 | 25 |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| 27 // Describes the RSA components for a parsed key. The names of the properties | 28 // Describes the RSA components for a parsed key. The names of the properties |
| 28 // correspond with those from the JWK spec. Note that Chromium's WebCrypto | 29 // correspond with those from the JWK spec. Note that Chromium's WebCrypto |
| 29 // implementation does not support multi-primes, so there is no parsed field | 30 // implementation does not support multi-primes, so there is no parsed field |
| 30 // for "oth". | 31 // for "oth". |
| 31 struct JwkRsaInfo { | 32 struct JwkRsaInfo { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 97 if (status.IsError()) | 98 if (status.IsError()) |
| 98 return status; | 99 return status; |
| 99 | 100 |
| 100 status = jwk.GetBigInteger("qi", &result->qi); | 101 status = jwk.GetBigInteger("qi", &result->qi); |
| 101 if (status.IsError()) | 102 if (status.IsError()) |
| 102 return status; | 103 return status; |
| 103 | 104 |
| 104 return Status::Success(); | 105 return Status::Success(); |
| 105 } | 106 } |
| 106 | 107 |
| 107 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, | |
| 108 // to unsigned int. | |
| 109 bool BigIntegerToUint(const uint8_t* data, | |
| 110 size_t data_size, | |
| 111 unsigned int* result) { | |
| 112 if (data_size == 0) | |
| 113 return false; | |
| 114 | |
| 115 *result = 0; | |
| 116 for (size_t i = 0; i < data_size; ++i) { | |
| 117 size_t reverse_i = data_size - i - 1; | |
| 118 | |
| 119 if (reverse_i >= sizeof(*result) && data[i]) | |
| 120 return false; // Too large for a uint. | |
| 121 | |
| 122 *result |= data[i] << 8 * reverse_i; | |
| 123 } | |
| 124 return true; | |
| 125 } | |
| 126 | |
| 127 // Creates a blink::WebCryptoAlgorithm having the modulus length and public | 108 // Creates a blink::WebCryptoAlgorithm having the modulus length and public |
| 128 // exponent of |key|. | 109 // exponent of |key|. |
| 129 Status CreateRsaHashedKeyAlgorithm( | 110 Status CreateRsaHashedKeyAlgorithm( |
| 130 blink::WebCryptoAlgorithmId rsa_algorithm, | 111 blink::WebCryptoAlgorithmId rsa_algorithm, |
| 131 blink::WebCryptoAlgorithmId hash_algorithm, | 112 blink::WebCryptoAlgorithmId hash_algorithm, |
| 132 EVP_PKEY* key, | 113 EVP_PKEY* key, |
| 133 blink::WebCryptoKeyAlgorithm* key_algorithm) { | 114 blink::WebCryptoKeyAlgorithm* key_algorithm) { |
| 134 DCHECK_EQ(EVP_PKEY_RSA, EVP_PKEY_id(key)); | 115 DCHECK_EQ(EVP_PKEY_RSA, EVP_PKEY_id(key)); |
| 135 | 116 |
| 136 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(key)); | 117 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(key)); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 // | 272 // |
| 292 // These correspond with limitations at the time there was an NSS WebCrypto | 273 // These correspond with limitations at the time there was an NSS WebCrypto |
| 293 // implementation. However in practice the upper bound is also helpful | 274 // implementation. However in practice the upper bound is also helpful |
| 294 // because generating large RSA keys is very slow. | 275 // because generating large RSA keys is very slow. |
| 295 if (modulus_length_bits < 256 || modulus_length_bits > 16384 || | 276 if (modulus_length_bits < 256 || modulus_length_bits > 16384 || |
| 296 (modulus_length_bits % 8) != 0) { | 277 (modulus_length_bits % 8) != 0) { |
| 297 return Status::ErrorGenerateRsaUnsupportedModulus(); | 278 return Status::ErrorGenerateRsaUnsupportedModulus(); |
| 298 } | 279 } |
| 299 | 280 |
| 300 unsigned int public_exponent = 0; | 281 unsigned int public_exponent = 0; |
| 301 if (!BigIntegerToUint(params->publicExponent().data(), | 282 if (!blink::bigIntegerToUint(params->publicExponent(), public_exponent)) { |
|
eroman
2015/10/28 19:12:41
nit: remove the curly brackets (to match style els
tommi (sloooow) - chröme
2015/10/29 09:01:17
ping
hbos_chromium
2015/10/29 09:26:39
Done.
| |
| 302 params->publicExponent().size(), &public_exponent)) { | |
| 303 return Status::ErrorGenerateKeyPublicExponent(); | 283 return Status::ErrorGenerateKeyPublicExponent(); |
| 304 } | 284 } |
| 305 | 285 |
| 306 // OpenSSL hangs when given bad public exponents. Use a whitelist. | 286 // OpenSSL hangs when given bad public exponents. Use a whitelist. |
| 307 if (public_exponent != 3 && public_exponent != 65537) | 287 if (public_exponent != 3 && public_exponent != 65537) |
| 308 return Status::ErrorGenerateKeyPublicExponent(); | 288 return Status::ErrorGenerateKeyPublicExponent(); |
| 309 | 289 |
| 310 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 290 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 311 | 291 |
| 312 // Generate an RSA key pair. | 292 // Generate an RSA key pair. |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 memcmp(algorithm.rsaHashedParams()->publicExponent().data(), | 542 memcmp(algorithm.rsaHashedParams()->publicExponent().data(), |
| 563 key->algorithm().rsaHashedParams()->publicExponent().data(), | 543 key->algorithm().rsaHashedParams()->publicExponent().data(), |
| 564 key->algorithm().rsaHashedParams()->publicExponent().size())) { | 544 key->algorithm().rsaHashedParams()->publicExponent().size())) { |
| 565 return Status::ErrorUnexpected(); | 545 return Status::ErrorUnexpected(); |
| 566 } | 546 } |
| 567 | 547 |
| 568 return Status::Success(); | 548 return Status::Success(); |
| 569 } | 549 } |
| 570 | 550 |
| 571 } // namespace webcrypto | 551 } // namespace webcrypto |
| OLD | NEW |