Index: content/child/webcrypto/webcrypto_util.cc |
diff --git a/content/child/webcrypto/webcrypto_util.cc b/content/child/webcrypto/webcrypto_util.cc |
index b94cbea2208b3100edbb36cfcc02b9ee1e835f6a..536be06c077cb1efb8e38ff653c6a5a73ed827da 100644 |
--- a/content/child/webcrypto/webcrypto_util.cc |
+++ b/content/child/webcrypto/webcrypto_util.cc |
@@ -16,6 +16,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(unsigned int) && data[i]) |
Ryan Sleevi
2014/07/21 21:36:45
sizeof(*result)
eroman
2014/07/21 21:52:21
Done.
|
+ return false; // Too large for a long. |
+ |
+ *result |= data[i] << 8 * reverse_i; |
+ } |
+ return true; |
+} |
+ |
+} // namespace |
+ |
const uint8_t* Uint8VectorStart(const std::vector<uint8_t>& data) { |
if (data.empty()) |
return NULL; |
@@ -260,6 +285,37 @@ Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages, |
return Status::Success(); |
} |
+Status GetRsaKeyGenGetParameters( |
+ const blink::WebCryptoRsaHashedKeyGenParams* params, |
+ unsigned int* public_exponent, |
+ unsigned int* modulus_length_bits) { |
+ *modulus_length_bits = params->modulusLengthBits(); |
+ |
+ if (!*modulus_length_bits) |
+ return Status::ErrorGenerateRsaZeroModulus(); |
+ |
+ // Limit key sizes to those supported by NSS: |
+ // * Multiple of 8 bytes |
+ // * 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 |