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

Side by Side Diff: content/child/webcrypto/shared_crypto.cc

Issue 195893034: [webcrypto] Add JWK symmetric key RSAES-PKCS1-v1_5 wrap / unwrap for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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
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 "content/child/webcrypto/shared_crypto.h" 5 #include "content/child/webcrypto/shared_crypto.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "content/child/webcrypto/crypto_data.h" 8 #include "content/child/webcrypto/crypto_data.h"
9 #include "content/child/webcrypto/platform_crypto.h" 9 #include "content/child/webcrypto/platform_crypto.h"
10 #include "content/child/webcrypto/webcrypto_util.h" 10 #include "content/child/webcrypto/webcrypto_util.h"
11 #include "crypto/secure_util.h" 11 #include "crypto/secure_util.h"
12 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" 12 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
13 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" 13 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
14 #include "third_party/WebKit/public/platform/WebCryptoKey.h" 14 #include "third_party/WebKit/public/platform/WebCryptoKey.h"
15 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" 15 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
16 16
17 namespace content { 17 namespace content {
18 18
19 namespace webcrypto { 19 namespace webcrypto {
20 20
21 namespace { 21 namespace {
22 22
23 // TODO(eroman): Move this helper to WebCryptoKey. 23 // TODO(eroman): Move this helper to WebCryptoKey.
24 bool KeyUsageAllows(const blink::WebCryptoKey& key, 24 bool KeyUsageAllows(const blink::WebCryptoKey& key,
25 const blink::WebCryptoKeyUsage usage) { 25 const blink::WebCryptoKeyUsage usage) {
26 return ((key.usages() & usage) != 0); 26 return ((key.usages() & usage) != 0);
27 } 27 }
28 28
29 bool KeyUsageAllowsAnyOf(const blink::WebCryptoKey& key,
eroman 2014/03/18 06:18:39 this probably needs to be rebased, these diffs sho
padolph 2014/03/18 17:52:19 'git cl rebase' does not work for me. I get the er
30 const blink::WebCryptoKeyUsageMask usage_mask) {
31 return ((key.usages() & usage_mask) != 0);
32 }
33
34 bool IsValidAesKeyLengthBits(unsigned int length_bits) { 29 bool IsValidAesKeyLengthBits(unsigned int length_bits) {
35 return length_bits == 128 || length_bits == 192 || length_bits == 256; 30 return length_bits == 128 || length_bits == 192 || length_bits == 256;
36 } 31 }
37 32
38 bool IsValidAesKeyLengthBytes(unsigned int length_bytes) { 33 bool IsValidAesKeyLengthBytes(unsigned int length_bytes) {
39 return length_bytes == 16 || length_bytes == 24 || length_bytes == 32; 34 return length_bytes == 16 || length_bytes == 24 || length_bytes == 32;
40 } 35 }
41 36
42 Status ToPlatformSymKey(const blink::WebCryptoKey& key, 37 Status ToPlatformSymKey(const blink::WebCryptoKey& key,
43 platform::SymKey** out) { 38 platform::SymKey** out) {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 algorithm_or_null, 284 algorithm_or_null,
290 extractable, 285 extractable,
291 usage_mask, 286 usage_mask,
292 key); 287 key);
293 } 288 }
294 default: 289 default:
295 return Status::ErrorUnsupported(); 290 return Status::ErrorUnsupported();
296 } 291 }
297 } 292 }
298 293
294 Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key,
295 const blink::WebCryptoKey& key_to_wrap,
296 const blink::WebCryptoAlgorithm& wrapping_algorithm,
297 blink::WebArrayBuffer* buffer) {
298 // A raw key is always a symmetric key.
299 platform::SymKey* platform_key;
300 Status status = ToPlatformSymKey(key_to_wrap, &platform_key);
301 if (status.IsError())
302 return status;
303
304 // TODO(padolph): Handle other wrapping algorithms
305 switch (wrapping_algorithm.id()) {
306 case blink::WebCryptoAlgorithmIdAesKw: {
307 platform::SymKey* platform_wrapping_key;
308 status = ToPlatformSymKey(wrapping_key, &platform_wrapping_key);
309 if (status.IsError())
310 return status;
311 return platform::WrapSymKeyAesKw(
312 platform_wrapping_key, platform_key, buffer);
313 }
314 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: {
315 platform::PublicKey* platform_wrapping_key;
316 status = ToPlatformPublicKey(wrapping_key, &platform_wrapping_key);
317 if (status.IsError())
318 return status;
319 return platform::WrapSymKeyRsaEs(
320 platform_wrapping_key, platform_key, buffer);
321 }
322 default:
323 return Status::ErrorUnsupported();
324 }
325 }
326
299 Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm, 327 Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm,
300 const blink::WebCryptoKey& key, 328 const blink::WebCryptoKey& key,
301 const CryptoData& data, 329 const CryptoData& data,
302 blink::WebArrayBuffer* buffer) { 330 blink::WebArrayBuffer* buffer) {
303 platform::SymKey* sym_key; 331 platform::SymKey* sym_key;
304 Status status = ToPlatformSymKey(key, &sym_key); 332 Status status = ToPlatformSymKey(key, &sym_key);
305 if (status.IsError()) 333 if (status.IsError())
306 return status; 334 return status;
307 status = CheckAesKwInputSize(data); 335 status = CheckAesKwInputSize(data);
308 if (status.IsError()) 336 if (status.IsError())
(...skipping 14 matching lines...) Expand all
323 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer); 351 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer);
324 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: 352 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
325 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); 353 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer);
326 case blink::WebCryptoAlgorithmIdAesKw: 354 case blink::WebCryptoAlgorithmIdAesKw:
327 return DecryptAesKw(algorithm, key, data, buffer); 355 return DecryptAesKw(algorithm, key, data, buffer);
328 default: 356 default:
329 return Status::ErrorUnsupported(); 357 return Status::ErrorUnsupported();
330 } 358 }
331 } 359 }
332 360
361 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm,
362 const blink::WebCryptoKey& key,
363 const CryptoData& data,
364 blink::WebArrayBuffer* buffer) {
365 if (algorithm.id() != key.algorithm().id())
366 return Status::ErrorUnexpected();
367 switch (algorithm.id()) {
368 case blink::WebCryptoAlgorithmIdAesCbc:
369 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer);
370 case blink::WebCryptoAlgorithmIdAesGcm:
371 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer);
372 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
373 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer);
374 default:
375 return Status::ErrorUnsupported();
376 }
377 }
378
333 Status UnwrapKeyDecryptAndImport( 379 Status UnwrapKeyDecryptAndImport(
334 blink::WebCryptoKeyFormat format, 380 blink::WebCryptoKeyFormat format,
335 const CryptoData& wrapped_key_data, 381 const CryptoData& wrapped_key_data,
336 const blink::WebCryptoKey& wrapping_key, 382 const blink::WebCryptoKey& wrapping_key,
337 const blink::WebCryptoAlgorithm& wrapping_algorithm, 383 const blink::WebCryptoAlgorithm& wrapping_algorithm,
338 const blink::WebCryptoAlgorithm& algorithm_or_null, 384 const blink::WebCryptoAlgorithm& algorithm_or_null,
339 bool extractable, 385 bool extractable,
340 blink::WebCryptoKeyUsageMask usage_mask, 386 blink::WebCryptoKeyUsageMask usage_mask,
341 blink::WebCryptoKey* key) { 387 blink::WebCryptoKey* key) {
342 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey))
343 return Status::ErrorUnexpected();
344 blink::WebArrayBuffer buffer; 388 blink::WebArrayBuffer buffer;
345 Status status = DecryptDontCheckKeyUsage( 389 Status status = DecryptDontCheckKeyUsage(
346 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); 390 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer);
347 if (status.IsError()) 391 if (status.IsError())
348 return status; 392 return status;
349 status = ImportKey(format, 393 status = ImportKey(format,
350 CryptoData(buffer), 394 CryptoData(buffer),
351 algorithm_or_null, 395 algorithm_or_null,
352 extractable, 396 extractable,
353 usage_mask, 397 usage_mask,
354 key); 398 key);
355 // NOTE! Returning the details of any ImportKey() failure here would leak 399 // NOTE! Returning the details of any ImportKey() failure here would leak
356 // information about the plaintext internals of the encrypted key. Instead, 400 // information about the plaintext internals of the encrypted key. Instead,
357 // collapse any error into the generic Status::Error(). 401 // collapse any error into the generic Status::Error().
358 return status.IsError() ? Status::Error() : Status::Success(); 402 return status.IsError() ? Status::Error() : Status::Success();
359 } 403 }
360 404
405 Status WrapKeyExportAndEncrypt(
406 blink::WebCryptoKeyFormat format,
407 const blink::WebCryptoKey& wrapping_key,
408 const blink::WebCryptoKey& key_to_wrap,
409 const blink::WebCryptoAlgorithm& wrapping_algorithm,
410 blink::WebArrayBuffer* buffer) {
411 blink::WebArrayBuffer exported_data;
412 Status status = ExportKey(format, key_to_wrap, &exported_data);
413 if (status.IsError())
414 return status;
415 return EncryptDontCheckUsage(
416 wrapping_algorithm, wrapping_key, CryptoData(exported_data), buffer);
417 }
418
361 } // namespace 419 } // namespace
362 420
363 void Init() { platform::Init(); } 421 void Init() { platform::Init(); }
364 422
365 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, 423 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
366 const blink::WebCryptoKey& key, 424 const blink::WebCryptoKey& key,
367 const CryptoData& data, 425 const CryptoData& data,
368 blink::WebArrayBuffer* buffer) { 426 blink::WebArrayBuffer* buffer) {
369 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt)) 427 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt))
370 return Status::ErrorUnexpected(); 428 return Status::ErrorUnexpected();
371 if (algorithm.id() != key.algorithm().id()) 429 return EncryptDontCheckUsage(algorithm, key, data, buffer);
372 return Status::ErrorUnexpected();
373
374 switch (algorithm.id()) {
375 case blink::WebCryptoAlgorithmIdAesCbc:
376 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer);
377 case blink::WebCryptoAlgorithmIdAesGcm:
378 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer);
379 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
380 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer);
381 default:
382 return Status::ErrorUnsupported();
383 }
384 } 430 }
385 431
386 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, 432 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
387 const blink::WebCryptoKey& key, 433 const blink::WebCryptoKey& key,
388 const CryptoData& data, 434 const CryptoData& data,
389 blink::WebArrayBuffer* buffer) { 435 blink::WebArrayBuffer* buffer) {
390 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt)) 436 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt))
391 return Status::ErrorUnexpected(); 437 return Status::ErrorUnexpected();
392 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer); 438 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer);
393 } 439 }
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 default: 639 default:
594 return Status::ErrorUnsupported(); 640 return Status::ErrorUnsupported();
595 } 641 }
596 } 642 }
597 643
598 Status WrapKey(blink::WebCryptoKeyFormat format, 644 Status WrapKey(blink::WebCryptoKeyFormat format,
599 const blink::WebCryptoKey& wrapping_key, 645 const blink::WebCryptoKey& wrapping_key,
600 const blink::WebCryptoKey& key_to_wrap, 646 const blink::WebCryptoKey& key_to_wrap,
601 const blink::WebCryptoAlgorithm& wrapping_algorithm, 647 const blink::WebCryptoAlgorithm& wrapping_algorithm,
602 blink::WebArrayBuffer* buffer) { 648 blink::WebArrayBuffer* buffer) {
603 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey)) 649 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey))
eroman 2014/03/18 06:18:39 hah! these checks are mainly a precaution, since t
padolph 2014/03/18 17:52:19 Was hoping I could sneak this fix in unnoticed ;-)
604 return Status::ErrorUnexpected(); 650 return Status::ErrorUnexpected();
605 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) 651 if (wrapping_algorithm.id() != wrapping_key.algorithm().id())
606 return Status::ErrorUnexpected(); 652 return Status::ErrorUnexpected();
607 653
608 // TODO (padolph): Handle formats other than raw 654 switch (format) {
609 if (format != blink::WebCryptoKeyFormatRaw) 655 case blink::WebCryptoKeyFormatRaw:
610 return Status::ErrorUnsupported(); 656 return WrapKeyRaw(wrapping_key, key_to_wrap, wrapping_algorithm, buffer);
611 // TODO (padolph): Handle key-to-wrap types other than secret/symmetric 657 case blink::WebCryptoKeyFormatJwk:
612 if (key_to_wrap.type() != blink::WebCryptoKeyTypeSecret) 658 return WrapKeyExportAndEncrypt(
613 return Status::ErrorUnsupported(); 659 format, wrapping_key, key_to_wrap, wrapping_algorithm, buffer);
614 660 case blink::WebCryptoKeyFormatSpki:
615 platform::SymKey* platform_key; 661 case blink::WebCryptoKeyFormatPkcs8:
616 Status status = ToPlatformSymKey(key_to_wrap, &platform_key); 662 return Status::ErrorUnsupported(); // TODO(padolph)
617 if (status.IsError())
618 return status;
619
620 // TODO(padolph): Handle other wrapping algorithms
621 switch (wrapping_algorithm.id()) {
622 case blink::WebCryptoAlgorithmIdAesKw: {
623 platform::SymKey* platform_wrapping_key;
624 status = ToPlatformSymKey(wrapping_key, &platform_wrapping_key);
625 if (status.IsError())
626 return status;
627 return platform::WrapSymKeyAesKw(
628 platform_wrapping_key, platform_key, buffer);
629 }
630 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: {
631 platform::PublicKey* platform_wrapping_key;
632 status = ToPlatformPublicKey(wrapping_key, &platform_wrapping_key);
633 if (status.IsError())
634 return status;
635 return platform::WrapSymKeyRsaEs(
636 platform_wrapping_key, platform_key, buffer);
637 }
638 default: 663 default:
664 NOTREACHED();
639 return Status::ErrorUnsupported(); 665 return Status::ErrorUnsupported();
640 } 666 }
641 } 667 }
642 668
643 Status UnwrapKey(blink::WebCryptoKeyFormat format, 669 Status UnwrapKey(blink::WebCryptoKeyFormat format,
644 const CryptoData& wrapped_key_data, 670 const CryptoData& wrapped_key_data,
645 const blink::WebCryptoKey& wrapping_key, 671 const blink::WebCryptoKey& wrapping_key,
646 const blink::WebCryptoAlgorithm& wrapping_algorithm, 672 const blink::WebCryptoAlgorithm& wrapping_algorithm,
647 const blink::WebCryptoAlgorithm& algorithm_or_null, 673 const blink::WebCryptoAlgorithm& algorithm_or_null,
648 bool extractable, 674 bool extractable,
(...skipping 27 matching lines...) Expand all
676 return Status::ErrorUnsupported(); // TODO(padolph) 702 return Status::ErrorUnsupported(); // TODO(padolph)
677 default: 703 default:
678 NOTREACHED(); 704 NOTREACHED();
679 return Status::ErrorUnsupported(); 705 return Status::ErrorUnsupported();
680 } 706 }
681 } 707 }
682 708
683 } // namespace webcrypto 709 } // namespace webcrypto
684 710
685 } // namespace content 711 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698