Index: content/child/webcrypto/webcrypto_util.cc |
diff --git a/content/child/webcrypto/webcrypto_util.cc b/content/child/webcrypto/webcrypto_util.cc |
index 929b491c4481be4667fce86c11fa5ec2c586a663..8c28fda36c6c2b5cef9edd5d34a5421e03543b5a 100644 |
--- a/content/child/webcrypto/webcrypto_util.cc |
+++ b/content/child/webcrypto/webcrypto_util.cc |
@@ -17,6 +17,31 @@ namespace content { |
namespace webcrypto { |
+namespace { |
+ |
+// Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, |
+// to unsigned int. |
+bool BigIntegerToUint(const uint8_t* data, |
+ unsigned int data_size, |
+ unsigned int* result) { |
+ // TODO(eroman): Fix handling of empty biginteger. http://crbug.com/373552 |
+ if (data_size == 0) |
+ return false; |
+ |
+ *result = 0; |
+ for (size_t i = 0; i < data_size; ++i) { |
+ size_t reverse_i = data_size - i - 1; |
+ |
+ if (reverse_i >= sizeof(*result) && data[i]) |
+ return false; // Too large for a uint. |
+ |
+ *result |= data[i] << 8 * reverse_i; |
+ } |
+ return true; |
+} |
+ |
+} // namespace |
+ |
// This function decodes unpadded 'base64url' encoded data, as described in |
// RFC4648 (http://www.ietf.org/rfc/rfc4648.txt) Section 5. To do this, first |
// change the incoming data to 'base64' encoding by applying the appropriate |
@@ -249,6 +274,34 @@ Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages, |
return Status::Success(); |
} |
+Status GetRsaKeyGenParameters( |
+ const blink::WebCryptoRsaHashedKeyGenParams* params, |
+ unsigned int* public_exponent, |
+ unsigned int* modulus_length_bits) { |
+ *modulus_length_bits = params->modulusLengthBits(); |
+ |
+ // Limit key sizes to those supported by NSS: |
+ // * Multiple of 8 bits |
+ // * 256 bits to 16K bits |
+ if (*modulus_length_bits < 256 || *modulus_length_bits > 16384 || |
+ (*modulus_length_bits % 8) != 0) { |
+ return Status::ErrorGenerateRsaUnsupportedModulus(); |
+ } |
+ |
+ if (!BigIntegerToUint(params->publicExponent().data(), |
+ params->publicExponent().size(), |
+ public_exponent)) { |
+ return Status::ErrorGenerateKeyPublicExponent(); |
+ } |
+ |
+ // OpenSSL hangs when given bad public exponents, whereas NSS simply fails. To |
+ // avoid feeding OpenSSL data that will hang use a whitelist. |
+ if (*public_exponent != 3 && *public_exponent != 65537) |
+ return Status::ErrorGenerateKeyPublicExponent(); |
+ |
+ return Status::Success(); |
+} |
+ |
} // namespace webcrypto |
} // namespace content |