 Chromium Code Reviews
 Chromium Code Reviews Issue 178073007:
  [webcrypto] Update to use the KeyAlgorithm.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 178073007:
  [webcrypto] Update to use the KeyAlgorithm.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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" | 
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" | 
| 12 #include "base/strings/string_piece.h" | 12 #include "base/strings/string_piece.h" | 
| 13 #include "base/values.h" | 13 #include "base/values.h" | 
| 14 #include "content/renderer/webcrypto/crypto_data.h" | 14 #include "content/renderer/webcrypto/crypto_data.h" | 
| 15 #include "content/renderer/webcrypto/platform_crypto.h" | 15 #include "content/renderer/webcrypto/platform_crypto.h" | 
| 16 #include "content/renderer/webcrypto/shared_crypto.h" | 16 #include "content/renderer/webcrypto/shared_crypto.h" | 
| 17 #include "content/renderer/webcrypto/webcrypto_util.h" | 17 #include "content/renderer/webcrypto/webcrypto_util.h" | 
| 18 #include "third_party/WebKit/public/platform/WebCrypto.h" // TODO(eroman): | |
| 
Ryan Sleevi
2014/02/25 22:26:26
What's the TODO?
 
eroman
2014/02/25 23:26:47
Done.
The todo is for me to delete that line. Add
 | |
| 18 | 19 | 
| 19 namespace content { | 20 namespace content { | 
| 20 | 21 | 
| 21 namespace webcrypto { | 22 namespace webcrypto { | 
| 22 | 23 | 
| 23 namespace { | 24 namespace { | 
| 24 | 25 | 
| 25 typedef blink::WebCryptoAlgorithm (*AlgorithmCreationFunc)(); | 26 typedef blink::WebCryptoAlgorithm (*AlgorithmCreationFunc)(); | 
| 26 | 27 | 
| 27 class JwkAlgorithmInfo { | 28 class JwkAlgorithmInfo { | 
| 28 public: | 29 public: | 
| 29 JwkAlgorithmInfo() | 30 JwkAlgorithmInfo() | 
| 30 : creation_func_(NULL), | 31 : creation_func_(NULL), | 
| 31 required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) {} | 32 required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) {} | 
| 32 | 33 | 
| 33 explicit JwkAlgorithmInfo(AlgorithmCreationFunc algorithm_creation_func) | 34 explicit JwkAlgorithmInfo(AlgorithmCreationFunc algorithm_creation_func) | 
| 34 : creation_func_(algorithm_creation_func), | 35 : creation_func_(algorithm_creation_func), | 
| 35 required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) {} | 36 required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) {} | 
| 36 | 37 | 
| 37 JwkAlgorithmInfo(AlgorithmCreationFunc algorithm_creation_func, | 38 JwkAlgorithmInfo(AlgorithmCreationFunc algorithm_creation_func, | 
| 38 unsigned int required_key_length_bits) | 39 unsigned int required_key_length_bits) | 
| 39 : creation_func_(algorithm_creation_func), | 40 : creation_func_(algorithm_creation_func), | 
| 40 required_key_length_bytes_(required_key_length_bits / 8) { | 41 required_key_length_bytes_(required_key_length_bits / 8) { | 
| 41 DCHECK((required_key_length_bits % 8) == 0); | 42 DCHECK((required_key_length_bits % 8) == 0); | 
| 42 } | 43 } | 
| 43 | 44 | 
| 44 bool CreateAlgorithm(blink::WebCryptoAlgorithm* algorithm) const { | 45 bool CreateImportAlgorithm(blink::WebCryptoAlgorithm* algorithm) const { | 
| 45 *algorithm = creation_func_(); | 46 *algorithm = creation_func_(); | 
| 46 return !algorithm->isNull(); | 47 return !algorithm->isNull(); | 
| 47 } | 48 } | 
| 48 | 49 | 
| 49 bool IsInvalidKeyByteLength(size_t byte_length) const { | 50 bool IsInvalidKeyByteLength(size_t byte_length) const { | 
| 50 if (required_key_length_bytes_ == NO_KEY_SIZE_REQUIREMENT) | 51 if (required_key_length_bytes_ == NO_KEY_SIZE_REQUIREMENT) | 
| 51 return false; | 52 return false; | 
| 52 return required_key_length_bytes_ != byte_length; | 53 return required_key_length_bytes_ != byte_length; | 
| 53 } | 54 } | 
| 54 | 55 | 
| 55 private: | 56 private: | 
| 56 enum { NO_KEY_SIZE_REQUIREMENT = UINT_MAX }; | 57 enum { NO_KEY_SIZE_REQUIREMENT = UINT_MAX }; | 
| 57 | 58 | 
| 58 AlgorithmCreationFunc creation_func_; | 59 AlgorithmCreationFunc creation_func_; | 
| 59 | 60 | 
| 60 // The expected key size for the algorithm or NO_KEY_SIZE_REQUIREMENT. | 61 // The expected key size for the algorithm or NO_KEY_SIZE_REQUIREMENT. | 
| 61 unsigned int required_key_length_bytes_; | 62 unsigned int required_key_length_bytes_; | 
| 62 }; | 63 }; | 
| 63 | 64 | 
| 64 typedef std::map<std::string, JwkAlgorithmInfo> JwkAlgorithmInfoMap; | 65 typedef std::map<std::string, JwkAlgorithmInfo> JwkAlgorithmInfoMap; | 
| 65 | 66 | 
| 66 class JwkAlgorithmRegistry { | 67 class JwkAlgorithmRegistry { | 
| 67 public: | 68 public: | 
| 68 JwkAlgorithmRegistry() { | 69 JwkAlgorithmRegistry() { | 
| 69 // TODO(eroman): | 70 // TODO(eroman): | 
| 70 // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-20 | 71 // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-20 | 
| 71 // says HMAC with SHA-2 should have a key size at least as large as the | 72 // says HMAC with SHA-2 should have a key size at least as large as the | 
| 72 // hash output. | 73 // hash output. | 
| 73 alg_to_info_["HS256"] = | 74 alg_to_info_["HS256"] = | 
| 74 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacAlgorithmByHashId, | 75 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm, | 
| 75 blink::WebCryptoAlgorithmIdSha256>); | 76 blink::WebCryptoAlgorithmIdSha256>); | 
| 76 alg_to_info_["HS384"] = | 77 alg_to_info_["HS384"] = | 
| 77 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacAlgorithmByHashId, | 78 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm, | 
| 78 blink::WebCryptoAlgorithmIdSha384>); | 79 blink::WebCryptoAlgorithmIdSha384>); | 
| 79 alg_to_info_["HS512"] = | 80 alg_to_info_["HS512"] = | 
| 80 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacAlgorithmByHashId, | 81 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm, | 
| 81 blink::WebCryptoAlgorithmIdSha512>); | 82 blink::WebCryptoAlgorithmIdSha512>); | 
| 82 alg_to_info_["RS256"] = | 83 alg_to_info_["RS256"] = | 
| 83 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaAlgorithm, | 84 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm, | 
| 84 blink::WebCryptoAlgorithmIdSha256>); | 85 blink::WebCryptoAlgorithmIdSha256>); | 
| 85 alg_to_info_["RS384"] = | 86 alg_to_info_["RS384"] = | 
| 86 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaAlgorithm, | 87 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm, | 
| 87 blink::WebCryptoAlgorithmIdSha384>); | 88 blink::WebCryptoAlgorithmIdSha384>); | 
| 88 alg_to_info_["RS512"] = | 89 alg_to_info_["RS512"] = | 
| 89 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaAlgorithm, | 90 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm, | 
| 90 blink::WebCryptoAlgorithmIdSha512>); | 91 blink::WebCryptoAlgorithmIdSha512>); | 
| 91 alg_to_info_["RSA1_5"] = JwkAlgorithmInfo( | 92 alg_to_info_["RSA1_5"] = JwkAlgorithmInfo( | 
| 92 &BindAlgorithmId<CreateAlgorithm, | 93 &BindAlgorithmId<CreateAlgorithm, | 
| 93 blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5>); | 94 blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5>); | 
| 94 alg_to_info_["RSA-OAEP"] = | 95 alg_to_info_["RSA-OAEP"] = | 
| 95 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaOaepAlgorithm, | 96 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaOaepImportAlgorithm, | 
| 96 blink::WebCryptoAlgorithmIdSha1>); | 97 blink::WebCryptoAlgorithmIdSha1>); | 
| 97 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 128 yet | 98 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 128 yet | 
| 98 alg_to_info_["A128KW"] = | 99 alg_to_info_["A128KW"] = | 
| 99 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 128); | 100 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 128); | 
| 100 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 256 yet | 101 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 256 yet | 
| 101 alg_to_info_["A256KW"] = | 102 alg_to_info_["A256KW"] = | 
| 102 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 256); | 103 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 256); | 
| 103 alg_to_info_["A128GCM"] = JwkAlgorithmInfo( | 104 alg_to_info_["A128GCM"] = JwkAlgorithmInfo( | 
| 104 &BindAlgorithmId<CreateAlgorithm, blink::WebCryptoAlgorithmIdAesGcm>, | 105 &BindAlgorithmId<CreateAlgorithm, blink::WebCryptoAlgorithmIdAesGcm>, | 
| 105 128); | 106 128); | 
| (...skipping 28 matching lines...) Expand all Loading... | |
| 134 static blink::WebCryptoAlgorithm BindAlgorithmId() { | 135 static blink::WebCryptoAlgorithm BindAlgorithmId() { | 
| 135 return func(algorithm_id); | 136 return func(algorithm_id); | 
| 136 } | 137 } | 
| 137 | 138 | 
| 138 JwkAlgorithmInfoMap alg_to_info_; | 139 JwkAlgorithmInfoMap alg_to_info_; | 
| 139 }; | 140 }; | 
| 140 | 141 | 
| 141 base::LazyInstance<JwkAlgorithmRegistry> jwk_alg_registry = | 142 base::LazyInstance<JwkAlgorithmRegistry> jwk_alg_registry = | 
| 142 LAZY_INSTANCE_INITIALIZER; | 143 LAZY_INSTANCE_INITIALIZER; | 
| 143 | 144 | 
| 144 bool WebCryptoAlgorithmsConsistent(const blink::WebCryptoAlgorithm& alg1, | 145 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | 
| 145 const blink::WebCryptoAlgorithm& alg2) { | 146 bool ImportAlgorithmsConsistent(const blink::WebCryptoAlgorithm& alg1, | 
| 147 const blink::WebCryptoAlgorithm& alg2) { | |
| 146 DCHECK(!alg1.isNull()); | 148 DCHECK(!alg1.isNull()); | 
| 147 DCHECK(!alg2.isNull()); | 149 DCHECK(!alg2.isNull()); | 
| 148 if (alg1.id() != alg2.id()) | 150 if (alg1.id() != alg2.id()) | 
| 151 return false; | |
| 152 if (alg1.paramsType() != alg2.paramsType()) | |
| 153 return false; | |
| 154 switch (alg1.paramsType()) { | |
| 155 case blink::WebCryptoAlgorithmParamsTypeNone: | |
| 156 return true; | |
| 157 case blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams: | |
| 158 return ImportAlgorithmsConsistent(alg1.rsaHashedImportParams()->hash(), | |
| 159 alg2.rsaHashedImportParams()->hash()); | |
| 160 case blink::WebCryptoAlgorithmParamsTypeHmacImportParams: | |
| 161 return ImportAlgorithmsConsistent(alg1.hmacImportParams()->hash(), | |
| 162 alg2.hmacImportParams()->hash()); | |
| 163 default: | |
| 164 return false; | |
| 165 } | |
| 166 } | |
| 167 #else | |
| 168 bool ImportAlgorithmsConsistent(const blink::WebCryptoAlgorithm& alg1, | |
| 169 const blink::WebCryptoAlgorithm& alg2) { | |
| 170 DCHECK(!alg1.isNull()); | |
| 171 DCHECK(!alg2.isNull()); | |
| 172 if (alg1.id() != alg2.id()) | |
| 149 return false; | 173 return false; | 
| 150 switch (alg1.id()) { | 174 switch (alg1.id()) { | 
| 151 case blink::WebCryptoAlgorithmIdHmac: | 175 case blink::WebCryptoAlgorithmIdHmac: | 
| 152 case blink::WebCryptoAlgorithmIdRsaOaep: | 176 case blink::WebCryptoAlgorithmIdRsaOaep: | 
| 153 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 177 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 
| 154 if (WebCryptoAlgorithmsConsistent(GetInnerHashAlgorithm(alg1), | 178 if (ImportAlgorithmsConsistent(GetInnerHashAlgorithm(alg1), | 
| 155 GetInnerHashAlgorithm(alg2))) { | 179 GetInnerHashAlgorithm(alg2))) { | 
| 156 return true; | 180 return true; | 
| 157 } | 181 } | 
| 158 break; | 182 break; | 
| 159 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 183 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 
| 160 case blink::WebCryptoAlgorithmIdSha1: | 184 case blink::WebCryptoAlgorithmIdSha1: | 
| 161 case blink::WebCryptoAlgorithmIdSha224: | 185 case blink::WebCryptoAlgorithmIdSha224: | 
| 162 case blink::WebCryptoAlgorithmIdSha256: | 186 case blink::WebCryptoAlgorithmIdSha256: | 
| 163 case blink::WebCryptoAlgorithmIdSha384: | 187 case blink::WebCryptoAlgorithmIdSha384: | 
| 164 case blink::WebCryptoAlgorithmIdSha512: | 188 case blink::WebCryptoAlgorithmIdSha512: | 
| 165 case blink::WebCryptoAlgorithmIdAesCbc: | 189 case blink::WebCryptoAlgorithmIdAesCbc: | 
| 166 case blink::WebCryptoAlgorithmIdAesGcm: | 190 case blink::WebCryptoAlgorithmIdAesGcm: | 
| 167 case blink::WebCryptoAlgorithmIdAesCtr: | 191 case blink::WebCryptoAlgorithmIdAesCtr: | 
| 168 return true; | 192 return true; | 
| 169 default: | 193 default: | 
| 170 NOTREACHED(); // Not a supported algorithm. | 194 NOTREACHED(); // Not a supported algorithm. | 
| 171 break; | 195 break; | 
| 172 } | 196 } | 
| 173 return false; | 197 return false; | 
| 174 } | 198 } | 
| 199 #endif | |
| 175 | 200 | 
| 176 // Extracts the required string property with key |path| from |dict| and saves | 201 // Extracts the required string property with key |path| from |dict| and saves | 
| 177 // the result to |*result|. If the property does not exist or is not a string, | 202 // the result to |*result|. If the property does not exist or is not a string, | 
| 178 // returns an error. | 203 // returns an error. | 
| 179 Status GetJwkString(base::DictionaryValue* dict, | 204 Status GetJwkString(base::DictionaryValue* dict, | 
| 180 const std::string& path, | 205 const std::string& path, | 
| 181 std::string* result) { | 206 std::string* result) { | 
| 182 base::Value* value = NULL; | 207 base::Value* value = NULL; | 
| 183 if (!dict->Get(path, &value)) | 208 if (!dict->Get(path, &value)) | 
| 184 return Status::ErrorJwkPropertyMissing(path); | 209 return Status::ErrorJwkPropertyMissing(path); | 
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 441 | 466 | 
| 442 if (has_jwk_alg) { | 467 if (has_jwk_alg) { | 
| 443 // JWK alg present | 468 // JWK alg present | 
| 444 | 469 | 
| 445 // TODO(padolph): Validate alg vs kty. For example kty="RSA" implies alg can | 470 // TODO(padolph): Validate alg vs kty. For example kty="RSA" implies alg can | 
| 446 // only be from the RSA family. | 471 // only be from the RSA family. | 
| 447 | 472 | 
| 448 blink::WebCryptoAlgorithm jwk_algorithm = | 473 blink::WebCryptoAlgorithm jwk_algorithm = | 
| 449 blink::WebCryptoAlgorithm::createNull(); | 474 blink::WebCryptoAlgorithm::createNull(); | 
| 450 algorithm_info = jwk_alg_registry.Get().GetAlgorithmInfo(jwk_alg_value); | 475 algorithm_info = jwk_alg_registry.Get().GetAlgorithmInfo(jwk_alg_value); | 
| 451 if (!algorithm_info || !algorithm_info->CreateAlgorithm(&jwk_algorithm)) | 476 if (!algorithm_info || | 
| 477 !algorithm_info->CreateImportAlgorithm(&jwk_algorithm)) | |
| 452 return Status::ErrorJwkUnrecognizedAlgorithm(); // case 1 | 478 return Status::ErrorJwkUnrecognizedAlgorithm(); // case 1 | 
| 453 | 479 | 
| 454 // JWK alg valid | 480 // JWK alg valid | 
| 455 if (algorithm_or_null.isNull()) { | 481 if (algorithm_or_null.isNull()) { | 
| 456 // input algorithm not specified | 482 // input algorithm not specified | 
| 457 algorithm = jwk_algorithm; // case 2 | 483 algorithm = jwk_algorithm; // case 2 | 
| 458 } else { | 484 } else { | 
| 459 // input algorithm specified | 485 // input algorithm specified | 
| 460 if (!WebCryptoAlgorithmsConsistent(jwk_algorithm, algorithm_or_null)) | 486 if (!ImportAlgorithmsConsistent(jwk_algorithm, algorithm_or_null)) | 
| 461 return Status::ErrorJwkAlgorithmInconsistent(); // case 3 | 487 return Status::ErrorJwkAlgorithmInconsistent(); // case 3 | 
| 462 algorithm = algorithm_or_null; // case 4 | 488 algorithm = algorithm_or_null; // case 4 | 
| 463 } | 489 } | 
| 464 } else { | 490 } else { | 
| 465 // JWK alg missing | 491 // JWK alg missing | 
| 466 if (algorithm_or_null.isNull()) | 492 if (algorithm_or_null.isNull()) | 
| 467 return Status::ErrorJwkAlgorithmMissing(); // case 5 | 493 return Status::ErrorJwkAlgorithmMissing(); // case 5 | 
| 468 algorithm = algorithm_or_null; // case 6 | 494 algorithm = algorithm_or_null; // case 6 | 
| 469 } | 495 } | 
| 470 DCHECK(!algorithm.isNull()); | 496 DCHECK(!algorithm.isNull()); | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 } else { | 580 } else { | 
| 555 return Status::ErrorJwkUnrecognizedKty(); | 581 return Status::ErrorJwkUnrecognizedKty(); | 
| 556 } | 582 } | 
| 557 | 583 | 
| 558 return Status::Success(); | 584 return Status::Success(); | 
| 559 } | 585 } | 
| 560 | 586 | 
| 561 } // namespace webcrypto | 587 } // namespace webcrypto | 
| 562 | 588 | 
| 563 } // namespace content | 589 } // namespace content | 
| OLD | NEW |