OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |