| 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->publicExponentToUint(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 |