OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 return true; | 389 return true; |
390 } | 390 } |
391 | 391 |
392 const AlgorithmInfo* lookupAlgorithmInfo(blink::WebCryptoAlgorithmId id) | 392 const AlgorithmInfo* lookupAlgorithmInfo(blink::WebCryptoAlgorithmId id) |
393 { | 393 { |
394 if (id < 0 || id >= WTF_ARRAY_LENGTH(algorithmIdToInfo)) | 394 if (id < 0 || id >= WTF_ARRAY_LENGTH(algorithmIdToInfo)) |
395 return 0; | 395 return 0; |
396 return &algorithmIdToInfo[id]; | 396 return &algorithmIdToInfo[id]; |
397 } | 397 } |
398 | 398 |
| 399 void completeWithSyntaxError(const String& message, CryptoResult* result) |
| 400 { |
| 401 result->completeWithError(blink::WebCryptoErrorTypeSyntax, message); |
| 402 } |
| 403 |
| 404 void completeWithNotSupportedError(const String& message, CryptoResult* result) |
| 405 { |
| 406 result->completeWithError(blink::WebCryptoErrorTypeNotSupported, message); |
| 407 } |
| 408 |
| 409 void completeWithDataError(const String& message, CryptoResult* result) |
| 410 { |
| 411 result->completeWithError(blink::WebCryptoErrorTypeData, message); |
| 412 } |
| 413 |
399 // ErrorContext holds a stack of string literals which describe what was | 414 // ErrorContext holds a stack of string literals which describe what was |
400 // happening at the time the error occurred. This is helpful because | 415 // happening at the time the error occurred. This is helpful because |
401 // parsing of the algorithm dictionary can be recursive and it is difficult to | 416 // parsing of the algorithm dictionary can be recursive and it is difficult to |
402 // tell what went wrong from a failure alone. | 417 // tell what went wrong from a failure alone. |
403 class ErrorContext { | 418 class ErrorContext { |
404 public: | 419 public: |
405 void add(const char* message) | 420 void add(const char* message) |
406 { | 421 { |
407 m_messages.append(message); | 422 m_messages.append(message); |
408 } | 423 } |
409 | 424 |
| 425 void removeLast() |
| 426 { |
| 427 m_messages.removeLast(); |
| 428 } |
| 429 |
410 // Join all of the string literals into a single String. | 430 // Join all of the string literals into a single String. |
411 String toString() const | 431 String toString() const |
412 { | 432 { |
413 if (m_messages.isEmpty()) | 433 if (m_messages.isEmpty()) |
414 return String(); | 434 return String(); |
415 | 435 |
416 StringBuilder result; | 436 StringBuilder result; |
417 const char* Separator = ": "; | 437 const char* Separator = ": "; |
418 | 438 |
419 size_t length = (m_messages.size() - 1) * strlen(Separator); | 439 size_t length = (m_messages.size() - 1) * strlen(Separator); |
(...skipping 29 matching lines...) Expand all Loading... |
449 // This inline size is large enough to avoid having to grow the Vector in | 469 // This inline size is large enough to avoid having to grow the Vector in |
450 // the majority of cases (up to 1 nested algorithm identifier). | 470 // the majority of cases (up to 1 nested algorithm identifier). |
451 Vector<const char*, 10> m_messages; | 471 Vector<const char*, 10> m_messages; |
452 }; | 472 }; |
453 | 473 |
454 // Defined by the WebCrypto spec as: | 474 // Defined by the WebCrypto spec as: |
455 // | 475 // |
456 // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; | 476 // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; |
457 // | 477 // |
458 // FIXME: Currently only supports ArrayBufferView. | 478 // FIXME: Currently only supports ArrayBufferView. |
459 bool getOptionalCryptoOperationData(const Dictionary& raw, const char* propertyN
ame, bool& hasProperty, RefPtr<ArrayBufferView>& buffer, const ErrorContext& con
text, String& errorDetails) | 479 bool getOptionalCryptoOperationData(const Dictionary& raw, const char* propertyN
ame, bool& hasProperty, RefPtr<ArrayBufferView>& buffer, const ErrorContext& con
text, CryptoResult* result) |
460 { | 480 { |
461 if (!raw.get(propertyName, buffer)) { | 481 if (!raw.get(propertyName, buffer)) { |
462 hasProperty = false; | 482 hasProperty = false; |
463 return true; | 483 return true; |
464 } | 484 } |
465 | 485 |
466 hasProperty = true; | 486 hasProperty = true; |
467 | 487 |
468 if (!buffer) { | 488 if (!buffer) { |
469 errorDetails = context.toString(propertyName, "Not an ArrayBufferView"); | 489 completeWithSyntaxError(context.toString(propertyName, "Not an ArrayBuff
erView"), result); |
470 return false; | 490 return false; |
471 } | 491 } |
472 | 492 |
473 return true; | 493 return true; |
474 } | 494 } |
475 | 495 |
476 // Defined by the WebCrypto spec as: | 496 // Defined by the WebCrypto spec as: |
477 // | 497 // |
478 // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; | 498 // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; |
479 // | 499 // |
480 // FIXME: Currently only supports ArrayBufferView. | 500 // FIXME: Currently only supports ArrayBufferView. |
481 bool getCryptoOperationData(const Dictionary& raw, const char* propertyName, Ref
Ptr<ArrayBufferView>& buffer, const ErrorContext& context, String& errorDetails) | 501 bool getCryptoOperationData(const Dictionary& raw, const char* propertyName, Ref
Ptr<ArrayBufferView>& buffer, const ErrorContext& context, CryptoResult* result) |
482 { | 502 { |
483 bool hasProperty; | 503 bool hasProperty; |
484 bool ok = getOptionalCryptoOperationData(raw, propertyName, hasProperty, buf
fer, context, errorDetails); | 504 bool ok = getOptionalCryptoOperationData(raw, propertyName, hasProperty, buf
fer, context, result); |
485 if (!hasProperty) { | 505 if (!hasProperty) { |
486 errorDetails = context.toString(propertyName, "Missing required property
"); | 506 completeWithSyntaxError(context.toString(propertyName, "Missing required
property"), result); |
487 return false; | 507 return false; |
488 } | 508 } |
489 return ok; | 509 return ok; |
490 } | 510 } |
491 | 511 |
492 bool getUint8Array(const Dictionary& raw, const char* propertyName, RefPtr<Uint8
Array>& array, const ErrorContext& context, String& errorDetails) | 512 bool getUint8Array(const Dictionary& raw, const char* propertyName, RefPtr<Uint8
Array>& array, const ErrorContext& context, CryptoResult* result) |
493 { | 513 { |
494 if (!raw.get(propertyName, array) || !array) { | 514 if (!raw.get(propertyName, array) || !array) { |
495 errorDetails = context.toString(propertyName, "Missing or not a Uint8Arr
ay"); | 515 completeWithSyntaxError(context.toString(propertyName, "Missing or not a
Uint8Array"), result); |
496 return false; | 516 return false; |
497 } | 517 } |
498 return true; | 518 return true; |
499 } | 519 } |
500 | 520 |
501 // Defined by the WebCrypto spec as: | 521 // Defined by the WebCrypto spec as: |
502 // | 522 // |
503 // typedef Uint8Array BigInteger; | 523 // typedef Uint8Array BigInteger; |
504 bool getBigInteger(const Dictionary& raw, const char* propertyName, RefPtr<Uint8
Array>& array, const ErrorContext& context, String& errorDetails) | 524 bool getBigInteger(const Dictionary& raw, const char* propertyName, RefPtr<Uint8
Array>& array, const ErrorContext& context, CryptoResult* result) |
505 { | 525 { |
506 if (!getUint8Array(raw, propertyName, array, context, errorDetails)) | 526 if (!getUint8Array(raw, propertyName, array, context, result)) |
507 return false; | 527 return false; |
508 | 528 |
509 if (!array->byteLength()) { | 529 if (!array->byteLength()) { |
510 errorDetails = context.toString(propertyName, "BigInteger should not be
empty"); | 530 completeWithSyntaxError(context.toString(propertyName, "BigInteger shoul
d not be empty"), result); |
511 return false; | 531 return false; |
512 } | 532 } |
513 | 533 |
514 if (!raw.get(propertyName, array) || !array) { | 534 if (!raw.get(propertyName, array) || !array) { |
515 errorDetails = context.toString(propertyName, "Missing or not a Uint8Arr
ay"); | 535 completeWithSyntaxError(context.toString(propertyName, "Missing or not a
Uint8Array"), result); |
516 return false; | 536 return false; |
517 } | 537 } |
518 return true; | 538 return true; |
519 } | 539 } |
520 | 540 |
521 // Gets an integer according to WebIDL's [EnforceRange]. | 541 // Gets an integer according to WebIDL's [EnforceRange]. |
522 bool getOptionalInteger(const Dictionary& raw, const char* propertyName, bool& h
asProperty, double& value, double minValue, double maxValue, const ErrorContext&
context, String& errorDetails) | 542 bool getOptionalInteger(const Dictionary& raw, const char* propertyName, bool& h
asProperty, double& value, double minValue, double maxValue, const ErrorContext&
context, CryptoResult* result) |
523 { | 543 { |
524 double number; | 544 double number; |
525 bool ok = raw.get(propertyName, number, hasProperty); | 545 bool ok = raw.get(propertyName, number, hasProperty); |
526 | 546 |
527 if (!hasProperty) | 547 if (!hasProperty) |
528 return true; | 548 return true; |
529 | 549 |
530 if (!ok || std::isnan(number)) { | 550 if (!ok || std::isnan(number)) { |
531 errorDetails = context.toString(propertyName, "Is not a number"); | 551 completeWithSyntaxError(context.toString(propertyName, "Is not a number"
), result); |
532 return false; | 552 return false; |
533 } | 553 } |
534 | 554 |
535 number = trunc(number); | 555 number = trunc(number); |
536 | 556 |
537 if (std::isinf(number) || number < minValue || number > maxValue) { | 557 if (std::isinf(number) || number < minValue || number > maxValue) { |
538 errorDetails = context.toString(propertyName, "Outside of numeric range"
); | 558 completeWithSyntaxError(context.toString(propertyName, "Outside of numer
ic range"), result); |
539 return false; | 559 return false; |
540 } | 560 } |
541 | 561 |
542 value = number; | 562 value = number; |
543 return true; | 563 return true; |
544 } | 564 } |
545 | 565 |
546 bool getInteger(const Dictionary& raw, const char* propertyName, double& value,
double minValue, double maxValue, const ErrorContext& context, String& errorDeta
ils) | 566 bool getInteger(const Dictionary& raw, const char* propertyName, double& value,
double minValue, double maxValue, const ErrorContext& context, CryptoResult* res
ult) |
547 { | 567 { |
548 bool hasProperty; | 568 bool hasProperty; |
549 if (!getOptionalInteger(raw, propertyName, hasProperty, value, minValue, max
Value, context, errorDetails)) | 569 if (!getOptionalInteger(raw, propertyName, hasProperty, value, minValue, max
Value, context, result)) |
550 return false; | 570 return false; |
551 | 571 |
552 if (!hasProperty) { | 572 if (!hasProperty) { |
553 errorDetails = context.toString(propertyName, "Missing required property
"); | 573 completeWithSyntaxError(context.toString(propertyName, "Missing required
property"), result); |
554 return false; | 574 return false; |
555 } | 575 } |
556 | 576 |
557 return true; | 577 return true; |
558 } | 578 } |
559 | 579 |
560 bool getUint32(const Dictionary& raw, const char* propertyName, uint32_t& value,
const ErrorContext& context, String& errorDetails) | 580 bool getUint32(const Dictionary& raw, const char* propertyName, uint32_t& value,
const ErrorContext& context, CryptoResult* result) |
561 { | 581 { |
562 double number; | 582 double number; |
563 if (!getInteger(raw, propertyName, number, 0, 0xFFFFFFFF, context, errorDeta
ils)) | 583 if (!getInteger(raw, propertyName, number, 0, 0xFFFFFFFF, context, result)) |
564 return false; | 584 return false; |
565 value = number; | 585 value = number; |
566 return true; | 586 return true; |
567 } | 587 } |
568 | 588 |
569 bool getUint16(const Dictionary& raw, const char* propertyName, uint16_t& value,
const ErrorContext& context, String& errorDetails) | 589 bool getUint16(const Dictionary& raw, const char* propertyName, uint16_t& value,
const ErrorContext& context, CryptoResult* result) |
570 { | 590 { |
571 double number; | 591 double number; |
572 if (!getInteger(raw, propertyName, number, 0, 0xFFFF, context, errorDetails)
) | 592 if (!getInteger(raw, propertyName, number, 0, 0xFFFF, context, result)) |
573 return false; | 593 return false; |
574 value = number; | 594 value = number; |
575 return true; | 595 return true; |
576 } | 596 } |
577 | 597 |
578 bool getUint8(const Dictionary& raw, const char* propertyName, uint8_t& value, c
onst ErrorContext& context, String& errorDetails) | 598 bool getUint8(const Dictionary& raw, const char* propertyName, uint8_t& value, c
onst ErrorContext& context, CryptoResult* result) |
579 { | 599 { |
580 double number; | 600 double number; |
581 if (!getInteger(raw, propertyName, number, 0, 0xFF, context, errorDetails)) | 601 if (!getInteger(raw, propertyName, number, 0, 0xFF, context, result)) |
582 return false; | 602 return false; |
583 value = number; | 603 value = number; |
584 return true; | 604 return true; |
585 } | 605 } |
586 | 606 |
587 bool getOptionalUint32(const Dictionary& raw, const char* propertyName, bool& ha
sValue, uint32_t& value, const ErrorContext& context, String& errorDetails) | 607 bool getOptionalUint32(const Dictionary& raw, const char* propertyName, bool& ha
sValue, uint32_t& value, const ErrorContext& context, CryptoResult* result) |
588 { | 608 { |
589 double number; | 609 double number; |
590 if (!getOptionalInteger(raw, propertyName, hasValue, number, 0, 0xFFFFFFFF,
context, errorDetails)) | 610 if (!getOptionalInteger(raw, propertyName, hasValue, number, 0, 0xFFFFFFFF,
context, result)) |
591 return false; | 611 return false; |
592 if (hasValue) | 612 if (hasValue) |
593 value = number; | 613 value = number; |
594 return true; | 614 return true; |
595 } | 615 } |
596 | 616 |
597 // Defined by the WebCrypto spec as: | 617 // Defined by the WebCrypto spec as: |
598 // | 618 // |
599 // dictionary AesCbcParams : Algorithm { | 619 // dictionary AesCbcParams : Algorithm { |
600 // CryptoOperationData iv; | 620 // CryptoOperationData iv; |
601 // }; | 621 // }; |
602 bool parseAesCbcParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa
rams>& params, const ErrorContext& context, String& errorDetails) | 622 bool parseAesCbcParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa
rams>& params, const ErrorContext& context, CryptoResult* result) |
603 { | 623 { |
604 RefPtr<ArrayBufferView> iv; | 624 RefPtr<ArrayBufferView> iv; |
605 if (!getCryptoOperationData(raw, "iv", iv, context, errorDetails)) | 625 if (!getCryptoOperationData(raw, "iv", iv, context, result)) |
606 return false; | 626 return false; |
607 | 627 |
608 if (iv->byteLength() != 16) { | 628 if (iv->byteLength() != 16) { |
609 errorDetails = context.toString("iv", "Must be 16 bytes"); | 629 completeWithDataError(context.toString("iv", "Must be 16 bytes"), result
); |
610 return false; | 630 return false; |
611 } | 631 } |
612 | 632 |
613 params = adoptPtr(new blink::WebCryptoAesCbcParams(static_cast<unsigned char
*>(iv->baseAddress()), iv->byteLength())); | 633 params = adoptPtr(new blink::WebCryptoAesCbcParams(static_cast<unsigned char
*>(iv->baseAddress()), iv->byteLength())); |
614 return true; | 634 return true; |
615 } | 635 } |
616 | 636 |
617 // Defined by the WebCrypto spec as: | 637 // Defined by the WebCrypto spec as: |
618 // | 638 // |
619 // dictionary AesKeyGenParams : Algorithm { | 639 // dictionary AesKeyGenParams : Algorithm { |
620 // [EnforceRange] unsigned short length; | 640 // [EnforceRange] unsigned short length; |
621 // }; | 641 // }; |
622 bool parseAesKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorith
mParams>& params, const ErrorContext& context, String& errorDetails) | 642 bool parseAesKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorith
mParams>& params, const ErrorContext& context, CryptoResult* result) |
623 { | 643 { |
624 uint16_t length; | 644 uint16_t length; |
625 if (!getUint16(raw, "length", length, context, errorDetails)) | 645 if (!getUint16(raw, "length", length, context, result)) |
626 return false; | 646 return false; |
627 | 647 |
628 params = adoptPtr(new blink::WebCryptoAesKeyGenParams(length)); | 648 params = adoptPtr(new blink::WebCryptoAesKeyGenParams(length)); |
629 return true; | 649 return true; |
630 } | 650 } |
631 | 651 |
632 bool parseAlgorithm(const Dictionary&, AlgorithmOperation, blink::WebCryptoAlgor
ithm&, ErrorContext, String&); | 652 bool parseAlgorithm(const Dictionary&, AlgorithmOperation, blink::WebCryptoAlgor
ithm&, ErrorContext, CryptoResult*); |
633 | 653 |
634 bool parseHash(const Dictionary& raw, blink::WebCryptoAlgorithm& hash, ErrorCont
ext context, String& errorDetails) | 654 bool parseHash(const Dictionary& raw, blink::WebCryptoAlgorithm& hash, ErrorCont
ext context, CryptoResult* result) |
635 { | 655 { |
636 Dictionary rawHash; | 656 Dictionary rawHash; |
637 if (!raw.get("hash", rawHash)) { | 657 if (!raw.get("hash", rawHash)) { |
638 errorDetails = context.toString("hash", "Missing or not a dictionary"); | 658 completeWithSyntaxError(context.toString("hash", "Missing or not a dicti
onary"), result); |
639 return false; | 659 return false; |
640 } | 660 } |
641 | 661 |
642 context.add("hash"); | 662 context.add("hash"); |
643 return parseAlgorithm(rawHash, Digest, hash, context, errorDetails); | 663 return parseAlgorithm(rawHash, Digest, hash, context, result); |
644 } | 664 } |
645 | 665 |
646 // Defined by the WebCrypto spec as: | 666 // Defined by the WebCrypto spec as: |
647 // | 667 // |
648 // dictionary HmacImportParams : Algorithm { | 668 // dictionary HmacImportParams : Algorithm { |
649 // AlgorithmIdentifier hash; | 669 // AlgorithmIdentifier hash; |
650 // }; | 670 // }; |
651 bool parseHmacImportParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorit
hmParams>& params, const ErrorContext& context, String& errorDetails) | 671 bool parseHmacImportParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorit
hmParams>& params, const ErrorContext& context, CryptoResult* result) |
652 { | 672 { |
653 blink::WebCryptoAlgorithm hash; | 673 blink::WebCryptoAlgorithm hash; |
654 if (!parseHash(raw, hash, context, errorDetails)) | 674 if (!parseHash(raw, hash, context, result)) |
655 return false; | 675 return false; |
656 | 676 |
657 params = adoptPtr(new blink::WebCryptoHmacImportParams(hash)); | 677 params = adoptPtr(new blink::WebCryptoHmacImportParams(hash)); |
658 return true; | 678 return true; |
659 } | 679 } |
660 | 680 |
661 // Defined by the WebCrypto spec as: | 681 // Defined by the WebCrypto spec as: |
662 // | 682 // |
663 // dictionary HmacKeyGenParams : Algorithm { | 683 // dictionary HmacKeyGenParams : Algorithm { |
664 // AlgorithmIdentifier hash; | 684 // AlgorithmIdentifier hash; |
665 // // The length (in bits) of the key to generate. If unspecified, the | 685 // // The length (in bits) of the key to generate. If unspecified, the |
666 // // recommended length will be used, which is the size of the associated
hash function's block | 686 // // recommended length will be used, which is the size of the associated
hash function's block |
667 // // size. | 687 // // size. |
668 // unsigned long length; | 688 // unsigned long length; |
669 // }; | 689 // }; |
670 bool parseHmacKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorit
hmParams>& params, const ErrorContext& context, String& errorDetails) | 690 bool parseHmacKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorit
hmParams>& params, const ErrorContext& context, CryptoResult* result) |
671 { | 691 { |
672 blink::WebCryptoAlgorithm hash; | 692 blink::WebCryptoAlgorithm hash; |
673 if (!parseHash(raw, hash, context, errorDetails)) | 693 if (!parseHash(raw, hash, context, result)) |
674 return false; | 694 return false; |
675 | 695 |
676 bool hasLength; | 696 bool hasLength; |
677 uint32_t length = 0; | 697 uint32_t length = 0; |
678 if (!getOptionalUint32(raw, "length", hasLength, length, context, errorDetai
ls)) | 698 if (!getOptionalUint32(raw, "length", hasLength, length, context, result)) |
679 return false; | 699 return false; |
680 | 700 |
681 params = adoptPtr(new blink::WebCryptoHmacKeyGenParams(hash, hasLength, leng
th)); | 701 params = adoptPtr(new blink::WebCryptoHmacKeyGenParams(hash, hasLength, leng
th)); |
682 return true; | 702 return true; |
683 } | 703 } |
684 | 704 |
685 // Defined by the WebCrypto spec as: | 705 // Defined by the WebCrypto spec as: |
686 // | 706 // |
687 // dictionary RsaHashedImportParams { | 707 // dictionary RsaHashedImportParams { |
688 // AlgorithmIdentifier hash; | 708 // AlgorithmIdentifier hash; |
689 // }; | 709 // }; |
690 bool parseRsaHashedImportParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAl
gorithmParams>& params, const ErrorContext& context, String& errorDetails) | 710 bool parseRsaHashedImportParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAl
gorithmParams>& params, const ErrorContext& context, CryptoResult* result) |
691 { | 711 { |
692 blink::WebCryptoAlgorithm hash; | 712 blink::WebCryptoAlgorithm hash; |
693 if (!parseHash(raw, hash, context, errorDetails)) | 713 if (!parseHash(raw, hash, context, result)) |
694 return false; | 714 return false; |
695 | 715 |
696 params = adoptPtr(new blink::WebCryptoRsaHashedImportParams(hash)); | 716 params = adoptPtr(new blink::WebCryptoRsaHashedImportParams(hash)); |
697 return true; | 717 return true; |
698 } | 718 } |
699 | 719 |
700 // Defined by the WebCrypto spec as: | 720 // Defined by the WebCrypto spec as: |
701 // | 721 // |
702 // dictionary RsaKeyGenParams : Algorithm { | 722 // dictionary RsaKeyGenParams : Algorithm { |
703 // unsigned long modulusLength; | 723 // unsigned long modulusLength; |
704 // BigInteger publicExponent; | 724 // BigInteger publicExponent; |
705 // }; | 725 // }; |
706 bool parseRsaKeyGenParams(const Dictionary& raw, uint32_t& modulusLength, RefPtr
<Uint8Array>& publicExponent, const ErrorContext& context, String& errorDetails) | 726 bool parseRsaKeyGenParams(const Dictionary& raw, uint32_t& modulusLength, RefPtr
<Uint8Array>& publicExponent, const ErrorContext& context, CryptoResult* result) |
707 { | 727 { |
708 if (!getUint32(raw, "modulusLength", modulusLength, context, errorDetails)) | 728 if (!getUint32(raw, "modulusLength", modulusLength, context, result)) |
709 return false; | 729 return false; |
710 | 730 |
711 if (!getBigInteger(raw, "publicExponent", publicExponent, context, errorDeta
ils)) | 731 if (!getBigInteger(raw, "publicExponent", publicExponent, context, result)) |
712 return false; | 732 return false; |
713 | 733 |
714 return true; | 734 return true; |
715 } | 735 } |
716 | 736 |
717 bool parseRsaKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorith
mParams>& params, const ErrorContext& context, String& errorDetails) | 737 bool parseRsaKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorith
mParams>& params, const ErrorContext& context, CryptoResult* result) |
718 { | 738 { |
719 uint32_t modulusLength; | 739 uint32_t modulusLength; |
720 RefPtr<Uint8Array> publicExponent; | 740 RefPtr<Uint8Array> publicExponent; |
721 if (!parseRsaKeyGenParams(raw, modulusLength, publicExponent, context, error
Details)) | 741 if (!parseRsaKeyGenParams(raw, modulusLength, publicExponent, context, resul
t)) |
722 return false; | 742 return false; |
723 | 743 |
724 params = adoptPtr(new blink::WebCryptoRsaKeyGenParams(modulusLength, static_
cast<const unsigned char*>(publicExponent->baseAddress()), publicExponent->byteL
ength())); | 744 params = adoptPtr(new blink::WebCryptoRsaKeyGenParams(modulusLength, static_
cast<const unsigned char*>(publicExponent->baseAddress()), publicExponent->byteL
ength())); |
725 return true; | 745 return true; |
726 } | 746 } |
727 | 747 |
728 // Defined by the WebCrypto spec as: | 748 // Defined by the WebCrypto spec as: |
729 // | 749 // |
730 // dictionary RsaHashedKeyGenParams : RsaKeyGenParams { | 750 // dictionary RsaHashedKeyGenParams : RsaKeyGenParams { |
731 // AlgorithmIdentifier hash; | 751 // AlgorithmIdentifier hash; |
732 // }; | 752 // }; |
733 bool parseRsaHashedKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAl
gorithmParams>& params, const ErrorContext& context, String& errorDetails) | 753 bool parseRsaHashedKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAl
gorithmParams>& params, const ErrorContext& context, CryptoResult* result) |
734 { | 754 { |
735 uint32_t modulusLength; | 755 uint32_t modulusLength; |
736 RefPtr<Uint8Array> publicExponent; | 756 RefPtr<Uint8Array> publicExponent; |
737 if (!parseRsaKeyGenParams(raw, modulusLength, publicExponent, context, error
Details)) | 757 if (!parseRsaKeyGenParams(raw, modulusLength, publicExponent, context, resul
t)) |
738 return false; | 758 return false; |
739 | 759 |
740 blink::WebCryptoAlgorithm hash; | 760 blink::WebCryptoAlgorithm hash; |
741 if (!parseHash(raw, hash, context, errorDetails)) | 761 if (!parseHash(raw, hash, context, result)) |
742 return false; | 762 return false; |
743 | 763 |
744 params = adoptPtr(new blink::WebCryptoRsaHashedKeyGenParams(hash, modulusLen
gth, static_cast<const unsigned char*>(publicExponent->baseAddress()), publicExp
onent->byteLength())); | 764 params = adoptPtr(new blink::WebCryptoRsaHashedKeyGenParams(hash, modulusLen
gth, static_cast<const unsigned char*>(publicExponent->baseAddress()), publicExp
onent->byteLength())); |
745 return true; | 765 return true; |
746 } | 766 } |
747 | 767 |
748 // Defined by the WebCrypto spec as: | 768 // Defined by the WebCrypto spec as: |
749 // | 769 // |
750 // dictionary AesCtrParams : Algorithm { | 770 // dictionary AesCtrParams : Algorithm { |
751 // CryptoOperationData counter; | 771 // CryptoOperationData counter; |
752 // [EnforceRange] octet length; | 772 // [EnforceRange] octet length; |
753 // }; | 773 // }; |
754 bool parseAesCtrParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa
rams>& params, const ErrorContext& context, String& errorDetails) | 774 bool parseAesCtrParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa
rams>& params, const ErrorContext& context, CryptoResult* result) |
755 { | 775 { |
756 RefPtr<ArrayBufferView> counter; | 776 RefPtr<ArrayBufferView> counter; |
757 if (!getCryptoOperationData(raw, "counter", counter, context, errorDetails)) | 777 if (!getCryptoOperationData(raw, "counter", counter, context, result)) |
758 return false; | 778 return false; |
759 | 779 |
760 uint8_t length; | 780 uint8_t length; |
761 if (!getUint8(raw, "length", length, context, errorDetails)) | 781 if (!getUint8(raw, "length", length, context, result)) |
762 return false; | 782 return false; |
763 | 783 |
764 params = adoptPtr(new blink::WebCryptoAesCtrParams(length, static_cast<const
unsigned char*>(counter->baseAddress()), counter->byteLength())); | 784 params = adoptPtr(new blink::WebCryptoAesCtrParams(length, static_cast<const
unsigned char*>(counter->baseAddress()), counter->byteLength())); |
765 return true; | 785 return true; |
766 } | 786 } |
767 | 787 |
768 // Defined by the WebCrypto spec as: | 788 // Defined by the WebCrypto spec as: |
769 // | 789 // |
770 // dictionary AesGcmParams : Algorithm { | 790 // dictionary AesGcmParams : Algorithm { |
771 // CryptoOperationData iv; | 791 // CryptoOperationData iv; |
772 // CryptoOperationData? additionalData; | 792 // CryptoOperationData? additionalData; |
773 // [EnforceRange] octet? tagLength; // May be 0-128 | 793 // [EnforceRange] octet? tagLength; // May be 0-128 |
774 // } | 794 // } |
775 bool parseAesGcmParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa
rams>& params, const ErrorContext& context, String& errorDetails) | 795 bool parseAesGcmParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa
rams>& params, const ErrorContext& context, CryptoResult* result) |
776 { | 796 { |
777 RefPtr<ArrayBufferView> iv; | 797 RefPtr<ArrayBufferView> iv; |
778 if (!getCryptoOperationData(raw, "iv", iv, context, errorDetails)) | 798 if (!getCryptoOperationData(raw, "iv", iv, context, result)) |
779 return false; | 799 return false; |
780 | 800 |
781 bool hasAdditionalData; | 801 bool hasAdditionalData; |
782 RefPtr<ArrayBufferView> additionalData; | 802 RefPtr<ArrayBufferView> additionalData; |
783 if (!getOptionalCryptoOperationData(raw, "additionalData", hasAdditionalData
, additionalData, context, errorDetails)) | 803 if (!getOptionalCryptoOperationData(raw, "additionalData", hasAdditionalData
, additionalData, context, result)) |
784 return false; | 804 return false; |
785 | 805 |
786 double tagLength; | 806 double tagLength; |
787 bool hasTagLength; | 807 bool hasTagLength; |
788 if (!getOptionalInteger(raw, "tagLength", hasTagLength, tagLength, 0, 128, c
ontext, errorDetails)) | 808 if (!getOptionalInteger(raw, "tagLength", hasTagLength, tagLength, 0, 128, c
ontext, result)) |
789 return false; | 809 return false; |
790 | 810 |
791 const unsigned char* ivStart = static_cast<const unsigned char*>(iv->baseAdd
ress()); | 811 const unsigned char* ivStart = static_cast<const unsigned char*>(iv->baseAdd
ress()); |
792 unsigned ivLength = iv->byteLength(); | 812 unsigned ivLength = iv->byteLength(); |
793 | 813 |
794 const unsigned char* additionalDataStart = hasAdditionalData ? static_cast<c
onst unsigned char*>(additionalData->baseAddress()) : 0; | 814 const unsigned char* additionalDataStart = hasAdditionalData ? static_cast<c
onst unsigned char*>(additionalData->baseAddress()) : 0; |
795 unsigned additionalDataLength = hasAdditionalData ? additionalData->byteLeng
th() : 0; | 815 unsigned additionalDataLength = hasAdditionalData ? additionalData->byteLeng
th() : 0; |
796 | 816 |
797 params = adoptPtr(new blink::WebCryptoAesGcmParams(ivStart, ivLength, hasAdd
itionalData, additionalDataStart, additionalDataLength, hasTagLength, tagLength)
); | 817 params = adoptPtr(new blink::WebCryptoAesGcmParams(ivStart, ivLength, hasAdd
itionalData, additionalDataStart, additionalDataLength, hasTagLength, tagLength)
); |
798 return true; | 818 return true; |
799 } | 819 } |
800 | 820 |
801 bool parseAlgorithmParams(const Dictionary& raw, blink::WebCryptoAlgorithmParams
Type type, OwnPtr<blink::WebCryptoAlgorithmParams>& params, ErrorContext& contex
t, String& errorDetails) | 821 bool parseAlgorithmParams(const Dictionary& raw, blink::WebCryptoAlgorithmParams
Type type, OwnPtr<blink::WebCryptoAlgorithmParams>& params, ErrorContext& contex
t, CryptoResult* result) |
802 { | 822 { |
803 switch (type) { | 823 switch (type) { |
804 case blink::WebCryptoAlgorithmParamsTypeNone: | 824 case blink::WebCryptoAlgorithmParamsTypeNone: |
805 return true; | 825 return true; |
806 case blink::WebCryptoAlgorithmParamsTypeAesCbcParams: | 826 case blink::WebCryptoAlgorithmParamsTypeAesCbcParams: |
807 context.add("AesCbcParams"); | 827 context.add("AesCbcParams"); |
808 return parseAesCbcParams(raw, params, context, errorDetails); | 828 return parseAesCbcParams(raw, params, context, result); |
809 case blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams: | 829 case blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams: |
810 context.add("AesKeyGenParams"); | 830 context.add("AesKeyGenParams"); |
811 return parseAesKeyGenParams(raw, params, context, errorDetails); | 831 return parseAesKeyGenParams(raw, params, context, result); |
812 case blink::WebCryptoAlgorithmParamsTypeHmacImportParams: | 832 case blink::WebCryptoAlgorithmParamsTypeHmacImportParams: |
813 context.add("HmacImportParams"); | 833 context.add("HmacImportParams"); |
814 return parseHmacImportParams(raw, params, context, errorDetails); | 834 return parseHmacImportParams(raw, params, context, result); |
815 case blink::WebCryptoAlgorithmParamsTypeHmacKeyGenParams: | 835 case blink::WebCryptoAlgorithmParamsTypeHmacKeyGenParams: |
816 context.add("HmacKeyGenParams"); | 836 context.add("HmacKeyGenParams"); |
817 return parseHmacKeyGenParams(raw, params, context, errorDetails); | 837 return parseHmacKeyGenParams(raw, params, context, result); |
818 case blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams: | 838 case blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams: |
819 context.add("RsaHashedKeyGenParams"); | 839 context.add("RsaHashedKeyGenParams"); |
820 return parseRsaHashedKeyGenParams(raw, params, context, errorDetails); | 840 return parseRsaHashedKeyGenParams(raw, params, context, result); |
821 case blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams: | 841 case blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams: |
822 context.add("RsaHashedImportParams"); | 842 context.add("RsaHashedImportParams"); |
823 return parseRsaHashedImportParams(raw, params, context, errorDetails); | 843 return parseRsaHashedImportParams(raw, params, context, result); |
824 case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams: | 844 case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams: |
825 context.add("RsaKeyGenParams"); | 845 context.add("RsaKeyGenParams"); |
826 return parseRsaKeyGenParams(raw, params, context, errorDetails); | 846 return parseRsaKeyGenParams(raw, params, context, result); |
827 case blink::WebCryptoAlgorithmParamsTypeAesCtrParams: | 847 case blink::WebCryptoAlgorithmParamsTypeAesCtrParams: |
828 context.add("AesCtrParams"); | 848 context.add("AesCtrParams"); |
829 return parseAesCtrParams(raw, params, context, errorDetails); | 849 return parseAesCtrParams(raw, params, context, result); |
830 case blink::WebCryptoAlgorithmParamsTypeAesGcmParams: | 850 case blink::WebCryptoAlgorithmParamsTypeAesGcmParams: |
831 context.add("AesGcmParams"); | 851 context.add("AesGcmParams"); |
832 return parseAesGcmParams(raw, params, context, errorDetails); | 852 return parseAesGcmParams(raw, params, context, result); |
833 case blink::WebCryptoAlgorithmParamsTypeRsaOaepParams: | 853 case blink::WebCryptoAlgorithmParamsTypeRsaOaepParams: |
834 // TODO | 854 // TODO |
835 notImplemented(); | 855 notImplemented(); |
836 break; | 856 break; |
837 } | 857 } |
838 ASSERT_NOT_REACHED(); | 858 ASSERT_NOT_REACHED(); |
839 return false; | 859 return false; |
840 } | 860 } |
841 | 861 |
842 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp
toAlgorithm& algorithm, ErrorContext context, String& errorDetails) | 862 const char* operationToString(AlgorithmOperation op) |
| 863 { |
| 864 switch (op) { |
| 865 case Encrypt: |
| 866 return "encrypt"; |
| 867 case Decrypt: |
| 868 return "decrypt"; |
| 869 case Sign: |
| 870 return "sign"; |
| 871 case Verify: |
| 872 return "verify"; |
| 873 case Digest: |
| 874 return "digest"; |
| 875 case GenerateKey: |
| 876 return "generateKey"; |
| 877 case ImportKey: |
| 878 return "importKey"; |
| 879 case DeriveKey: |
| 880 return "deriveKey"; |
| 881 case DeriveBits: |
| 882 return "deriveBits"; |
| 883 case WrapKey: |
| 884 return "wrapKey"; |
| 885 case UnwrapKey: |
| 886 return "unwrapKey"; |
| 887 } |
| 888 return 0; |
| 889 } |
| 890 |
| 891 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp
toAlgorithm& algorithm, ErrorContext context, CryptoResult* result) |
843 { | 892 { |
844 context.add("Algorithm"); | 893 context.add("Algorithm"); |
845 | 894 |
846 if (!raw.isObject()) { | 895 if (!raw.isObject()) { |
847 errorDetails = context.toString("Not an object"); | 896 completeWithSyntaxError(context.toString("Not an object"), result); |
848 return false; | 897 return false; |
849 } | 898 } |
850 | 899 |
851 String algorithmName; | 900 String algorithmName; |
852 if (!raw.get("name", algorithmName)) { | 901 if (!raw.get("name", algorithmName)) { |
853 errorDetails = context.toString("name", "Missing or not a string"); | 902 completeWithSyntaxError(context.toString("name", "Missing or not a strin
g"), result); |
854 return false; | 903 return false; |
855 } | 904 } |
856 | 905 |
857 blink::WebCryptoAlgorithmId algorithmId; | 906 blink::WebCryptoAlgorithmId algorithmId; |
858 if (!lookupAlgorithmIdByName(algorithmName, algorithmId)) { | 907 if (!lookupAlgorithmIdByName(algorithmName, algorithmId)) { |
859 errorDetails = context.toString("Unrecognized algorithm name"); | 908 // FIXME: The spec says to return a SyntaxError if the input contains |
| 909 // any non-ASCII characters. |
| 910 completeWithNotSupportedError(context.toString("Unrecognized name"), res
ult); |
860 return false; | 911 return false; |
861 } | 912 } |
862 | 913 |
| 914 // Remove the "Algorithm:" prefix for all subsequent errors. |
| 915 context.removeLast(); |
| 916 |
863 const AlgorithmInfo* algorithmInfo = lookupAlgorithmInfo(algorithmId); | 917 const AlgorithmInfo* algorithmInfo = lookupAlgorithmInfo(algorithmId); |
864 context.add(algorithmInfo->name); | |
865 | 918 |
866 if (algorithmInfo->operationToParamsType[op] == Undefined) { | 919 if (algorithmInfo->operationToParamsType[op] == Undefined) { |
867 errorDetails = context.toString("Unsupported operation"); | 920 context.add(algorithmIdToName(algorithmId)); |
| 921 completeWithNotSupportedError(context.toString("Unsupported operation",
operationToString(op)), result); |
868 return false; | 922 return false; |
869 } | 923 } |
870 | 924 |
871 blink::WebCryptoAlgorithmParamsType paramsType = static_cast<blink::WebCrypt
oAlgorithmParamsType>(algorithmInfo->operationToParamsType[op]); | 925 blink::WebCryptoAlgorithmParamsType paramsType = static_cast<blink::WebCrypt
oAlgorithmParamsType>(algorithmInfo->operationToParamsType[op]); |
872 | 926 |
873 OwnPtr<blink::WebCryptoAlgorithmParams> params; | 927 OwnPtr<blink::WebCryptoAlgorithmParams> params; |
874 if (!parseAlgorithmParams(raw, paramsType, params, context, errorDetails)) | 928 if (!parseAlgorithmParams(raw, paramsType, params, context, result)) |
875 return false; | 929 return false; |
876 | 930 |
877 algorithm = blink::WebCryptoAlgorithm(algorithmId, params.release()); | 931 algorithm = blink::WebCryptoAlgorithm(algorithmId, params.release()); |
878 return true; | 932 return true; |
879 } | 933 } |
880 | 934 |
881 } // namespace | 935 } // namespace |
882 | 936 |
883 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp
toAlgorithm& algorithm, CryptoResult* result) | 937 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp
toAlgorithm& algorithm, CryptoResult* result) |
884 { | 938 { |
885 String errorDetails; | 939 return parseAlgorithm(raw, op, algorithm, ErrorContext(), result); |
886 if (!parseAlgorithm(raw, op, algorithm, ErrorContext(), errorDetails)) { | |
887 result->completeWithError(errorDetails); | |
888 return false; | |
889 } | |
890 return true; | |
891 } | 940 } |
892 | 941 |
893 const char* algorithmIdToName(blink::WebCryptoAlgorithmId id) | 942 const char* algorithmIdToName(blink::WebCryptoAlgorithmId id) |
894 { | 943 { |
895 return lookupAlgorithmInfo(id)->name; | 944 return lookupAlgorithmInfo(id)->name; |
896 } | 945 } |
897 | 946 |
898 } // namespace WebCore | 947 } // namespace WebCore |
OLD | NEW |