Chromium Code Reviews| 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 |