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)) |
302 params->publicExponent().size(), &public_exponent)) { | |
303 return Status::ErrorGenerateKeyPublicExponent(); | 283 return Status::ErrorGenerateKeyPublicExponent(); |
304 } | |
305 | 284 |
306 // OpenSSL hangs when given bad public exponents. Use a whitelist. | 285 // OpenSSL hangs when given bad public exponents. Use a whitelist. |
307 if (public_exponent != 3 && public_exponent != 65537) | 286 if (public_exponent != 3 && public_exponent != 65537) |
308 return Status::ErrorGenerateKeyPublicExponent(); | 287 return Status::ErrorGenerateKeyPublicExponent(); |
309 | 288 |
310 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 289 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
311 | 290 |
312 // Generate an RSA key pair. | 291 // Generate an RSA key pair. |
313 crypto::ScopedRSA rsa_private_key(RSA_new()); | 292 crypto::ScopedRSA rsa_private_key(RSA_new()); |
314 crypto::ScopedBIGNUM bn(BN_new()); | 293 crypto::ScopedBIGNUM bn(BN_new()); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 memcmp(algorithm.rsaHashedParams()->publicExponent().data(), | 541 memcmp(algorithm.rsaHashedParams()->publicExponent().data(), |
563 key->algorithm().rsaHashedParams()->publicExponent().data(), | 542 key->algorithm().rsaHashedParams()->publicExponent().data(), |
564 key->algorithm().rsaHashedParams()->publicExponent().size())) { | 543 key->algorithm().rsaHashedParams()->publicExponent().size())) { |
565 return Status::ErrorUnexpected(); | 544 return Status::ErrorUnexpected(); |
566 } | 545 } |
567 | 546 |
568 return Status::Success(); | 547 return Status::Success(); |
569 } | 548 } |
570 | 549 |
571 } // namespace webcrypto | 550 } // namespace webcrypto |
OLD | NEW |