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

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

Issue 155623005: Refactor to share more code between OpenSSL and NSS implementations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address sleevi comments (except for explicit ctor) Created 6 years, 10 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "content/renderer/webcrypto/webcrypto_impl.h"
6
7 #include <algorithm> 5 #include <algorithm>
8 #include <functional> 6 #include <functional>
9 #include <map> 7 #include <map>
10 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
11 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
12 #include "base/logging.h" 10 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
14 #include "base/strings/string_piece.h" 12 #include "base/strings/string_piece.h"
15 #include "base/values.h" 13 #include "base/values.h"
14 #include "content/renderer/webcrypto/crypto_data.h"
15 #include "content/renderer/webcrypto/platform_crypto.h"
16 #include "content/renderer/webcrypto/shared_crypto.h"
16 #include "content/renderer/webcrypto/webcrypto_util.h" 17 #include "content/renderer/webcrypto/webcrypto_util.h"
17 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
18 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
19 #include "third_party/WebKit/public/platform/WebCryptoKey.h"
20 #include "third_party/WebKit/public/platform/WebString.h"
21 18
22 namespace content { 19 namespace content {
23 20
24 using webcrypto::Status; 21 namespace webcrypto {
25 22
26 namespace { 23 namespace {
27 24
28 void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
29 DCHECK(status.IsError());
30 if (status.HasErrorDetails())
31 result->completeWithError(blink::WebString::fromUTF8(status.ToString()));
32 else
33 result->completeWithError();
34 }
35
36 bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) {
37 // TODO(padolph): include all other asymmetric algorithms once they are
38 // defined, e.g. EC and DH.
39 return (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
40 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
41 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep);
42 }
43
44 typedef blink::WebCryptoAlgorithm (*AlgorithmCreationFunc)(); 25 typedef blink::WebCryptoAlgorithm (*AlgorithmCreationFunc)();
45 26
46 class JwkAlgorithmInfo { 27 class JwkAlgorithmInfo {
47 public: 28 public:
48 JwkAlgorithmInfo() 29 JwkAlgorithmInfo()
49 : creation_func_(NULL), 30 : creation_func_(NULL),
50 required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) { 31 required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) {
51 32
52 } 33 }
53 34
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 typedef std::map<std::string, JwkAlgorithmInfo> JwkAlgorithmInfoMap; 68 typedef std::map<std::string, JwkAlgorithmInfo> JwkAlgorithmInfoMap;
88 69
89 class JwkAlgorithmRegistry { 70 class JwkAlgorithmRegistry {
90 public: 71 public:
91 JwkAlgorithmRegistry() { 72 JwkAlgorithmRegistry() {
92 // TODO(eroman): 73 // TODO(eroman):
93 // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-20 74 // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-20
94 // says HMAC with SHA-2 should have a key size at least as large as the 75 // says HMAC with SHA-2 should have a key size at least as large as the
95 // hash output. 76 // hash output.
96 alg_to_info_["HS256"] = JwkAlgorithmInfo( 77 alg_to_info_["HS256"] = JwkAlgorithmInfo(
97 &BindAlgorithmId<webcrypto::CreateHmacAlgorithmByHashId, 78 &BindAlgorithmId<CreateHmacAlgorithmByHashId,
98 blink::WebCryptoAlgorithmIdSha256>); 79 blink::WebCryptoAlgorithmIdSha256>);
99 alg_to_info_["HS384"] = JwkAlgorithmInfo( 80 alg_to_info_["HS384"] = JwkAlgorithmInfo(
100 &BindAlgorithmId<webcrypto::CreateHmacAlgorithmByHashId, 81 &BindAlgorithmId<CreateHmacAlgorithmByHashId,
101 blink::WebCryptoAlgorithmIdSha384>); 82 blink::WebCryptoAlgorithmIdSha384>);
102 alg_to_info_["HS512"] = JwkAlgorithmInfo( 83 alg_to_info_["HS512"] = JwkAlgorithmInfo(
103 &BindAlgorithmId<webcrypto::CreateHmacAlgorithmByHashId, 84 &BindAlgorithmId<CreateHmacAlgorithmByHashId,
104 blink::WebCryptoAlgorithmIdSha512>); 85 blink::WebCryptoAlgorithmIdSha512>);
105 alg_to_info_["RS256"] = JwkAlgorithmInfo( 86 alg_to_info_["RS256"] = JwkAlgorithmInfo(
106 &BindAlgorithmId<webcrypto::CreateRsaSsaAlgorithm, 87 &BindAlgorithmId<CreateRsaSsaAlgorithm,
107 blink::WebCryptoAlgorithmIdSha256>); 88 blink::WebCryptoAlgorithmIdSha256>);
108 alg_to_info_["RS384"] = JwkAlgorithmInfo( 89 alg_to_info_["RS384"] = JwkAlgorithmInfo(
109 &BindAlgorithmId<webcrypto::CreateRsaSsaAlgorithm, 90 &BindAlgorithmId<CreateRsaSsaAlgorithm,
110 blink::WebCryptoAlgorithmIdSha384>); 91 blink::WebCryptoAlgorithmIdSha384>);
111 alg_to_info_["RS512"] = JwkAlgorithmInfo( 92 alg_to_info_["RS512"] = JwkAlgorithmInfo(
112 &BindAlgorithmId<webcrypto::CreateRsaSsaAlgorithm, 93 &BindAlgorithmId<CreateRsaSsaAlgorithm,
113 blink::WebCryptoAlgorithmIdSha512>); 94 blink::WebCryptoAlgorithmIdSha512>);
114 alg_to_info_["RSA1_5"] = JwkAlgorithmInfo( 95 alg_to_info_["RSA1_5"] = JwkAlgorithmInfo(
115 &BindAlgorithmId<webcrypto::CreateAlgorithm, 96 &BindAlgorithmId<CreateAlgorithm,
116 blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5>); 97 blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5>);
117 alg_to_info_["RSA-OAEP"] = JwkAlgorithmInfo( 98 alg_to_info_["RSA-OAEP"] = JwkAlgorithmInfo(
118 &BindAlgorithmId<webcrypto::CreateRsaOaepAlgorithm, 99 &BindAlgorithmId<CreateRsaOaepAlgorithm,
119 blink::WebCryptoAlgorithmIdSha1>); 100 blink::WebCryptoAlgorithmIdSha1>);
120 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 128 yet 101 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 128 yet
121 alg_to_info_["A128KW"] = 102 alg_to_info_["A128KW"] =
122 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 128); 103 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 128);
123 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 256 yet 104 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 256 yet
124 alg_to_info_["A256KW"] = 105 alg_to_info_["A256KW"] =
125 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 256); 106 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 256);
126 alg_to_info_["A128GCM"] = JwkAlgorithmInfo( 107 alg_to_info_["A128GCM"] = JwkAlgorithmInfo(
127 &BindAlgorithmId<webcrypto::CreateAlgorithm, 108 &BindAlgorithmId<CreateAlgorithm,
128 blink::WebCryptoAlgorithmIdAesGcm>, 128); 109 blink::WebCryptoAlgorithmIdAesGcm>, 128);
129 alg_to_info_["A256GCM"] = JwkAlgorithmInfo( 110 alg_to_info_["A256GCM"] = JwkAlgorithmInfo(
130 &BindAlgorithmId<webcrypto::CreateAlgorithm, 111 &BindAlgorithmId<CreateAlgorithm,
131 blink::WebCryptoAlgorithmIdAesGcm>, 256); 112 blink::WebCryptoAlgorithmIdAesGcm>, 256);
132 alg_to_info_["A128CBC"] = JwkAlgorithmInfo( 113 alg_to_info_["A128CBC"] = JwkAlgorithmInfo(
133 &BindAlgorithmId<webcrypto::CreateAlgorithm, 114 &BindAlgorithmId<CreateAlgorithm,
134 blink::WebCryptoAlgorithmIdAesCbc>, 128); 115 blink::WebCryptoAlgorithmIdAesCbc>, 128);
135 alg_to_info_["A192CBC"] = JwkAlgorithmInfo( 116 alg_to_info_["A192CBC"] = JwkAlgorithmInfo(
136 &BindAlgorithmId<webcrypto::CreateAlgorithm, 117 &BindAlgorithmId<CreateAlgorithm,
137 blink::WebCryptoAlgorithmIdAesCbc>, 192); 118 blink::WebCryptoAlgorithmIdAesCbc>, 192);
138 alg_to_info_["A256CBC"] = JwkAlgorithmInfo( 119 alg_to_info_["A256CBC"] = JwkAlgorithmInfo(
139 &BindAlgorithmId<webcrypto::CreateAlgorithm, 120 &BindAlgorithmId<CreateAlgorithm,
140 blink::WebCryptoAlgorithmIdAesCbc>, 256); 121 blink::WebCryptoAlgorithmIdAesCbc>, 256);
141 } 122 }
142 123
143 // Returns NULL if the algorithm name was not registered. 124 // Returns NULL if the algorithm name was not registered.
144 const JwkAlgorithmInfo* GetAlgorithmInfo(const std::string& jwk_alg) const { 125 const JwkAlgorithmInfo* GetAlgorithmInfo(const std::string& jwk_alg) const {
145 const JwkAlgorithmInfoMap::const_iterator pos = alg_to_info_.find(jwk_alg); 126 const JwkAlgorithmInfoMap::const_iterator pos = alg_to_info_.find(jwk_alg);
146 if (pos == alg_to_info_.end()) 127 if (pos == alg_to_info_.end())
147 return NULL; 128 return NULL;
148 return &pos->second; 129 return &pos->second;
149 } 130 }
(...skipping 18 matching lines...) Expand all
168 const blink::WebCryptoAlgorithm& alg2) { 149 const blink::WebCryptoAlgorithm& alg2) {
169 DCHECK(!alg1.isNull()); 150 DCHECK(!alg1.isNull());
170 DCHECK(!alg2.isNull()); 151 DCHECK(!alg2.isNull());
171 if (alg1.id() != alg2.id()) 152 if (alg1.id() != alg2.id())
172 return false; 153 return false;
173 switch (alg1.id()) { 154 switch (alg1.id()) {
174 case blink::WebCryptoAlgorithmIdHmac: 155 case blink::WebCryptoAlgorithmIdHmac:
175 case blink::WebCryptoAlgorithmIdRsaOaep: 156 case blink::WebCryptoAlgorithmIdRsaOaep:
176 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: 157 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
177 if (WebCryptoAlgorithmsConsistent( 158 if (WebCryptoAlgorithmsConsistent(
178 webcrypto::GetInnerHashAlgorithm(alg1), 159 GetInnerHashAlgorithm(alg1),
179 webcrypto::GetInnerHashAlgorithm(alg2))) { 160 GetInnerHashAlgorithm(alg2))) {
180 return true; 161 return true;
181 } 162 }
182 break; 163 break;
183 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: 164 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
184 case blink::WebCryptoAlgorithmIdSha1: 165 case blink::WebCryptoAlgorithmIdSha1:
185 case blink::WebCryptoAlgorithmIdSha224: 166 case blink::WebCryptoAlgorithmIdSha224:
186 case blink::WebCryptoAlgorithmIdSha256: 167 case blink::WebCryptoAlgorithmIdSha256:
187 case blink::WebCryptoAlgorithmIdSha384: 168 case blink::WebCryptoAlgorithmIdSha384:
188 case blink::WebCryptoAlgorithmIdSha512: 169 case blink::WebCryptoAlgorithmIdSha512:
189 case blink::WebCryptoAlgorithmIdAesCbc: 170 case blink::WebCryptoAlgorithmIdAesCbc:
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 // the base64-decoded bytes to |*result|. If the property does not exist or is 216 // the base64-decoded bytes to |*result|. If the property does not exist or is
236 // not a string, or could not be base64-decoded, returns an error. 217 // not a string, or could not be base64-decoded, returns an error.
237 Status GetJwkBytes(base::DictionaryValue* dict, 218 Status GetJwkBytes(base::DictionaryValue* dict,
238 const std::string& path, 219 const std::string& path,
239 std::string* result) { 220 std::string* result) {
240 std::string base64_string; 221 std::string base64_string;
241 Status status = GetJwkString(dict, path, &base64_string); 222 Status status = GetJwkString(dict, path, &base64_string);
242 if (status.IsError()) 223 if (status.IsError())
243 return status; 224 return status;
244 225
245 if (!webcrypto::Base64DecodeUrlSafe(base64_string, result)) 226 if (!Base64DecodeUrlSafe(base64_string, result))
246 return Status::ErrorJwkBase64Decode(path); 227 return Status::ErrorJwkBase64Decode(path);
247 228
248 return Status::Success(); 229 return Status::Success();
249 } 230 }
250 231
251 // Extracts the optional boolean property with key |path| from |dict| and saves 232 // Extracts the optional boolean property with key |path| from |dict| and saves
252 // the result to |*result| if it was found. If the property exists and is not a 233 // the result to |*result| if it was found. If the property exists and is not a
253 // boolean, returns an error. Otherwise returns success, and sets 234 // boolean, returns an error. Otherwise returns success, and sets
254 // |*property_exists| if it was found. 235 // |*property_exists| if it was found.
255 Status GetOptionalJwkBool(base::DictionaryValue* dict, 236 Status GetOptionalJwkBool(base::DictionaryValue* dict,
256 const std::string& path, 237 const std::string& path,
257 bool* result, 238 bool* result,
258 bool* property_exists) { 239 bool* property_exists) {
259 *property_exists = false; 240 *property_exists = false;
260 base::Value* value = NULL; 241 base::Value* value = NULL;
261 if (!dict->Get(path, &value)) 242 if (!dict->Get(path, &value))
262 return Status::Success(); 243 return Status::Success();
263 244
264 if (!value->GetAsBoolean(result)) 245 if (!value->GetAsBoolean(result))
265 return Status::ErrorJwkPropertyWrongType(path, "boolean"); 246 return Status::ErrorJwkPropertyWrongType(path, "boolean");
266 247
267 *property_exists = true; 248 *property_exists = true;
268 return Status::Success(); 249 return Status::Success();
269 } 250 }
270 251
271 } // namespace 252 } // namespace
272 253
273 WebCryptoImpl::WebCryptoImpl() { 254 Status ImportKeyJwk(
274 Init(); 255 const CryptoData& key_data,
275 }
276
277 void WebCryptoImpl::encrypt(
278 const blink::WebCryptoAlgorithm& algorithm,
279 const blink::WebCryptoKey& key,
280 const unsigned char* data,
281 unsigned int data_size,
282 blink::WebCryptoResult result) {
283 DCHECK(!algorithm.isNull());
284 blink::WebArrayBuffer buffer;
285 Status status = EncryptInternal(algorithm, key, data, data_size, &buffer);
286 if (status.IsError())
287 CompleteWithError(status, &result);
288 else
289 result.completeWithBuffer(buffer);
290 }
291
292 void WebCryptoImpl::decrypt(
293 const blink::WebCryptoAlgorithm& algorithm,
294 const blink::WebCryptoKey& key,
295 const unsigned char* data,
296 unsigned int data_size,
297 blink::WebCryptoResult result) {
298 DCHECK(!algorithm.isNull());
299 blink::WebArrayBuffer buffer;
300 Status status = DecryptInternal(algorithm, key, data, data_size, &buffer);
301 if (status.IsError())
302 CompleteWithError(status, &result);
303 else
304 result.completeWithBuffer(buffer);
305 }
306
307 void WebCryptoImpl::digest(
308 const blink::WebCryptoAlgorithm& algorithm,
309 const unsigned char* data,
310 unsigned int data_size,
311 blink::WebCryptoResult result) {
312 DCHECK(!algorithm.isNull());
313 blink::WebArrayBuffer buffer;
314 Status status = DigestInternal(algorithm, data, data_size, &buffer);
315 if (status.IsError())
316 CompleteWithError(status, &result);
317 else
318 result.completeWithBuffer(buffer);
319 }
320
321 void WebCryptoImpl::generateKey(
322 const blink::WebCryptoAlgorithm& algorithm,
323 bool extractable,
324 blink::WebCryptoKeyUsageMask usage_mask,
325 blink::WebCryptoResult result) {
326 DCHECK(!algorithm.isNull());
327 if (IsAlgorithmAsymmetric(algorithm)) {
328 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
329 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
330 Status status = GenerateKeyPairInternal(
331 algorithm, extractable, usage_mask, &public_key, &private_key);
332 if (status.IsError()) {
333 CompleteWithError(status, &result);
334 } else {
335 DCHECK(public_key.handle());
336 DCHECK(private_key.handle());
337 DCHECK_EQ(algorithm.id(), public_key.algorithm().id());
338 DCHECK_EQ(algorithm.id(), private_key.algorithm().id());
339 DCHECK_EQ(true, public_key.extractable());
340 DCHECK_EQ(extractable, private_key.extractable());
341 DCHECK_EQ(usage_mask, public_key.usages());
342 DCHECK_EQ(usage_mask, private_key.usages());
343 result.completeWithKeyPair(public_key, private_key);
344 }
345 } else {
346 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
347 Status status = GenerateSecretKeyInternal(
348 algorithm, extractable, usage_mask, &key);
349 if (status.IsError()) {
350 CompleteWithError(status, &result);
351 } else {
352 DCHECK(key.handle());
353 DCHECK_EQ(algorithm.id(), key.algorithm().id());
354 DCHECK_EQ(extractable, key.extractable());
355 DCHECK_EQ(usage_mask, key.usages());
356 result.completeWithKey(key);
357 }
358 }
359 }
360
361 void WebCryptoImpl::importKey(
362 blink::WebCryptoKeyFormat format,
363 const unsigned char* key_data,
364 unsigned int key_data_size,
365 const blink::WebCryptoAlgorithm& algorithm_or_null, 256 const blink::WebCryptoAlgorithm& algorithm_or_null,
366 bool extractable, 257 bool extractable,
367 blink::WebCryptoKeyUsageMask usage_mask, 258 blink::WebCryptoKeyUsageMask usage_mask,
368 blink::WebCryptoResult result) {
369 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
370 Status status = Status::Error();
371 if (format == blink::WebCryptoKeyFormatJwk) {
372 status = ImportKeyJwk(key_data,
373 key_data_size,
374 algorithm_or_null,
375 extractable,
376 usage_mask,
377 &key);
378 } else {
379 status = ImportKeyInternal(format,
380 key_data,
381 key_data_size,
382 algorithm_or_null,
383 extractable,
384 usage_mask,
385 &key);
386 }
387 if (status.IsError()) {
388 CompleteWithError(status, &result);
389 } else {
390 DCHECK(key.handle());
391 DCHECK(!key.algorithm().isNull());
392 DCHECK_EQ(extractable, key.extractable());
393 result.completeWithKey(key);
394 }
395 }
396
397 void WebCryptoImpl::exportKey(
398 blink::WebCryptoKeyFormat format,
399 const blink::WebCryptoKey& key,
400 blink::WebCryptoResult result) {
401 blink::WebArrayBuffer buffer;
402 Status status = ExportKeyInternal(format, key, &buffer);
403 if (status.IsError())
404 CompleteWithError(status, &result);
405 else
406 result.completeWithBuffer(buffer);
407 }
408
409 void WebCryptoImpl::sign(
410 const blink::WebCryptoAlgorithm& algorithm,
411 const blink::WebCryptoKey& key,
412 const unsigned char* data,
413 unsigned int data_size,
414 blink::WebCryptoResult result) {
415 DCHECK(!algorithm.isNull());
416 blink::WebArrayBuffer buffer;
417 Status status = SignInternal(algorithm, key, data, data_size, &buffer);
418 if (status.IsError())
419 CompleteWithError(status, &result);
420 else
421 result.completeWithBuffer(buffer);
422 }
423
424 void WebCryptoImpl::verifySignature(
425 const blink::WebCryptoAlgorithm& algorithm,
426 const blink::WebCryptoKey& key,
427 const unsigned char* signature,
428 unsigned int signature_size,
429 const unsigned char* data,
430 unsigned int data_size,
431 blink::WebCryptoResult result) {
432 DCHECK(!algorithm.isNull());
433 bool signature_match = false;
434 Status status = VerifySignatureInternal(algorithm,
435 key,
436 signature,
437 signature_size,
438 data,
439 data_size,
440 &signature_match);
441 if (status.IsError())
442 CompleteWithError(status, &result);
443 else
444 result.completeWithBoolean(signature_match);
445 }
446
447 Status WebCryptoImpl::ImportKeyJwk(
448 const unsigned char* key_data,
449 unsigned int key_data_size,
450 const blink::WebCryptoAlgorithm& algorithm_or_null,
451 bool extractable,
452 blink::WebCryptoKeyUsageMask usage_mask,
453 blink::WebCryptoKey* key) { 259 blink::WebCryptoKey* key) {
454 260
455 // The goal of this method is to extract key material and meta data from the 261 // The goal of this method is to extract key material and meta data from the
456 // incoming JWK, combine them with the input parameters, and ultimately import 262 // incoming JWK, combine them with the input parameters, and ultimately import
457 // a Web Crypto Key. 263 // a Web Crypto Key.
458 // 264 //
459 // JSON Web Key Format (JWK) 265 // JSON Web Key Format (JWK)
460 // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-16 266 // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-16
461 // TODO(padolph): Not all possible values are handled by this code right now 267 // TODO(padolph): Not all possible values are handled by this code right now
462 // 268 //
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 // Web Crypto Key non-extractable. Conversely, if the JWK extractable is 386 // Web Crypto Key non-extractable. Conversely, if the JWK extractable is
581 // false but the input parameter is true, it is an inconsistency. If both 387 // false but the input parameter is true, it is an inconsistency. If both
582 // are true or both are false, use that value. 388 // are true or both are false, use that value.
583 // 389 //
584 // usage_mask 390 // usage_mask
585 // The input usage_mask must be a strict subset of the interpreted JWK use 391 // The input usage_mask must be a strict subset of the interpreted JWK use
586 // value, else it is judged inconsistent. In all cases the input usage_mask 392 // value, else it is judged inconsistent. In all cases the input usage_mask
587 // is used as the final usage_mask. 393 // is used as the final usage_mask.
588 // 394 //
589 395
590 if (!key_data_size) 396 if (!key_data.byte_length())
591 return Status::ErrorImportEmptyKeyData(); 397 return Status::ErrorImportEmptyKeyData();
592 DCHECK(key); 398 DCHECK(key);
593 399
594 // Parse the incoming JWK JSON. 400 // Parse the incoming JWK JSON.
595 base::StringPiece json_string(reinterpret_cast<const char*>(key_data), 401 base::StringPiece json_string(reinterpret_cast<const char*>(key_data.bytes()),
596 key_data_size); 402 key_data.byte_length());
597 scoped_ptr<base::Value> value(base::JSONReader::Read(json_string)); 403 scoped_ptr<base::Value> value(base::JSONReader::Read(json_string));
598 // Note, bare pointer dict_value is ok since it points into scoped value. 404 // Note, bare pointer dict_value is ok since it points into scoped value.
599 base::DictionaryValue* dict_value = NULL; 405 base::DictionaryValue* dict_value = NULL;
600 if (!value.get() || !value->GetAsDictionary(&dict_value) || !dict_value) 406 if (!value.get() || !value->GetAsDictionary(&dict_value) || !dict_value)
601 return Status::ErrorJwkNotDictionary(); 407 return Status::ErrorJwkNotDictionary();
602 408
603 // JWK "kty". Exit early if this required JWK parameter is missing. 409 // JWK "kty". Exit early if this required JWK parameter is missing.
604 std::string jwk_kty_value; 410 std::string jwk_kty_value;
605 Status status = GetJwkString(dict_value, "kty", &jwk_kty_value); 411 Status status = GetJwkString(dict_value, "kty", &jwk_kty_value);
606 if (status.IsError()) 412 if (status.IsError())
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 // string. For example "A128CBC" implies the JWK carries 128 bits 514 // string. For example "A128CBC" implies the JWK carries 128 bits
709 // of key material. For such keys validate that enough bytes were provided. 515 // of key material. For such keys validate that enough bytes were provided.
710 // If this validation is not done, then it would be possible to select a 516 // If this validation is not done, then it would be possible to select a
711 // different algorithm by passing a different lengthed key, since that is 517 // different algorithm by passing a different lengthed key, since that is
712 // how WebCrypto interprets things. 518 // how WebCrypto interprets things.
713 if (algorithm_info && 519 if (algorithm_info &&
714 algorithm_info->IsInvalidKeyByteLength(jwk_k_value.size())) { 520 algorithm_info->IsInvalidKeyByteLength(jwk_k_value.size())) {
715 return Status::ErrorJwkIncorrectKeyLength(); 521 return Status::ErrorJwkIncorrectKeyLength();
716 } 522 }
717 523
718 return ImportKeyInternal(blink::WebCryptoKeyFormatRaw, 524 return ImportKey(blink::WebCryptoKeyFormatRaw,
719 reinterpret_cast<const uint8*>(jwk_k_value.data()), 525 jwk_k_value,
720 jwk_k_value.size(), 526 algorithm,
721 algorithm, 527 extractable,
722 extractable, 528 usage_mask,
723 usage_mask, 529 key);
724 key);
725 } else if (jwk_kty_value == "RSA") { 530 } else if (jwk_kty_value == "RSA") {
726 531
727 // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry 532 // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry
728 // in the JWK, while an RSA private key must have those, plus at least a "d" 533 // in the JWK, while an RSA private key must have those, plus at least a "d"
729 // (private exponent) entry. 534 // (private exponent) entry.
730 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, 535 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
731 // section 6.3. 536 // section 6.3.
732 537
733 // RSA private key import is not currently supported, so fail here if a "d" 538 // RSA private key import is not currently supported, so fail here if a "d"
734 // entry is found. 539 // entry is found.
735 // TODO(padolph): Support RSA private key import. 540 // TODO(padolph): Support RSA private key import.
736 if (dict_value->HasKey("d")) 541 if (dict_value->HasKey("d"))
737 return Status::ErrorJwkRsaPrivateKeyUnsupported(); 542 return Status::ErrorJwkRsaPrivateKeyUnsupported();
738 543
739 std::string jwk_n_value; 544 std::string jwk_n_value;
740 status = GetJwkBytes(dict_value, "n", &jwk_n_value); 545 status = GetJwkBytes(dict_value, "n", &jwk_n_value);
741 if (status.IsError()) 546 if (status.IsError())
742 return status; 547 return status;
743 std::string jwk_e_value; 548 std::string jwk_e_value;
744 status = GetJwkBytes(dict_value, "e", &jwk_e_value); 549 status = GetJwkBytes(dict_value, "e", &jwk_e_value);
745 if (status.IsError()) 550 if (status.IsError())
746 return status; 551 return status;
747 552
748 return ImportRsaPublicKeyInternal( 553 return platform::ImportRsaPublicKey(jwk_n_value,
749 reinterpret_cast<const uint8*>(jwk_n_value.data()), 554 jwk_e_value,
750 jwk_n_value.size(), 555 algorithm,
751 reinterpret_cast<const uint8*>(jwk_e_value.data()), 556 extractable,
752 jwk_e_value.size(), 557 usage_mask,
753 algorithm, 558 key);
Ryan Sleevi 2014/02/07 21:26:40 alignment
eroman 2014/02/08 02:23:51 Done.
754 extractable,
755 usage_mask,
756 key);
757 559
758 } else { 560 } else {
759 return Status::ErrorJwkUnrecognizedKty(); 561 return Status::ErrorJwkUnrecognizedKty();
760 } 562 }
761 563
762 return Status::Success(); 564 return Status::Success();
763 } 565 }
764 566
567 } // namespace webcrypto
568
765 } // namespace content 569 } // namespace content
570
571
Ryan Sleevi 2014/02/07 21:26:40 unnecessary newline?
eroman 2014/02/08 02:23:51 Ick git cl format added these.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698