| 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 |