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

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: 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 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 return platform::ImportKeyPkcs8( 479 return platform::ImportKeyPkcs8(
403 algorithm_or_null, key_data, extractable, usage_mask, key); 480 algorithm_or_null, key_data, extractable, usage_mask, key);
404 case blink::WebCryptoKeyFormatJwk: 481 case blink::WebCryptoKeyFormatJwk:
405 return ImportKeyJwk( 482 return ImportKeyJwk(
406 key_data, algorithm_or_null, extractable, usage_mask, key); 483 key_data, algorithm_or_null, extractable, usage_mask, key);
407 default: 484 default:
408 return Status::ErrorUnsupported(); 485 return Status::ErrorUnsupported();
409 } 486 }
410 } 487 }
411 488
412 Status ExportKey(blink::WebCryptoKeyFormat format, 489 // TODO(eroman): Move this to anonymous namespace.
413 const blink::WebCryptoKey& key, 490 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format,
414 blink::WebArrayBuffer* buffer) { 491 const blink::WebCryptoKey& key,
415 if (!key.extractable()) 492 blink::WebArrayBuffer* buffer) {
416 return Status::ErrorKeyNotExtractable();
417
418 switch (format) { 493 switch (format) {
419 case blink::WebCryptoKeyFormatRaw: { 494 case blink::WebCryptoKeyFormatRaw: {
420 platform::SymKey* sym_key; 495 platform::SymKey* sym_key;
421 Status status = ToPlatformSymKey(key, &sym_key); 496 Status status = ToPlatformSymKey(key, &sym_key);
422 if (status.IsError()) 497 if (status.IsError())
423 return status; 498 return status;
424 return platform::ExportKeyRaw(sym_key, buffer); 499 return platform::ExportKeyRaw(sym_key, buffer);
425 } 500 }
426 case blink::WebCryptoKeyFormatSpki: { 501 case blink::WebCryptoKeyFormatSpki: {
427 platform::PublicKey* public_key; 502 platform::PublicKey* public_key;
428 Status status = ToPlatformPublicKey(key, &public_key); 503 Status status = ToPlatformPublicKey(key, &public_key);
429 if (status.IsError()) 504 if (status.IsError())
430 return status; 505 return status;
431 return platform::ExportKeySpki(public_key, buffer); 506 return platform::ExportKeySpki(public_key, buffer);
432 } 507 }
433 case blink::WebCryptoKeyFormatPkcs8: 508 case blink::WebCryptoKeyFormatPkcs8:
434 case blink::WebCryptoKeyFormatJwk: 509 case blink::WebCryptoKeyFormatJwk:
435 // TODO(eroman): 510 // TODO(eroman):
436 return Status::ErrorUnsupported(); 511 return Status::ErrorUnsupported();
437 default: 512 default:
438 return Status::ErrorUnsupported(); 513 return Status::ErrorUnsupported();
439 } 514 }
440 } 515 }
441 516
517 Status ExportKey(blink::WebCryptoKeyFormat format,
518 const blink::WebCryptoKey& key,
519 blink::WebArrayBuffer* buffer) {
520 if (!key.extractable())
521 return Status::ErrorKeyNotExtractable();
522 return ExportKeyDontCheckExtractability(format, key, buffer);
523 }
524
442 Status Sign(const blink::WebCryptoAlgorithm& algorithm, 525 Status Sign(const blink::WebCryptoAlgorithm& algorithm,
443 const blink::WebCryptoKey& key, 526 const blink::WebCryptoKey& key,
444 const CryptoData& data, 527 const CryptoData& data,
445 blink::WebArrayBuffer* buffer) { 528 blink::WebArrayBuffer* buffer) {
446 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign)) 529 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign))
447 return Status::ErrorUnexpected(); 530 return Status::ErrorUnexpected();
448 if (algorithm.id() != key.algorithm().id()) 531 if (algorithm.id() != key.algorithm().id())
449 return Status::ErrorUnexpected(); 532 return Status::ErrorUnexpected();
450 533
451 switch (algorithm.id()) { 534 switch (algorithm.id()) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 algorithm_or_null, 646 algorithm_or_null,
564 extractable, 647 extractable,
565 usage_mask, 648 usage_mask,
566 key); 649 key);
567 } 650 }
568 default: 651 default:
569 return Status::ErrorUnsupported(); 652 return Status::ErrorUnsupported();
570 } 653 }
571 } 654 }
572 655
656 Status SerializeKeyForClone(const blink::WebCryptoKey& key,
657 blink::WebVector<unsigned char>* data) {
658 blink::WebArrayBuffer buffer;
659 Status status = ExportKeyDontCheckExtractability(
660 GetCloneFormatForKeyType(key.type()), key, &buffer);
661 if (status.IsError())
662 return status;
663 *data = blink::WebVector<unsigned char>(
664 reinterpret_cast<unsigned char*>(buffer.data()), buffer.byteLength());
Ryan Sleevi 2014/03/12 23:18:41 This seems to follow a double-allocation strategy
eroman 2014/03/13 00:32:33 Changed to data->assign() Oops, not sure what tha
665 return Status::Success();
666 }
667
668 Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
669 blink::WebCryptoKeyType type,
670 bool extractable,
671 blink::WebCryptoKeyUsageMask usage_mask,
672 const CryptoData& key_data,
673 blink::WebCryptoKey* key) {
674 Status status = ImportKey(GetCloneFormatForKeyType(type),
675 key_data,
676 KeyAlgorithmToImportAlgorithm(algorithm),
677 extractable,
678 usage_mask,
679 key);
680 if (status.IsError())
681 return status;
682
683 return ValidateDeserializedKey(*key, algorithm, type);
684 }
685
573 } // namespace webcrypto 686 } // namespace webcrypto
574 687
575 } // namespace content 688 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698