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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 |
OLD | NEW |