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 <algorithm> | 5 #include <algorithm> |
6 #include <functional> | 6 #include <functional> |
7 #include <map> | 7 #include <map> |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 if (!value->GetAsBoolean(result)) | 230 if (!value->GetAsBoolean(result)) |
231 return Status::ErrorJwkPropertyWrongType(path, "boolean"); | 231 return Status::ErrorJwkPropertyWrongType(path, "boolean"); |
232 | 232 |
233 *property_exists = true; | 233 *property_exists = true; |
234 return Status::Success(); | 234 return Status::Success(); |
235 } | 235 } |
236 | 236 |
237 } // namespace | 237 } // namespace |
238 | 238 |
239 Status ImportKeyJwk(const CryptoData& key_data, | 239 Status ImportKeyJwk(const CryptoData& key_data, |
240 const blink::WebCryptoAlgorithm& algorithm_or_null, | 240 const blink::WebCryptoAlgorithm& algorithm, |
241 bool extractable, | 241 bool extractable, |
242 blink::WebCryptoKeyUsageMask usage_mask, | 242 blink::WebCryptoKeyUsageMask usage_mask, |
243 blink::WebCryptoKey* key) { | 243 blink::WebCryptoKey* key) { |
244 | 244 |
245 // The goal of this method is to extract key material and meta data from the | 245 // The goal of this method is to extract key material and meta data from the |
246 // incoming JWK, combine them with the input parameters, and ultimately import | 246 // incoming JWK, combine them with the input parameters, and ultimately import |
247 // a Web Crypto Key. | 247 // a Web Crypto Key. |
248 // | 248 // |
249 // JSON Web Key Format (JWK) | 249 // JSON Web Key Format (JWK) |
250 // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-16 | 250 // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-16 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 // | "n" | Contains the modulus value for the RSA public key. It is | | 344 // | "n" | Contains the modulus value for the RSA public key. It is | |
345 // | | represented as the base64url encoding of the value's | | 345 // | | represented as the base64url encoding of the value's | |
346 // | | unsigned big endian representation as an octet sequence. | | 346 // | | unsigned big endian representation as an octet sequence. | |
347 // +-------+--------------------------------------------------------------+ | 347 // +-------+--------------------------------------------------------------+ |
348 // | "e" | Contains the exponent value for the RSA public key. It is | | 348 // | "e" | Contains the exponent value for the RSA public key. It is | |
349 // | | represented as the base64url encoding of the value's | | 349 // | | represented as the base64url encoding of the value's | |
350 // | | unsigned big endian representation as an octet sequence. | | 350 // | | unsigned big endian representation as an octet sequence. | |
351 // +-------+--------------------------------------------------------------+ | 351 // +-------+--------------------------------------------------------------+ |
352 // | 352 // |
353 // Consistency and conflict resolution | 353 // Consistency and conflict resolution |
354 // The 'algorithm_or_null', 'extractable', and 'usage_mask' input parameters | 354 // The 'algorithm', 'extractable', and 'usage_mask' input parameters |
355 // may be different than the corresponding values inside the JWK. The Web | 355 // may be different than the corresponding values inside the JWK. The Web |
356 // Crypto spec says that if a JWK value is present but is inconsistent with | 356 // Crypto spec says that if a JWK value is present but is inconsistent with |
357 // the input value, it is an error and the operation must fail. If no | 357 // the input value, it is an error and the operation must fail. If no |
358 // inconsistency is found, the input and JWK values are combined as follows: | 358 // inconsistency is found then the input parameters are used. |
359 // | 359 // |
360 // algorithm | 360 // algorithm |
361 // If an algorithm is provided by both the input parameter and the JWK, | 361 // If the JWK algorithm is provided, it must match the web crypto input |
362 // consistency between the two is based only on algorithm ID's (including an | 362 // algorithm (both the algorithm ID and inner hash if applicable). |
363 // inner hash algorithm if present). In this case if the consistency | |
364 // check is passed, the input algorithm is used. If only one of either the | |
365 // input algorithm and JWK alg is provided, it is used as the final | |
366 // algorithm. | |
367 // | 363 // |
368 // extractable | 364 // extractable |
369 // If the JWK extractable is true but the input parameter is false, make the | 365 // If the JWK extractable is true but the input parameter is false, make the |
370 // Web Crypto Key non-extractable. Conversely, if the JWK extractable is | 366 // Web Crypto Key non-extractable. Conversely, if the JWK extractable is |
371 // false but the input parameter is true, it is an inconsistency. If both | 367 // false but the input parameter is true, it is an inconsistency. If both |
372 // are true or both are false, use that value. | 368 // are true or both are false, use that value. |
373 // | 369 // |
374 // usage_mask | 370 // usage_mask |
375 // The input usage_mask must be a strict subset of the interpreted JWK use | 371 // The input usage_mask must be a strict subset of the interpreted JWK use |
376 // value, else it is judged inconsistent. In all cases the input usage_mask | 372 // value, else it is judged inconsistent. In all cases the input usage_mask |
(...skipping 26 matching lines...) Expand all Loading... | |
403 status = GetOptionalJwkBool(dict_value, | 399 status = GetOptionalJwkBool(dict_value, |
404 "extractable", | 400 "extractable", |
405 &jwk_extractable_value, | 401 &jwk_extractable_value, |
406 &has_jwk_extractable); | 402 &has_jwk_extractable); |
407 if (status.IsError()) | 403 if (status.IsError()) |
408 return status; | 404 return status; |
409 if (has_jwk_extractable && !jwk_extractable_value && extractable) | 405 if (has_jwk_extractable && !jwk_extractable_value && extractable) |
410 return Status::ErrorJwkExtractableInconsistent(); | 406 return Status::ErrorJwkExtractableInconsistent(); |
411 } | 407 } |
412 | 408 |
413 // JWK "alg" (optional) --> algorithm parameter | 409 // JWK "alg" --> algorithm parameter |
Ryan Sleevi
2014/03/14 21:31:50
JWK "alg" remains optional
So you still have seve
eroman
2014/03/18 01:25:29
Done.
| |
414 // Note: input algorithm is also optional, so we have six cases to handle. | |
415 // 1. JWK alg present but unrecognized: error | |
416 // 2. JWK alg valid AND input algorithm isNull: use JWK value | |
417 // 3. JWK alg valid AND input algorithm specified, but JWK value | |
418 // inconsistent with input: error | |
419 // 4. JWK alg valid AND input algorithm specified, both consistent: use | |
420 // input value (because it has potentially more details) | |
421 // 5. JWK alg missing AND input algorithm isNull: error | |
422 // 6. JWK alg missing AND input algorithm specified: use input value | |
423 blink::WebCryptoAlgorithm algorithm = blink::WebCryptoAlgorithm::createNull(); | |
424 const JwkAlgorithmInfo* algorithm_info = NULL; | 410 const JwkAlgorithmInfo* algorithm_info = NULL; |
425 std::string jwk_alg_value; | 411 std::string jwk_alg_value; |
426 bool has_jwk_alg; | 412 bool has_jwk_alg; |
427 status = | 413 status = |
428 GetOptionalJwkString(dict_value, "alg", &jwk_alg_value, &has_jwk_alg); | 414 GetOptionalJwkString(dict_value, "alg", &jwk_alg_value, &has_jwk_alg); |
429 if (status.IsError()) | 415 if (status.IsError()) |
430 return status; | 416 return status; |
431 | 417 |
432 if (has_jwk_alg) { | 418 if (has_jwk_alg) { |
433 // JWK alg present | 419 // JWK alg present |
434 | 420 |
435 // TODO(padolph): Validate alg vs kty. For example kty="RSA" implies alg can | 421 // TODO(padolph): Validate alg vs kty. For example kty="RSA" implies alg can |
436 // only be from the RSA family. | 422 // only be from the RSA family. |
437 | 423 |
438 blink::WebCryptoAlgorithm jwk_algorithm = | 424 blink::WebCryptoAlgorithm jwk_algorithm = |
439 blink::WebCryptoAlgorithm::createNull(); | 425 blink::WebCryptoAlgorithm::createNull(); |
440 algorithm_info = jwk_alg_registry.Get().GetAlgorithmInfo(jwk_alg_value); | 426 algorithm_info = jwk_alg_registry.Get().GetAlgorithmInfo(jwk_alg_value); |
441 if (!algorithm_info || | 427 if (!algorithm_info || |
442 !algorithm_info->CreateImportAlgorithm(&jwk_algorithm)) | 428 !algorithm_info->CreateImportAlgorithm(&jwk_algorithm)) |
443 return Status::ErrorJwkUnrecognizedAlgorithm(); // case 1 | 429 return Status::ErrorJwkUnrecognizedAlgorithm(); |
444 | 430 |
445 // JWK alg valid | 431 // input algorithm specified |
Ryan Sleevi
2014/03/14 21:31:50
unnecessary comment?
eroman
2014/03/18 01:25:29
Done.
| |
446 if (algorithm_or_null.isNull()) { | 432 if (!ImportAlgorithmsConsistent(jwk_algorithm, algorithm)) |
447 // input algorithm not specified | 433 return Status::ErrorJwkAlgorithmInconsistent(); |
448 algorithm = jwk_algorithm; // case 2 | |
449 } else { | |
450 // input algorithm specified | |
451 if (!ImportAlgorithmsConsistent(jwk_algorithm, algorithm_or_null)) | |
452 return Status::ErrorJwkAlgorithmInconsistent(); // case 3 | |
453 algorithm = algorithm_or_null; // case 4 | |
454 } | |
455 } else { | |
456 // JWK alg missing | |
457 if (algorithm_or_null.isNull()) | |
458 return Status::ErrorJwkAlgorithmMissing(); // case 5 | |
459 algorithm = algorithm_or_null; // case 6 | |
460 } | 434 } |
461 DCHECK(!algorithm.isNull()); | 435 DCHECK(!algorithm.isNull()); |
462 | 436 |
463 // JWK "use" (optional) --> usage_mask parameter | 437 // JWK "use" (optional) --> usage_mask parameter |
464 std::string jwk_use_value; | 438 std::string jwk_use_value; |
465 bool has_jwk_use; | 439 bool has_jwk_use; |
466 status = | 440 status = |
467 GetOptionalJwkString(dict_value, "use", &jwk_use_value, &has_jwk_use); | 441 GetOptionalJwkString(dict_value, "use", &jwk_use_value, &has_jwk_use); |
468 if (status.IsError()) | 442 if (status.IsError()) |
469 return status; | 443 return status; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 } else { | 519 } else { |
546 return Status::ErrorJwkUnrecognizedKty(); | 520 return Status::ErrorJwkUnrecognizedKty(); |
547 } | 521 } |
548 | 522 |
549 return Status::Success(); | 523 return Status::Success(); |
550 } | 524 } |
551 | 525 |
552 } // namespace webcrypto | 526 } // namespace webcrypto |
553 | 527 |
554 } // namespace content | 528 } // namespace content |
OLD | NEW |