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 "content/child/webcrypto/webcrypto_util.h" | 5 #include "content/child/webcrypto/webcrypto_util.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
11 #include "content/child/webcrypto/status.h" | 11 #include "content/child/webcrypto/status.h" |
12 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 12 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
13 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 13 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
14 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 14 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
15 | 15 |
16 namespace content { | 16 namespace content { |
17 | 17 |
18 namespace webcrypto { | 18 namespace webcrypto { |
19 | 19 |
| 20 namespace { |
| 21 |
| 22 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, |
| 23 // to unsigned int. |
| 24 bool BigIntegerToUint(const uint8_t* data, |
| 25 unsigned int data_size, |
| 26 unsigned int* result) { |
| 27 // TODO(eroman): Fix handling of empty biginteger. http://crbug.com/373552 |
| 28 if (data_size == 0) |
| 29 return false; |
| 30 |
| 31 *result = 0; |
| 32 for (size_t i = 0; i < data_size; ++i) { |
| 33 size_t reverse_i = data_size - i - 1; |
| 34 |
| 35 if (reverse_i >= sizeof(*result) && data[i]) |
| 36 return false; // Too large for a uint. |
| 37 |
| 38 *result |= data[i] << 8 * reverse_i; |
| 39 } |
| 40 return true; |
| 41 } |
| 42 |
| 43 } // namespace |
| 44 |
20 // This function decodes unpadded 'base64url' encoded data, as described in | 45 // This function decodes unpadded 'base64url' encoded data, as described in |
21 // RFC4648 (http://www.ietf.org/rfc/rfc4648.txt) Section 5. To do this, first | 46 // RFC4648 (http://www.ietf.org/rfc/rfc4648.txt) Section 5. To do this, first |
22 // change the incoming data to 'base64' encoding by applying the appropriate | 47 // change the incoming data to 'base64' encoding by applying the appropriate |
23 // transformation including adding padding if required, and then call a base64 | 48 // transformation including adding padding if required, and then call a base64 |
24 // decoder. | 49 // decoder. |
25 bool Base64DecodeUrlSafe(const std::string& input, std::string* output) { | 50 bool Base64DecodeUrlSafe(const std::string& input, std::string* output) { |
26 std::string base64EncodedText(input); | 51 std::string base64EncodedText(input); |
27 std::replace(base64EncodedText.begin(), base64EncodedText.end(), '-', '+'); | 52 std::replace(base64EncodedText.begin(), base64EncodedText.end(), '-', '+'); |
28 std::replace(base64EncodedText.begin(), base64EncodedText.end(), '_', '/'); | 53 std::replace(base64EncodedText.begin(), base64EncodedText.end(), '_', '/'); |
29 base64EncodedText.append((4 - base64EncodedText.size() % 4) % 4, '='); | 54 base64EncodedText.append((4 - base64EncodedText.size() % 4) % 4, '='); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 return Status::ErrorImportAesKeyLength(); | 267 return Status::ErrorImportAesKeyLength(); |
243 } | 268 } |
244 | 269 |
245 Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages, | 270 Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages, |
246 blink::WebCryptoKeyUsageMask actual_usages) { | 271 blink::WebCryptoKeyUsageMask actual_usages) { |
247 if (!ContainsKeyUsages(all_possible_usages, actual_usages)) | 272 if (!ContainsKeyUsages(all_possible_usages, actual_usages)) |
248 return Status::ErrorCreateKeyBadUsages(); | 273 return Status::ErrorCreateKeyBadUsages(); |
249 return Status::Success(); | 274 return Status::Success(); |
250 } | 275 } |
251 | 276 |
| 277 Status GetRsaKeyGenParameters( |
| 278 const blink::WebCryptoRsaHashedKeyGenParams* params, |
| 279 unsigned int* public_exponent, |
| 280 unsigned int* modulus_length_bits) { |
| 281 *modulus_length_bits = params->modulusLengthBits(); |
| 282 |
| 283 // Limit key sizes to those supported by NSS: |
| 284 // * Multiple of 8 bits |
| 285 // * 256 bits to 16K bits |
| 286 if (*modulus_length_bits < 256 || *modulus_length_bits > 16384 || |
| 287 (*modulus_length_bits % 8) != 0) { |
| 288 return Status::ErrorGenerateRsaUnsupportedModulus(); |
| 289 } |
| 290 |
| 291 if (!BigIntegerToUint(params->publicExponent().data(), |
| 292 params->publicExponent().size(), |
| 293 public_exponent)) { |
| 294 return Status::ErrorGenerateKeyPublicExponent(); |
| 295 } |
| 296 |
| 297 // OpenSSL hangs when given bad public exponents, whereas NSS simply fails. To |
| 298 // avoid feeding OpenSSL data that will hang use a whitelist. |
| 299 if (*public_exponent != 3 && *public_exponent != 65537) |
| 300 return Status::ErrorGenerateKeyPublicExponent(); |
| 301 |
| 302 return Status::Success(); |
| 303 } |
| 304 |
252 } // namespace webcrypto | 305 } // namespace webcrypto |
253 | 306 |
254 } // namespace content | 307 } // namespace content |
OLD | NEW |