Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(247)

Side by Side Diff: content/renderer/webcrypto/jwk.cc

Issue 178073007: [webcrypto] Update to use the KeyAlgorithm. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | content/renderer/webcrypto/platform_crypto.h » ('j') | content/renderer/webcrypto/platform_crypto_nss.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698