| 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 10 matching lines...) Expand all  Loading... | 
| 21 namespace webcrypto { | 21 namespace webcrypto { | 
| 22 | 22 | 
| 23 namespace { | 23 namespace { | 
| 24 | 24 | 
| 25 typedef blink::WebCryptoAlgorithm (*AlgorithmCreationFunc)(); | 25 typedef blink::WebCryptoAlgorithm (*AlgorithmCreationFunc)(); | 
| 26 | 26 | 
| 27 class JwkAlgorithmInfo { | 27 class JwkAlgorithmInfo { | 
| 28  public: | 28  public: | 
| 29   JwkAlgorithmInfo() | 29   JwkAlgorithmInfo() | 
| 30       : creation_func_(NULL), | 30       : creation_func_(NULL), | 
| 31         required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) { | 31         required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) {} | 
| 32 |  | 
| 33   } |  | 
| 34 | 32 | 
| 35   explicit JwkAlgorithmInfo(AlgorithmCreationFunc algorithm_creation_func) | 33   explicit JwkAlgorithmInfo(AlgorithmCreationFunc algorithm_creation_func) | 
| 36       : creation_func_(algorithm_creation_func), | 34       : creation_func_(algorithm_creation_func), | 
| 37         required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) { | 35         required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) {} | 
| 38   } |  | 
| 39 | 36 | 
| 40   JwkAlgorithmInfo(AlgorithmCreationFunc algorithm_creation_func, | 37   JwkAlgorithmInfo(AlgorithmCreationFunc algorithm_creation_func, | 
| 41                    unsigned int required_key_length_bits) | 38                    unsigned int required_key_length_bits) | 
| 42       : creation_func_(algorithm_creation_func), | 39       : creation_func_(algorithm_creation_func), | 
| 43         required_key_length_bytes_(required_key_length_bits / 8) { | 40         required_key_length_bytes_(required_key_length_bits / 8) { | 
| 44     DCHECK((required_key_length_bits % 8) == 0); | 41     DCHECK((required_key_length_bits % 8) == 0); | 
| 45   } | 42   } | 
| 46 | 43 | 
| 47   bool CreateAlgorithm(blink::WebCryptoAlgorithm* algorithm) const { | 44   bool CreateAlgorithm(blink::WebCryptoAlgorithm* algorithm) const { | 
| 48     *algorithm = creation_func_(); | 45     *algorithm = creation_func_(); | 
| 49     return !algorithm->isNull(); | 46     return !algorithm->isNull(); | 
| 50   } | 47   } | 
| 51 | 48 | 
| 52   bool IsInvalidKeyByteLength(size_t byte_length) const { | 49   bool IsInvalidKeyByteLength(size_t byte_length) const { | 
| 53     if (required_key_length_bytes_ == NO_KEY_SIZE_REQUIREMENT) | 50     if (required_key_length_bytes_ == NO_KEY_SIZE_REQUIREMENT) | 
| 54       return false; | 51       return false; | 
| 55     return required_key_length_bytes_  != byte_length; | 52     return required_key_length_bytes_ != byte_length; | 
| 56   } | 53   } | 
| 57 | 54 | 
| 58  private: | 55  private: | 
| 59   enum { NO_KEY_SIZE_REQUIREMENT = UINT_MAX }; | 56   enum { NO_KEY_SIZE_REQUIREMENT = UINT_MAX }; | 
| 60 | 57 | 
| 61   AlgorithmCreationFunc creation_func_; | 58   AlgorithmCreationFunc creation_func_; | 
| 62 | 59 | 
| 63   // The expected key size for the algorithm or NO_KEY_SIZE_REQUIREMENT. | 60   // The expected key size for the algorithm or NO_KEY_SIZE_REQUIREMENT. | 
| 64   unsigned int required_key_length_bytes_; | 61   unsigned int required_key_length_bytes_; | 
| 65 |  | 
| 66 }; | 62 }; | 
| 67 | 63 | 
| 68 typedef std::map<std::string, JwkAlgorithmInfo> JwkAlgorithmInfoMap; | 64 typedef std::map<std::string, JwkAlgorithmInfo> JwkAlgorithmInfoMap; | 
| 69 | 65 | 
| 70 class JwkAlgorithmRegistry { | 66 class JwkAlgorithmRegistry { | 
| 71  public: | 67  public: | 
| 72   JwkAlgorithmRegistry() { | 68   JwkAlgorithmRegistry() { | 
| 73     // TODO(eroman): | 69     // TODO(eroman): | 
| 74     // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-20 | 70     // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-20 | 
| 75     // says HMAC with SHA-2 should have a key size at least as large as the | 71     // says HMAC with SHA-2 should have a key size at least as large as the | 
| 76     // hash output. | 72     // hash output. | 
| 77     alg_to_info_["HS256"] = JwkAlgorithmInfo( | 73     alg_to_info_["HS256"] = | 
| 78         &BindAlgorithmId<CreateHmacAlgorithmByHashId, | 74         JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacAlgorithmByHashId, | 
| 79                         blink::WebCryptoAlgorithmIdSha256>); | 75                                           blink::WebCryptoAlgorithmIdSha256>); | 
| 80     alg_to_info_["HS384"] = JwkAlgorithmInfo( | 76     alg_to_info_["HS384"] = | 
| 81         &BindAlgorithmId<CreateHmacAlgorithmByHashId, | 77         JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacAlgorithmByHashId, | 
| 82                         blink::WebCryptoAlgorithmIdSha384>); | 78                                           blink::WebCryptoAlgorithmIdSha384>); | 
| 83     alg_to_info_["HS512"] = JwkAlgorithmInfo( | 79     alg_to_info_["HS512"] = | 
| 84         &BindAlgorithmId<CreateHmacAlgorithmByHashId, | 80         JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacAlgorithmByHashId, | 
| 85                          blink::WebCryptoAlgorithmIdSha512>); | 81                                           blink::WebCryptoAlgorithmIdSha512>); | 
| 86     alg_to_info_["RS256"] = JwkAlgorithmInfo( | 82     alg_to_info_["RS256"] = | 
| 87         &BindAlgorithmId<CreateRsaSsaAlgorithm, | 83         JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaAlgorithm, | 
| 88                          blink::WebCryptoAlgorithmIdSha256>); | 84                                           blink::WebCryptoAlgorithmIdSha256>); | 
| 89     alg_to_info_["RS384"] = JwkAlgorithmInfo( | 85     alg_to_info_["RS384"] = | 
| 90         &BindAlgorithmId<CreateRsaSsaAlgorithm, | 86         JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaAlgorithm, | 
| 91                          blink::WebCryptoAlgorithmIdSha384>); | 87                                           blink::WebCryptoAlgorithmIdSha384>); | 
| 92     alg_to_info_["RS512"] = JwkAlgorithmInfo( | 88     alg_to_info_["RS512"] = | 
| 93         &BindAlgorithmId<CreateRsaSsaAlgorithm, | 89         JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaAlgorithm, | 
| 94                          blink::WebCryptoAlgorithmIdSha512>); | 90                                           blink::WebCryptoAlgorithmIdSha512>); | 
| 95     alg_to_info_["RSA1_5"] = JwkAlgorithmInfo( | 91     alg_to_info_["RSA1_5"] = JwkAlgorithmInfo( | 
| 96         &BindAlgorithmId<CreateAlgorithm, | 92         &BindAlgorithmId<CreateAlgorithm, | 
| 97                          blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5>); | 93                          blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5>); | 
| 98     alg_to_info_["RSA-OAEP"] = JwkAlgorithmInfo( | 94     alg_to_info_["RSA-OAEP"] = | 
| 99         &BindAlgorithmId<CreateRsaOaepAlgorithm, | 95         JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaOaepAlgorithm, | 
| 100                          blink::WebCryptoAlgorithmIdSha1>); | 96                                           blink::WebCryptoAlgorithmIdSha1>); | 
| 101     // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 128 yet | 97     // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 128 yet | 
| 102     alg_to_info_["A128KW"] = | 98     alg_to_info_["A128KW"] = | 
| 103         JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 128); | 99         JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 128); | 
| 104     // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 256 yet | 100     // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 256 yet | 
| 105     alg_to_info_["A256KW"] = | 101     alg_to_info_["A256KW"] = | 
| 106         JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 256); | 102         JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 256); | 
| 107     alg_to_info_["A128GCM"] = JwkAlgorithmInfo( | 103     alg_to_info_["A128GCM"] = JwkAlgorithmInfo( | 
| 108         &BindAlgorithmId<CreateAlgorithm, | 104         &BindAlgorithmId<CreateAlgorithm, blink::WebCryptoAlgorithmIdAesGcm>, | 
| 109                          blink::WebCryptoAlgorithmIdAesGcm>, 128); | 105         128); | 
| 110     alg_to_info_["A256GCM"] = JwkAlgorithmInfo( | 106     alg_to_info_["A256GCM"] = JwkAlgorithmInfo( | 
| 111         &BindAlgorithmId<CreateAlgorithm, | 107         &BindAlgorithmId<CreateAlgorithm, blink::WebCryptoAlgorithmIdAesGcm>, | 
| 112                          blink::WebCryptoAlgorithmIdAesGcm>, 256); | 108         256); | 
| 113     alg_to_info_["A128CBC"] = JwkAlgorithmInfo( | 109     alg_to_info_["A128CBC"] = JwkAlgorithmInfo( | 
| 114         &BindAlgorithmId<CreateAlgorithm, | 110         &BindAlgorithmId<CreateAlgorithm, blink::WebCryptoAlgorithmIdAesCbc>, | 
| 115                          blink::WebCryptoAlgorithmIdAesCbc>, 128); | 111         128); | 
| 116     alg_to_info_["A192CBC"] = JwkAlgorithmInfo( | 112     alg_to_info_["A192CBC"] = JwkAlgorithmInfo( | 
| 117         &BindAlgorithmId<CreateAlgorithm, | 113         &BindAlgorithmId<CreateAlgorithm, blink::WebCryptoAlgorithmIdAesCbc>, | 
| 118                          blink::WebCryptoAlgorithmIdAesCbc>, 192); | 114         192); | 
| 119     alg_to_info_["A256CBC"] = JwkAlgorithmInfo( | 115     alg_to_info_["A256CBC"] = JwkAlgorithmInfo( | 
| 120         &BindAlgorithmId<CreateAlgorithm, | 116         &BindAlgorithmId<CreateAlgorithm, blink::WebCryptoAlgorithmIdAesCbc>, | 
| 121                          blink::WebCryptoAlgorithmIdAesCbc>, 256); | 117         256); | 
| 122   } | 118   } | 
| 123 | 119 | 
| 124   // Returns NULL if the algorithm name was not registered. | 120   // Returns NULL if the algorithm name was not registered. | 
| 125   const JwkAlgorithmInfo* GetAlgorithmInfo(const std::string& jwk_alg) const { | 121   const JwkAlgorithmInfo* GetAlgorithmInfo(const std::string& jwk_alg) const { | 
| 126     const JwkAlgorithmInfoMap::const_iterator pos = alg_to_info_.find(jwk_alg); | 122     const JwkAlgorithmInfoMap::const_iterator pos = alg_to_info_.find(jwk_alg); | 
| 127     if (pos == alg_to_info_.end()) | 123     if (pos == alg_to_info_.end()) | 
| 128       return NULL; | 124       return NULL; | 
| 129     return &pos->second; | 125     return &pos->second; | 
| 130   } | 126   } | 
| 131 | 127 | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 148 bool WebCryptoAlgorithmsConsistent(const blink::WebCryptoAlgorithm& alg1, | 144 bool WebCryptoAlgorithmsConsistent(const blink::WebCryptoAlgorithm& alg1, | 
| 149                                    const blink::WebCryptoAlgorithm& alg2) { | 145                                    const blink::WebCryptoAlgorithm& alg2) { | 
| 150   DCHECK(!alg1.isNull()); | 146   DCHECK(!alg1.isNull()); | 
| 151   DCHECK(!alg2.isNull()); | 147   DCHECK(!alg2.isNull()); | 
| 152   if (alg1.id() != alg2.id()) | 148   if (alg1.id() != alg2.id()) | 
| 153     return false; | 149     return false; | 
| 154   switch (alg1.id()) { | 150   switch (alg1.id()) { | 
| 155     case blink::WebCryptoAlgorithmIdHmac: | 151     case blink::WebCryptoAlgorithmIdHmac: | 
| 156     case blink::WebCryptoAlgorithmIdRsaOaep: | 152     case blink::WebCryptoAlgorithmIdRsaOaep: | 
| 157     case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 153     case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 
| 158       if (WebCryptoAlgorithmsConsistent( | 154       if (WebCryptoAlgorithmsConsistent(GetInnerHashAlgorithm(alg1), | 
| 159               GetInnerHashAlgorithm(alg1), | 155                                         GetInnerHashAlgorithm(alg2))) { | 
| 160               GetInnerHashAlgorithm(alg2))) { |  | 
| 161         return true; | 156         return true; | 
| 162       } | 157       } | 
| 163       break; | 158       break; | 
| 164     case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 159     case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 
| 165     case blink::WebCryptoAlgorithmIdSha1: | 160     case blink::WebCryptoAlgorithmIdSha1: | 
| 166     case blink::WebCryptoAlgorithmIdSha224: | 161     case blink::WebCryptoAlgorithmIdSha224: | 
| 167     case blink::WebCryptoAlgorithmIdSha256: | 162     case blink::WebCryptoAlgorithmIdSha256: | 
| 168     case blink::WebCryptoAlgorithmIdSha384: | 163     case blink::WebCryptoAlgorithmIdSha384: | 
| 169     case blink::WebCryptoAlgorithmIdSha512: | 164     case blink::WebCryptoAlgorithmIdSha512: | 
| 170     case blink::WebCryptoAlgorithmIdAesCbc: | 165     case blink::WebCryptoAlgorithmIdAesCbc: | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 244 | 239 | 
| 245   if (!value->GetAsBoolean(result)) | 240   if (!value->GetAsBoolean(result)) | 
| 246     return Status::ErrorJwkPropertyWrongType(path, "boolean"); | 241     return Status::ErrorJwkPropertyWrongType(path, "boolean"); | 
| 247 | 242 | 
| 248   *property_exists = true; | 243   *property_exists = true; | 
| 249   return Status::Success(); | 244   return Status::Success(); | 
| 250 } | 245 } | 
| 251 | 246 | 
| 252 }  // namespace | 247 }  // namespace | 
| 253 | 248 | 
| 254 Status ImportKeyJwk( | 249 Status ImportKeyJwk(const CryptoData& key_data, | 
| 255     const CryptoData& key_data, | 250                     const blink::WebCryptoAlgorithm& algorithm_or_null, | 
| 256     const blink::WebCryptoAlgorithm& algorithm_or_null, | 251                     bool extractable, | 
| 257     bool extractable, | 252                     blink::WebCryptoKeyUsageMask usage_mask, | 
| 258     blink::WebCryptoKeyUsageMask usage_mask, | 253                     blink::WebCryptoKey* key) { | 
| 259     blink::WebCryptoKey* key) { |  | 
| 260 | 254 | 
| 261   // The goal of this method is to extract key material and meta data from the | 255   // The goal of this method is to extract key material and meta data from the | 
| 262   // incoming JWK, combine them with the input parameters, and ultimately import | 256   // incoming JWK, combine them with the input parameters, and ultimately import | 
| 263   // a Web Crypto Key. | 257   // a Web Crypto Key. | 
| 264   // | 258   // | 
| 265   // JSON Web Key Format (JWK) | 259   // JSON Web Key Format (JWK) | 
| 266   // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-16 | 260   // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-16 | 
| 267   // TODO(padolph): Not all possible values are handled by this code right now | 261   // TODO(padolph): Not all possible values are handled by this code right now | 
| 268   // | 262   // | 
| 269   // A JWK is a simple JSON dictionary with the following entries | 263   // A JWK is a simple JSON dictionary with the following entries | 
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 458       return Status::ErrorJwkUnrecognizedAlgorithm();  // case 1 | 452       return Status::ErrorJwkUnrecognizedAlgorithm();  // case 1 | 
| 459 | 453 | 
| 460     // JWK alg valid | 454     // JWK alg valid | 
| 461     if (algorithm_or_null.isNull()) { | 455     if (algorithm_or_null.isNull()) { | 
| 462       // input algorithm not specified | 456       // input algorithm not specified | 
| 463       algorithm = jwk_algorithm;  // case 2 | 457       algorithm = jwk_algorithm;  // case 2 | 
| 464     } else { | 458     } else { | 
| 465       // input algorithm specified | 459       // input algorithm specified | 
| 466       if (!WebCryptoAlgorithmsConsistent(jwk_algorithm, algorithm_or_null)) | 460       if (!WebCryptoAlgorithmsConsistent(jwk_algorithm, algorithm_or_null)) | 
| 467         return Status::ErrorJwkAlgorithmInconsistent();  // case 3 | 461         return Status::ErrorJwkAlgorithmInconsistent();  // case 3 | 
| 468       algorithm = algorithm_or_null;  // case 4 | 462       algorithm = algorithm_or_null;                     // case 4 | 
| 469     } | 463     } | 
| 470   } else { | 464   } else { | 
| 471     // JWK alg missing | 465     // JWK alg missing | 
| 472     if (algorithm_or_null.isNull()) | 466     if (algorithm_or_null.isNull()) | 
| 473       return Status::ErrorJwkAlgorithmMissing();  // case 5 | 467       return Status::ErrorJwkAlgorithmMissing();  // case 5 | 
| 474     algorithm = algorithm_or_null;  // case 6 | 468     algorithm = algorithm_or_null;                // case 6 | 
| 475   } | 469   } | 
| 476   DCHECK(!algorithm.isNull()); | 470   DCHECK(!algorithm.isNull()); | 
| 477 | 471 | 
| 478   // JWK "use" (optional) --> usage_mask parameter | 472   // JWK "use" (optional) --> usage_mask parameter | 
| 479   std::string jwk_use_value; | 473   std::string jwk_use_value; | 
| 480   bool has_jwk_use; | 474   bool has_jwk_use; | 
| 481   status = | 475   status = | 
| 482       GetOptionalJwkString(dict_value, "use", &jwk_use_value, &has_jwk_use); | 476       GetOptionalJwkString(dict_value, "use", &jwk_use_value, &has_jwk_use); | 
| 483   if (status.IsError()) | 477   if (status.IsError()) | 
| 484     return status; | 478     return status; | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 560   } else { | 554   } else { | 
| 561     return Status::ErrorJwkUnrecognizedKty(); | 555     return Status::ErrorJwkUnrecognizedKty(); | 
| 562   } | 556   } | 
| 563 | 557 | 
| 564   return Status::Success(); | 558   return Status::Success(); | 
| 565 } | 559 } | 
| 566 | 560 | 
| 567 }  // namespace webcrypto | 561 }  // namespace webcrypto | 
| 568 | 562 | 
| 569 }  // namespace content | 563 }  // namespace content | 
| OLD | NEW | 
|---|