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

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

Issue 196513002: [webcrypto] Implement structured clone of keys (chromium-side). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase and add header for WebVector 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 "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"
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 return Status::Error(); 226 return Status::Error();
227 // Fallthrough intentional! 227 // Fallthrough intentional!
228 case blink::WebCryptoAlgorithmIdHmac: 228 case blink::WebCryptoAlgorithmIdHmac:
229 return platform::ImportKeyRaw( 229 return platform::ImportKeyRaw(
230 algorithm_or_null, key_data, extractable, usage_mask, key); 230 algorithm_or_null, key_data, extractable, usage_mask, key);
231 default: 231 default:
232 return Status::ErrorUnsupported(); 232 return Status::ErrorUnsupported();
233 } 233 }
234 } 234 }
235 235
236 // Returns the key format to use for structured cloning.
237 blink::WebCryptoKeyFormat GetCloneFormatForKeyType(
238 blink::WebCryptoKeyType type) {
239 switch (type) {
240 case blink::WebCryptoKeyTypeSecret:
241 return blink::WebCryptoKeyFormatRaw;
242 case blink::WebCryptoKeyTypePublic:
243 return blink::WebCryptoKeyFormatSpki;
244 case blink::WebCryptoKeyTypePrivate:
245 return blink::WebCryptoKeyFormatPkcs8;
246 }
247
248 NOTREACHED();
249 return blink::WebCryptoKeyFormatRaw;
250 }
251
252 // Converts a KeyAlgorithm into an equivalent Algorithm for import.
253 blink::WebCryptoAlgorithm KeyAlgorithmToImportAlgorithm(
254 const blink::WebCryptoKeyAlgorithm& algorithm) {
255 switch (algorithm.paramsType()) {
256 case blink::WebCryptoKeyAlgorithmParamsTypeAes:
257 case blink::WebCryptoKeyAlgorithmParamsTypeRsa:
258 return CreateAlgorithm(algorithm.id());
259 case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
260 return CreateHmacImportAlgorithm(algorithm.hmacParams()->hash().id());
261 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
262 return CreateRsaHashedImportAlgorithm(
263 algorithm.id(), algorithm.rsaHashedParams()->hash().id());
264 case blink::WebCryptoKeyAlgorithmParamsTypeNone:
265 break;
266 }
267 return blink::WebCryptoAlgorithm::createNull();
268 }
269
270 // There is some duplicated information in the serialized format used by
271 // structured clone (since the KeyAlgorithm is serialized separately from the
272 // key data). Use this extra information to further validate what was
273 // deserialized from the key data.
274 //
275 // A failure here implies either a bug in the code, or that the serialized data
276 // was corrupted.
277 Status ValidateDeserializedKey(const blink::WebCryptoKey& key,
278 const blink::WebCryptoKeyAlgorithm& algorithm,
279 blink::WebCryptoKeyType type) {
280 if (algorithm.id() != key.algorithm().id())
281 return Status::ErrorUnexpected();
282
283 if (key.type() != type)
284 return Status::ErrorUnexpected();
285
286 switch (algorithm.paramsType()) {
287 case blink::WebCryptoKeyAlgorithmParamsTypeAes:
288 if (algorithm.aesParams()->lengthBits() !=
289 key.algorithm().aesParams()->lengthBits())
290 return Status::ErrorUnexpected();
291 break;
292 case blink::WebCryptoKeyAlgorithmParamsTypeRsa:
293 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
294 if (algorithm.rsaParams()->modulusLengthBits() !=
295 key.algorithm().rsaParams()->modulusLengthBits())
296 return Status::ErrorUnexpected();
297 if (algorithm.rsaParams()->publicExponent().size() !=
298 key.algorithm().rsaParams()->publicExponent().size())
299 return Status::ErrorUnexpected();
300 if (memcmp(algorithm.rsaParams()->publicExponent().data(),
301 key.algorithm().rsaParams()->publicExponent().data(),
302 key.algorithm().rsaParams()->publicExponent().size()) != 0)
303 return Status::ErrorUnexpected();
304 break;
305 case blink::WebCryptoKeyAlgorithmParamsTypeNone:
306 case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
307 break;
308 }
309
310 return Status::Success();
311 }
312
236 } // namespace 313 } // namespace
237 314
238 void Init() { platform::Init(); } 315 void Init() { platform::Init(); }
239 316
240 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, 317 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
241 const blink::WebCryptoKey& key, 318 const blink::WebCryptoKey& key,
242 const CryptoData& data, 319 const CryptoData& data,
243 blink::WebArrayBuffer* buffer) { 320 blink::WebArrayBuffer* buffer) {
244 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt)) 321 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt))
245 return Status::ErrorUnexpected(); 322 return Status::ErrorUnexpected();
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 return platform::ImportKeyPkcs8( 473 return platform::ImportKeyPkcs8(
397 algorithm_or_null, key_data, extractable, usage_mask, key); 474 algorithm_or_null, key_data, extractable, usage_mask, key);
398 case blink::WebCryptoKeyFormatJwk: 475 case blink::WebCryptoKeyFormatJwk:
399 return ImportKeyJwk( 476 return ImportKeyJwk(
400 key_data, algorithm_or_null, extractable, usage_mask, key); 477 key_data, algorithm_or_null, extractable, usage_mask, key);
401 default: 478 default:
402 return Status::ErrorUnsupported(); 479 return Status::ErrorUnsupported();
403 } 480 }
404 } 481 }
405 482
406 Status ExportKey(blink::WebCryptoKeyFormat format, 483 // TODO(eroman): Move this to anonymous namespace.
407 const blink::WebCryptoKey& key, 484 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format,
408 blink::WebArrayBuffer* buffer) { 485 const blink::WebCryptoKey& key,
409 if (!key.extractable()) 486 blink::WebArrayBuffer* buffer) {
410 return Status::ErrorKeyNotExtractable();
411
412 switch (format) { 487 switch (format) {
413 case blink::WebCryptoKeyFormatRaw: { 488 case blink::WebCryptoKeyFormatRaw: {
414 platform::SymKey* sym_key; 489 platform::SymKey* sym_key;
415 Status status = ToPlatformSymKey(key, &sym_key); 490 Status status = ToPlatformSymKey(key, &sym_key);
416 if (status.IsError()) 491 if (status.IsError())
417 return status; 492 return status;
418 return platform::ExportKeyRaw(sym_key, buffer); 493 return platform::ExportKeyRaw(sym_key, buffer);
419 } 494 }
420 case blink::WebCryptoKeyFormatSpki: { 495 case blink::WebCryptoKeyFormatSpki: {
421 platform::PublicKey* public_key; 496 platform::PublicKey* public_key;
422 Status status = ToPlatformPublicKey(key, &public_key); 497 Status status = ToPlatformPublicKey(key, &public_key);
423 if (status.IsError()) 498 if (status.IsError())
424 return status; 499 return status;
425 return platform::ExportKeySpki(public_key, buffer); 500 return platform::ExportKeySpki(public_key, buffer);
426 } 501 }
427 case blink::WebCryptoKeyFormatPkcs8: 502 case blink::WebCryptoKeyFormatPkcs8:
428 case blink::WebCryptoKeyFormatJwk: 503 case blink::WebCryptoKeyFormatJwk:
429 // TODO(eroman): 504 // TODO(eroman):
430 return Status::ErrorUnsupported(); 505 return Status::ErrorUnsupported();
431 default: 506 default:
432 return Status::ErrorUnsupported(); 507 return Status::ErrorUnsupported();
433 } 508 }
434 } 509 }
435 510
511 Status ExportKey(blink::WebCryptoKeyFormat format,
512 const blink::WebCryptoKey& key,
513 blink::WebArrayBuffer* buffer) {
514 if (!key.extractable())
515 return Status::ErrorKeyNotExtractable();
516 return ExportKeyDontCheckExtractability(format, key, buffer);
517 }
518
436 Status Sign(const blink::WebCryptoAlgorithm& algorithm, 519 Status Sign(const blink::WebCryptoAlgorithm& algorithm,
437 const blink::WebCryptoKey& key, 520 const blink::WebCryptoKey& key,
438 const CryptoData& data, 521 const CryptoData& data,
439 blink::WebArrayBuffer* buffer) { 522 blink::WebArrayBuffer* buffer) {
440 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign)) 523 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign))
441 return Status::ErrorUnexpected(); 524 return Status::ErrorUnexpected();
442 if (algorithm.id() != key.algorithm().id()) 525 if (algorithm.id() != key.algorithm().id())
443 return Status::ErrorUnexpected(); 526 return Status::ErrorUnexpected();
444 527
445 switch (algorithm.id()) { 528 switch (algorithm.id()) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 algorithm_or_null, 663 algorithm_or_null,
581 extractable, 664 extractable,
582 usage_mask, 665 usage_mask,
583 key); 666 key);
584 } 667 }
585 default: 668 default:
586 return Status::ErrorUnsupported(); 669 return Status::ErrorUnsupported();
587 } 670 }
588 } 671 }
589 672
673 Status SerializeKeyForClone(const blink::WebCryptoKey& key,
674 blink::WebVector<unsigned char>* data) {
675 blink::WebArrayBuffer buffer;
676 Status status = ExportKeyDontCheckExtractability(
677 GetCloneFormatForKeyType(key.type()), key, &buffer);
678 if (status.IsError())
679 return status;
680 data->assign(
681 reinterpret_cast<unsigned char*>(buffer.data()), buffer.byteLength());
682 return Status::Success();
683 }
684
685 Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
686 blink::WebCryptoKeyType type,
687 bool extractable,
688 blink::WebCryptoKeyUsageMask usage_mask,
689 const CryptoData& key_data,
690 blink::WebCryptoKey* key) {
691 Status status = ImportKey(GetCloneFormatForKeyType(type),
692 key_data,
693 KeyAlgorithmToImportAlgorithm(algorithm),
694 extractable,
695 usage_mask,
696 key);
697 if (status.IsError())
698 return status;
699
700 return ValidateDeserializedKey(*key, algorithm, type);
701 }
702
590 } // namespace webcrypto 703 } // namespace webcrypto
591 704
592 } // namespace content 705 } // namespace content
OLDNEW
« no previous file with comments | « content/child/webcrypto/shared_crypto.h ('k') | content/child/webcrypto/shared_crypto_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698