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" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 if (status.IsError()) | 97 if (status.IsError()) |
98 return status; | 98 return status; |
99 | 99 |
100 status = jwk.GetBigInteger("qi", &result->qi); | 100 status = jwk.GetBigInteger("qi", &result->qi); |
101 if (status.IsError()) | 101 if (status.IsError()) |
102 return status; | 102 return status; |
103 | 103 |
104 return Status::Success(); | 104 return Status::Success(); |
105 } | 105 } |
106 | 106 |
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 | 107 // Creates a blink::WebCryptoAlgorithm having the modulus length and public |
128 // exponent of |key|. | 108 // exponent of |key|. |
129 Status CreateRsaHashedKeyAlgorithm( | 109 Status CreateRsaHashedKeyAlgorithm( |
130 blink::WebCryptoAlgorithmId rsa_algorithm, | 110 blink::WebCryptoAlgorithmId rsa_algorithm, |
131 blink::WebCryptoAlgorithmId hash_algorithm, | 111 blink::WebCryptoAlgorithmId hash_algorithm, |
132 EVP_PKEY* key, | 112 EVP_PKEY* key, |
133 blink::WebCryptoKeyAlgorithm* key_algorithm) { | 113 blink::WebCryptoKeyAlgorithm* key_algorithm) { |
134 DCHECK_EQ(EVP_PKEY_RSA, EVP_PKEY_id(key)); | 114 DCHECK_EQ(EVP_PKEY_RSA, EVP_PKEY_id(key)); |
135 | 115 |
136 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(key)); | 116 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(key)); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 // | 271 // |
292 // These correspond with limitations at the time there was an NSS WebCrypto | 272 // These correspond with limitations at the time there was an NSS WebCrypto |
293 // implementation. However in practice the upper bound is also helpful | 273 // implementation. However in practice the upper bound is also helpful |
294 // because generating large RSA keys is very slow. | 274 // because generating large RSA keys is very slow. |
295 if (modulus_length_bits < 256 || modulus_length_bits > 16384 || | 275 if (modulus_length_bits < 256 || modulus_length_bits > 16384 || |
296 (modulus_length_bits % 8) != 0) { | 276 (modulus_length_bits % 8) != 0) { |
297 return Status::ErrorGenerateRsaUnsupportedModulus(); | 277 return Status::ErrorGenerateRsaUnsupportedModulus(); |
298 } | 278 } |
299 | 279 |
300 unsigned int public_exponent = 0; | 280 unsigned int public_exponent = 0; |
301 if (!BigIntegerToUint(params->publicExponent().data(), | 281 if (!params->publicExponentToUint32(&public_exponent)) { |
302 params->publicExponent().size(), &public_exponent)) { | |
303 return Status::ErrorGenerateKeyPublicExponent(); | 282 return Status::ErrorGenerateKeyPublicExponent(); |
304 } | 283 } |
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. |
(...skipping 249 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 |