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

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: Fix for openssl 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/platform_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 25
44 typedef blink::WebCryptoAlgorithm (*AlgorithmCreationFunc)(); 26 typedef blink::WebCryptoAlgorithm (*AlgorithmCreationFunc)();
45 27
46 class JwkAlgorithmInfo { 28 class JwkAlgorithmInfo {
47 public: 29 public:
48 JwkAlgorithmInfo() 30 JwkAlgorithmInfo()
49 : creation_func_(NULL), 31 : creation_func_(NULL),
50 required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) { 32 required_key_length_bytes_(NO_KEY_SIZE_REQUIREMENT) {
51 33
52 } 34 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 typedef std::map<std::string, JwkAlgorithmInfo> JwkAlgorithmInfoMap; 69 typedef std::map<std::string, JwkAlgorithmInfo> JwkAlgorithmInfoMap;
88 70
89 class JwkAlgorithmRegistry { 71 class JwkAlgorithmRegistry {
90 public: 72 public:
91 JwkAlgorithmRegistry() { 73 JwkAlgorithmRegistry() {
92 // TODO(eroman): 74 // TODO(eroman):
93 // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-20 75 // 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 76 // says HMAC with SHA-2 should have a key size at least as large as the
95 // hash output. 77 // hash output.
96 alg_to_info_["HS256"] = JwkAlgorithmInfo( 78 alg_to_info_["HS256"] = JwkAlgorithmInfo(
97 &BindAlgorithmId<webcrypto::CreateHmacAlgorithmByHashId, 79 &BindAlgorithmId<CreateHmacAlgorithmByHashId,
98 blink::WebCryptoAlgorithmIdSha256>); 80 blink::WebCryptoAlgorithmIdSha256>);
99 alg_to_info_["HS384"] = JwkAlgorithmInfo( 81 alg_to_info_["HS384"] = JwkAlgorithmInfo(
100 &BindAlgorithmId<webcrypto::CreateHmacAlgorithmByHashId, 82 &BindAlgorithmId<CreateHmacAlgorithmByHashId,
101 blink::WebCryptoAlgorithmIdSha384>); 83 blink::WebCryptoAlgorithmIdSha384>);
102 alg_to_info_["HS512"] = JwkAlgorithmInfo( 84 alg_to_info_["HS512"] = JwkAlgorithmInfo(
103 &BindAlgorithmId<webcrypto::CreateHmacAlgorithmByHashId, 85 &BindAlgorithmId<CreateHmacAlgorithmByHashId,
104 blink::WebCryptoAlgorithmIdSha512>); 86 blink::WebCryptoAlgorithmIdSha512>);
105 alg_to_info_["RS256"] = JwkAlgorithmInfo( 87 alg_to_info_["RS256"] = JwkAlgorithmInfo(
106 &BindAlgorithmId<webcrypto::CreateRsaSsaAlgorithm, 88 &BindAlgorithmId<CreateRsaSsaAlgorithm,
107 blink::WebCryptoAlgorithmIdSha256>); 89 blink::WebCryptoAlgorithmIdSha256>);
108 alg_to_info_["RS384"] = JwkAlgorithmInfo( 90 alg_to_info_["RS384"] = JwkAlgorithmInfo(
109 &BindAlgorithmId<webcrypto::CreateRsaSsaAlgorithm, 91 &BindAlgorithmId<CreateRsaSsaAlgorithm,
110 blink::WebCryptoAlgorithmIdSha384>); 92 blink::WebCryptoAlgorithmIdSha384>);
111 alg_to_info_["RS512"] = JwkAlgorithmInfo( 93 alg_to_info_["RS512"] = JwkAlgorithmInfo(
112 &BindAlgorithmId<webcrypto::CreateRsaSsaAlgorithm, 94 &BindAlgorithmId<CreateRsaSsaAlgorithm,
113 blink::WebCryptoAlgorithmIdSha512>); 95 blink::WebCryptoAlgorithmIdSha512>);
114 alg_to_info_["RSA1_5"] = JwkAlgorithmInfo( 96 alg_to_info_["RSA1_5"] = JwkAlgorithmInfo(
115 &BindAlgorithmId<webcrypto::CreateAlgorithm, 97 &BindAlgorithmId<CreateAlgorithm,
116 blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5>); 98 blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5>);
117 alg_to_info_["RSA-OAEP"] = JwkAlgorithmInfo( 99 alg_to_info_["RSA-OAEP"] = JwkAlgorithmInfo(
118 &BindAlgorithmId<webcrypto::CreateRsaOaepAlgorithm, 100 &BindAlgorithmId<CreateRsaOaepAlgorithm,
119 blink::WebCryptoAlgorithmIdSha1>); 101 blink::WebCryptoAlgorithmIdSha1>);
120 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 128 yet 102 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 128 yet
121 alg_to_info_["A128KW"] = 103 alg_to_info_["A128KW"] =
122 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 128); 104 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 128);
123 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 256 yet 105 // TODO(padolph): The Web Crypto spec does not enumerate AES-KW 256 yet
124 alg_to_info_["A256KW"] = 106 alg_to_info_["A256KW"] =
125 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 256); 107 JwkAlgorithmInfo(&blink::WebCryptoAlgorithm::createNull, 256);
126 alg_to_info_["A128GCM"] = JwkAlgorithmInfo( 108 alg_to_info_["A128GCM"] = JwkAlgorithmInfo(
127 &BindAlgorithmId<webcrypto::CreateAlgorithm, 109 &BindAlgorithmId<CreateAlgorithm,
128 blink::WebCryptoAlgorithmIdAesGcm>, 128); 110 blink::WebCryptoAlgorithmIdAesGcm>, 128);
129 alg_to_info_["A256GCM"] = JwkAlgorithmInfo( 111 alg_to_info_["A256GCM"] = JwkAlgorithmInfo(
130 &BindAlgorithmId<webcrypto::CreateAlgorithm, 112 &BindAlgorithmId<CreateAlgorithm,
131 blink::WebCryptoAlgorithmIdAesGcm>, 256); 113 blink::WebCryptoAlgorithmIdAesGcm>, 256);
132 alg_to_info_["A128CBC"] = JwkAlgorithmInfo( 114 alg_to_info_["A128CBC"] = JwkAlgorithmInfo(
133 &BindAlgorithmId<webcrypto::CreateAlgorithm, 115 &BindAlgorithmId<CreateAlgorithm,
134 blink::WebCryptoAlgorithmIdAesCbc>, 128); 116 blink::WebCryptoAlgorithmIdAesCbc>, 128);
135 alg_to_info_["A192CBC"] = JwkAlgorithmInfo( 117 alg_to_info_["A192CBC"] = JwkAlgorithmInfo(
136 &BindAlgorithmId<webcrypto::CreateAlgorithm, 118 &BindAlgorithmId<CreateAlgorithm,
137 blink::WebCryptoAlgorithmIdAesCbc>, 192); 119 blink::WebCryptoAlgorithmIdAesCbc>, 192);
138 alg_to_info_["A256CBC"] = JwkAlgorithmInfo( 120 alg_to_info_["A256CBC"] = JwkAlgorithmInfo(
139 &BindAlgorithmId<webcrypto::CreateAlgorithm, 121 &BindAlgorithmId<CreateAlgorithm,
140 blink::WebCryptoAlgorithmIdAesCbc>, 256); 122 blink::WebCryptoAlgorithmIdAesCbc>, 256);
141 } 123 }
142 124
143 // Returns NULL if the algorithm name was not registered. 125 // Returns NULL if the algorithm name was not registered.
144 const JwkAlgorithmInfo* GetAlgorithmInfo(const std::string& jwk_alg) const { 126 const JwkAlgorithmInfo* GetAlgorithmInfo(const std::string& jwk_alg) const {
145 const JwkAlgorithmInfoMap::const_iterator pos = alg_to_info_.find(jwk_alg); 127 const JwkAlgorithmInfoMap::const_iterator pos = alg_to_info_.find(jwk_alg);
146 if (pos == alg_to_info_.end()) 128 if (pos == alg_to_info_.end())
147 return NULL; 129 return NULL;
148 return &pos->second; 130 return &pos->second;
149 } 131 }
(...skipping 18 matching lines...) Expand all
168 const blink::WebCryptoAlgorithm& alg2) { 150 const blink::WebCryptoAlgorithm& alg2) {
169 DCHECK(!alg1.isNull()); 151 DCHECK(!alg1.isNull());
170 DCHECK(!alg2.isNull()); 152 DCHECK(!alg2.isNull());
171 if (alg1.id() != alg2.id()) 153 if (alg1.id() != alg2.id())
172 return false; 154 return false;
173 switch (alg1.id()) { 155 switch (alg1.id()) {
174 case blink::WebCryptoAlgorithmIdHmac: 156 case blink::WebCryptoAlgorithmIdHmac:
175 case blink::WebCryptoAlgorithmIdRsaOaep: 157 case blink::WebCryptoAlgorithmIdRsaOaep:
176 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: 158 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
177 if (WebCryptoAlgorithmsConsistent( 159 if (WebCryptoAlgorithmsConsistent(
178 webcrypto::GetInnerHashAlgorithm(alg1), 160 GetInnerHashAlgorithm(alg1),
179 webcrypto::GetInnerHashAlgorithm(alg2))) { 161 GetInnerHashAlgorithm(alg2))) {
180 return true; 162 return true;
181 } 163 }
182 break; 164 break;
183 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: 165 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
184 case blink::WebCryptoAlgorithmIdSha1: 166 case blink::WebCryptoAlgorithmIdSha1:
185 case blink::WebCryptoAlgorithmIdSha224: 167 case blink::WebCryptoAlgorithmIdSha224:
186 case blink::WebCryptoAlgorithmIdSha256: 168 case blink::WebCryptoAlgorithmIdSha256:
187 case blink::WebCryptoAlgorithmIdSha384: 169 case blink::WebCryptoAlgorithmIdSha384:
188 case blink::WebCryptoAlgorithmIdSha512: 170 case blink::WebCryptoAlgorithmIdSha512:
189 case blink::WebCryptoAlgorithmIdAesCbc: 171 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 217 // 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. 218 // not a string, or could not be base64-decoded, returns an error.
237 Status GetJwkBytes(base::DictionaryValue* dict, 219 Status GetJwkBytes(base::DictionaryValue* dict,
238 const std::string& path, 220 const std::string& path,
239 std::string* result) { 221 std::string* result) {
240 std::string base64_string; 222 std::string base64_string;
241 Status status = GetJwkString(dict, path, &base64_string); 223 Status status = GetJwkString(dict, path, &base64_string);
242 if (status.IsError()) 224 if (status.IsError())
243 return status; 225 return status;
244 226
245 if (!webcrypto::Base64DecodeUrlSafe(base64_string, result)) 227 if (!Base64DecodeUrlSafe(base64_string, result))
246 return Status::ErrorJwkBase64Decode(path); 228 return Status::ErrorJwkBase64Decode(path);
247 229
248 return Status::Success(); 230 return Status::Success();
249 } 231 }
250 232
251 // Extracts the optional boolean property with key |path| from |dict| and saves 233 // 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 234 // 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 235 // boolean, returns an error. Otherwise returns success, and sets
254 // |*property_exists| if it was found. 236 // |*property_exists| if it was found.
255 Status GetOptionalJwkBool(base::DictionaryValue* dict, 237 Status GetOptionalJwkBool(base::DictionaryValue* dict,
256 const std::string& path, 238 const std::string& path,
257 bool* result, 239 bool* result,
258 bool* property_exists) { 240 bool* property_exists) {
259 *property_exists = false; 241 *property_exists = false;
260 base::Value* value = NULL; 242 base::Value* value = NULL;
261 if (!dict->Get(path, &value)) 243 if (!dict->Get(path, &value))
262 return Status::Success(); 244 return Status::Success();
263 245
264 if (!value->GetAsBoolean(result)) 246 if (!value->GetAsBoolean(result))
265 return Status::ErrorJwkPropertyWrongType(path, "boolean"); 247 return Status::ErrorJwkPropertyWrongType(path, "boolean");
266 248
267 *property_exists = true; 249 *property_exists = true;
268 return Status::Success(); 250 return Status::Success();
269 } 251 }
270 252
271 } // namespace 253 } // namespace
272 254
273 WebCryptoImpl::WebCryptoImpl() { 255 Status PlatformCrypto::ImportKeyJwk(
274 Init(); 256 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, 257 const blink::WebCryptoAlgorithm& algorithm_or_null,
366 bool extractable, 258 bool extractable,
367 blink::WebCryptoKeyUsageMask usage_mask, 259 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) { 260 blink::WebCryptoKey* key) {
454 261
455 // The goal of this method is to extract key material and meta data from the 262 // 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 263 // incoming JWK, combine them with the input parameters, and ultimately import
457 // a Web Crypto Key. 264 // a Web Crypto Key.
458 // 265 //
459 // JSON Web Key Format (JWK) 266 // JSON Web Key Format (JWK)
460 // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-16 267 // 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 268 // TODO(padolph): Not all possible values are handled by this code right now
462 // 269 //
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 // Web Crypto Key non-extractable. Conversely, if the JWK extractable is 387 // 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 388 // false but the input parameter is true, it is an inconsistency. If both
582 // are true or both are false, use that value. 389 // are true or both are false, use that value.
583 // 390 //
584 // usage_mask 391 // usage_mask
585 // The input usage_mask must be a strict subset of the interpreted JWK use 392 // 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 393 // value, else it is judged inconsistent. In all cases the input usage_mask
587 // is used as the final usage_mask. 394 // is used as the final usage_mask.
588 // 395 //
589 396
590 if (!key_data_size) 397 if (!key_data.byte_length())
591 return Status::ErrorImportEmptyKeyData(); 398 return Status::ErrorImportEmptyKeyData();
592 DCHECK(key); 399 DCHECK(key);
593 400
594 // Parse the incoming JWK JSON. 401 // Parse the incoming JWK JSON.
595 base::StringPiece json_string(reinterpret_cast<const char*>(key_data), 402 base::StringPiece json_string(reinterpret_cast<const char*>(key_data.bytes()),
596 key_data_size); 403 key_data.byte_length());
597 scoped_ptr<base::Value> value(base::JSONReader::Read(json_string)); 404 scoped_ptr<base::Value> value(base::JSONReader::Read(json_string));
598 // Note, bare pointer dict_value is ok since it points into scoped value. 405 // Note, bare pointer dict_value is ok since it points into scoped value.
599 base::DictionaryValue* dict_value = NULL; 406 base::DictionaryValue* dict_value = NULL;
600 if (!value.get() || !value->GetAsDictionary(&dict_value) || !dict_value) 407 if (!value.get() || !value->GetAsDictionary(&dict_value) || !dict_value)
601 return Status::ErrorJwkNotDictionary(); 408 return Status::ErrorJwkNotDictionary();
602 409
603 // JWK "kty". Exit early if this required JWK parameter is missing. 410 // JWK "kty". Exit early if this required JWK parameter is missing.
604 std::string jwk_kty_value; 411 std::string jwk_kty_value;
605 Status status = GetJwkString(dict_value, "kty", &jwk_kty_value); 412 Status status = GetJwkString(dict_value, "kty", &jwk_kty_value);
606 if (status.IsError()) 413 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 515 // string. For example "A128CBC" implies the JWK carries 128 bits
709 // of key material. For such keys validate that enough bytes were provided. 516 // 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 517 // 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 518 // different algorithm by passing a different lengthed key, since that is
712 // how WebCrypto interprets things. 519 // how WebCrypto interprets things.
713 if (algorithm_info && 520 if (algorithm_info &&
714 algorithm_info->IsInvalidKeyByteLength(jwk_k_value.size())) { 521 algorithm_info->IsInvalidKeyByteLength(jwk_k_value.size())) {
715 return Status::ErrorJwkIncorrectKeyLength(); 522 return Status::ErrorJwkIncorrectKeyLength();
716 } 523 }
717 524
718 return ImportKeyInternal(blink::WebCryptoKeyFormatRaw, 525 return ImportKey(blink::WebCryptoKeyFormatRaw,
719 reinterpret_cast<const uint8*>(jwk_k_value.data()), 526 jwk_k_value,
720 jwk_k_value.size(), 527 algorithm,
721 algorithm, 528 extractable,
722 extractable, 529 usage_mask,
723 usage_mask, 530 key);
724 key);
725 } else if (jwk_kty_value == "RSA") { 531 } else if (jwk_kty_value == "RSA") {
726 532
727 // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry 533 // 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" 534 // in the JWK, while an RSA private key must have those, plus at least a "d"
729 // (private exponent) entry. 535 // (private exponent) entry.
730 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, 536 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
731 // section 6.3. 537 // section 6.3.
732 538
733 // RSA private key import is not currently supported, so fail here if a "d" 539 // RSA private key import is not currently supported, so fail here if a "d"
734 // entry is found. 540 // entry is found.
735 // TODO(padolph): Support RSA private key import. 541 // TODO(padolph): Support RSA private key import.
736 if (dict_value->HasKey("d")) 542 if (dict_value->HasKey("d"))
737 return Status::ErrorJwkRsaPrivateKeyUnsupported(); 543 return Status::ErrorJwkRsaPrivateKeyUnsupported();
738 544
739 std::string jwk_n_value; 545 std::string jwk_n_value;
740 status = GetJwkBytes(dict_value, "n", &jwk_n_value); 546 status = GetJwkBytes(dict_value, "n", &jwk_n_value);
741 if (status.IsError()) 547 if (status.IsError())
742 return status; 548 return status;
743 std::string jwk_e_value; 549 std::string jwk_e_value;
744 status = GetJwkBytes(dict_value, "e", &jwk_e_value); 550 status = GetJwkBytes(dict_value, "e", &jwk_e_value);
745 if (status.IsError()) 551 if (status.IsError())
746 return status; 552 return status;
747 553
748 return ImportRsaPublicKeyInternal( 554 return PlatformImportRsaPublicKey(jwk_n_value,
749 reinterpret_cast<const uint8*>(jwk_n_value.data()), 555 jwk_e_value,
750 jwk_n_value.size(), 556 algorithm,
751 reinterpret_cast<const uint8*>(jwk_e_value.data()), 557 extractable,
752 jwk_e_value.size(), 558 usage_mask,
753 algorithm, 559 key);
754 extractable,
755 usage_mask,
756 key);
757 560
758 } else { 561 } else {
759 return Status::ErrorJwkUnrecognizedKty(); 562 return Status::ErrorJwkUnrecognizedKty();
760 } 563 }
761 564
762 return Status::Success(); 565 return Status::Success();
763 } 566 }
764 567
568 } // namespace webcrypto
569
765 } // namespace content 570 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698