Changeset 208737 in webkit


Ignore:
Timestamp:
Nov 15, 2016 11:08:25 AM (7 years ago)
Author:
jiewen_tan@apple.com
Message:

Update SubtleCrypto::exportKey to match the latest spec
https://bugs.webkit.org/show_bug.cgi?id=164722
<rdar://problem/29251740>

Reviewed by Brent Fulgham.

LayoutTests/imported/w3c:

  • WebCryptoAPI/idlharness-expected.txt:

Source/WebCore:

This patch does following few things:

  1. It updates the SubtleCrypto::exportKey method to match the latest spec: https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-exportKey. It also refers to the latest Editor's Draft to a certain degree: https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-exportKey.
  2. It implements exportKey operations of the following algorithms: AES-CBC, AES-KW, HMAC, RSAES-PKCS1-V1_5, RSASSA-PKCS1-V1_5, and RSA-OAEP.
  3. It also fixes the following bugs: https://bugs.webkit.org/show_bug.cgi?id=156114, <rdar://problem/21773066>.

Note: We currently only support Raw and Jwk key format.

Tests: crypto/subtle/aes-cbc-generate-export-key-jwk-length-128.html

crypto/subtle/aes-cbc-generate-export-key-jwk-length-192.html
crypto/subtle/aes-cbc-generate-export-key-jwk-length-256.html
crypto/subtle/aes-cbc-generate-export-key-raw.html
crypto/subtle/aes-export-key-malformed-parameters.html
crypto/subtle/aes-kw-generate-export-key-jwk-length-128.html
crypto/subtle/aes-kw-generate-export-key-jwk-length-192.html
crypto/subtle/aes-kw-generate-export-key-jwk-length-256.html
crypto/subtle/aes-kw-generate-export-raw-key.html
crypto/subtle/export-key-malformed-parameters.html
crypto/subtle/hmac-export-key-malformed-parameters.html
crypto/subtle/hmac-generate-export-key-jwk-sha1.html
crypto/subtle/hmac-generate-export-key-jwk-sha224.html
crypto/subtle/hmac-generate-export-key-jwk-sha256.html
crypto/subtle/hmac-generate-export-key-jwk-sha384.html
crypto/subtle/hmac-generate-export-key-jwk-sha512.html
crypto/subtle/hmac-generate-export-raw-key.html
crypto/subtle/hmac-import-key-malformed-parameters.html
crypto/subtle/rsa-export-key-malformed-parameters.html
crypto/subtle/rsa-oaep-generate-export-key-jwk-sha1.html
crypto/subtle/rsa-oaep-generate-export-key-jwk-sha224.html
crypto/subtle/rsa-oaep-generate-export-key-jwk-sha256.html
crypto/subtle/rsa-oaep-generate-export-key-jwk-sha384.html
crypto/subtle/rsa-oaep-generate-export-key-jwk-sha512.html
crypto/subtle/rsaes-pkcs1-v1_5-generate-export-key-jwk.html
crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha1.html
crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha224.html
crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha256.html
crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha384.html
crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha512.html
crypto/workers/subtle/aes-generate-export-key-jwk.html
crypto/workers/subtle/aes-generate-export-key-raw.html
crypto/workers/subtle/hmac-generate-export-key-jwk.html
crypto/workers/subtle/hmac-generate-export-key-raw.html
crypto/workers/subtle/rsa-generate-export-key-jwk.html

  • bindings/js/JSSubtleCryptoCustom.cpp:

(WebCore::toJSValueFromJsonWebKey):
(WebCore::jsSubtleCryptoFunctionExportKeyPromise):
(WebCore::JSSubtleCrypto::exportKey):

  • crypto/CryptoAlgorithm.cpp:

(WebCore::CryptoAlgorithm::exportKey):

  • crypto/CryptoAlgorithm.h:
  • crypto/SubtleCrypto.idl:
  • crypto/algorithms/CryptoAlgorithmAES_CBC.cpp:

(WebCore::CryptoAlgorithmAES_CBC::importKey):
(WebCore::CryptoAlgorithmAES_CBC::exportKey):

  • crypto/algorithms/CryptoAlgorithmAES_CBC.h:
  • crypto/algorithms/CryptoAlgorithmAES_KW.cpp:

(WebCore::CryptoAlgorithmAES_KW::importKey):
(WebCore::CryptoAlgorithmAES_KW::exportKey):

  • crypto/algorithms/CryptoAlgorithmAES_KW.h:
  • crypto/algorithms/CryptoAlgorithmHMAC.cpp:

(WebCore::CryptoAlgorithmHMAC::importKey):
(WebCore::CryptoAlgorithmHMAC::exportKey):

  • crypto/algorithms/CryptoAlgorithmHMAC.h:
  • crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp:

(WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::importKey):
(WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::exportKey):

  • crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.h:
  • crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp:

(WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey):
(WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::exportKey):

  • crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h:
  • crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp:

(WebCore::CryptoAlgorithmRSA_OAEP::importKey):
(WebCore::CryptoAlgorithmRSA_OAEP::exportKey):

  • crypto/algorithms/CryptoAlgorithmRSA_OAEP.h:
  • crypto/keys/CryptoKeyAES.cpp:

(WebCore::CryptoKeyAES::exportJwk):

  • crypto/keys/CryptoKeyAES.h:
  • crypto/keys/CryptoKeyHMAC.cpp:

(WebCore::CryptoKeyHMAC::exportJwk):

  • crypto/keys/CryptoKeyHMAC.h:
  • crypto/keys/CryptoKeyRSA.cpp:

(WebCore::CryptoKeyRSA::exportJwk):

  • crypto/keys/CryptoKeyRSA.h:

LayoutTests:

Besides adding test cases for SubtleCrypto::exportKey, this patch also corrects a typo:
hmac-import-malformed-parameters* => hmac-import-key-malformed-parameters*.

  • crypto/subtle/aes-cbc-generate-export-key-jwk-length-128-expected.txt: Added.
  • crypto/subtle/aes-cbc-generate-export-key-jwk-length-128.html: Added.
  • crypto/subtle/aes-cbc-generate-export-key-jwk-length-192-expected.txt: Added.
  • crypto/subtle/aes-cbc-generate-export-key-jwk-length-192.html: Added.
  • crypto/subtle/aes-cbc-generate-export-key-jwk-length-256-expected.txt: Added.
  • crypto/subtle/aes-cbc-generate-export-key-jwk-length-256.html: Added.
  • crypto/subtle/aes-cbc-generate-export-key-raw-expected.txt: Added.
  • crypto/subtle/aes-cbc-generate-export-key-raw.html: Added.
  • crypto/subtle/aes-export-key-malformed-parameters-expected.txt: Added.
  • crypto/subtle/aes-export-key-malformed-parameters.html: Added.
  • crypto/subtle/aes-kw-generate-export-key-jwk-length-128-expected.txt: Added.
  • crypto/subtle/aes-kw-generate-export-key-jwk-length-128.html: Added.
  • crypto/subtle/aes-kw-generate-export-key-jwk-length-192-expected.txt: Added.
  • crypto/subtle/aes-kw-generate-export-key-jwk-length-192.html: Added.
  • crypto/subtle/aes-kw-generate-export-key-jwk-length-256-expected.txt: Added.
  • crypto/subtle/aes-kw-generate-export-key-jwk-length-256.html: Added.
  • crypto/subtle/aes-kw-generate-export-raw-key-expected.txt: Added.
  • crypto/subtle/aes-kw-generate-export-raw-key.html: Added.
  • crypto/subtle/export-key-malformed-parameters-expected.txt: Added.
  • crypto/subtle/export-key-malformed-parameters.html: Added.
  • crypto/subtle/hmac-export-key-malformed-parameters-expected.txt: Added.
  • crypto/subtle/hmac-export-key-malformed-parameters.html: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha1-expected.txt: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha1.html: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha224-expected.txt: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha224.html: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha256-expected.txt: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha256.html: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha384-expected.txt: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha384.html: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha512-expected.txt: Added.
  • crypto/subtle/hmac-generate-export-key-jwk-sha512.html: Added.
  • crypto/subtle/hmac-generate-export-raw-key-expected.txt: Added.
  • crypto/subtle/hmac-generate-export-raw-key.html: Added.
  • crypto/subtle/hmac-import-key-malformed-parameters-expected.txt: Renamed from LayoutTests/crypto/subtle/hmac-import-malformed-parameters-expected.txt.
  • crypto/subtle/hmac-import-key-malformed-parameters.html: Renamed from LayoutTests/crypto/subtle/hmac-import-malformed-parameters.html.
  • crypto/subtle/rsa-export-key-malformed-parameters-expected.txt: Added.
  • crypto/subtle/rsa-export-key-malformed-parameters.html: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha1-expected.txt: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha1.html: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha224-expected.txt: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha224.html: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha256-expected.txt: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha256.html: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha384-expected.txt: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha384.html: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha512-expected.txt: Added.
  • crypto/subtle/rsa-oaep-generate-export-key-jwk-sha512.html: Added.
  • crypto/subtle/rsaes-pkcs1-v1_5-generate-export-key-jwk-expected.txt: Added.
  • crypto/subtle/rsaes-pkcs1-v1_5-generate-export-key-jwk.html: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha1-expected.txt: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha1.html: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha224-expected.txt: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha224.html: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha256-expected.txt: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha256.html: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha384-expected.txt: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha384.html: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha512-expected.txt: Added.
  • crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha512.html: Added.
  • crypto/workers/subtle/aes-generate-export-key-jwk-expected.txt: Added.
  • crypto/workers/subtle/aes-generate-export-key-jwk.html: Added.
  • crypto/workers/subtle/aes-generate-export-key-raw-expected.txt: Added.
  • crypto/workers/subtle/aes-generate-export-key-raw.html: Added.
  • crypto/workers/subtle/hmac-generate-export-key-jwk-expected.txt: Added.
  • crypto/workers/subtle/hmac-generate-export-key-jwk.html: Added.
  • crypto/workers/subtle/hmac-generate-export-key-raw-expected.txt: Added.
  • crypto/workers/subtle/hmac-generate-export-key-raw.html: Added.
  • crypto/workers/subtle/resources/aes-generate-export-key-jwk.js: Added.
  • crypto/workers/subtle/resources/aes-generate-export-key-raw.js: Added.
  • crypto/workers/subtle/resources/hmac-generate-export-key-jwk.js: Added.
  • crypto/workers/subtle/resources/hmac-generate-export-key-raw.js: Added.
  • crypto/workers/subtle/resources/rsa-generate-export-key-jwk.js: Added.
  • crypto/workers/subtle/rsa-generate-export-key-jwk-expected.txt: Added.
  • crypto/workers/subtle/rsa-generate-export-key-jwk.html: Added.
Location:
trunk
Files:
73 added
26 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r208735 r208737  
     12016-11-14  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        Update SubtleCrypto::exportKey to match the latest spec
     4        https://bugs.webkit.org/show_bug.cgi?id=164722
     5        <rdar://problem/29251740>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Besides adding test cases for SubtleCrypto::exportKey, this patch also corrects a typo:
     10        hmac-import-malformed-parameters* => hmac-import-key-malformed-parameters*.
     11
     12        * crypto/subtle/aes-cbc-generate-export-key-jwk-length-128-expected.txt: Added.
     13        * crypto/subtle/aes-cbc-generate-export-key-jwk-length-128.html: Added.
     14        * crypto/subtle/aes-cbc-generate-export-key-jwk-length-192-expected.txt: Added.
     15        * crypto/subtle/aes-cbc-generate-export-key-jwk-length-192.html: Added.
     16        * crypto/subtle/aes-cbc-generate-export-key-jwk-length-256-expected.txt: Added.
     17        * crypto/subtle/aes-cbc-generate-export-key-jwk-length-256.html: Added.
     18        * crypto/subtle/aes-cbc-generate-export-key-raw-expected.txt: Added.
     19        * crypto/subtle/aes-cbc-generate-export-key-raw.html: Added.
     20        * crypto/subtle/aes-export-key-malformed-parameters-expected.txt: Added.
     21        * crypto/subtle/aes-export-key-malformed-parameters.html: Added.
     22        * crypto/subtle/aes-kw-generate-export-key-jwk-length-128-expected.txt: Added.
     23        * crypto/subtle/aes-kw-generate-export-key-jwk-length-128.html: Added.
     24        * crypto/subtle/aes-kw-generate-export-key-jwk-length-192-expected.txt: Added.
     25        * crypto/subtle/aes-kw-generate-export-key-jwk-length-192.html: Added.
     26        * crypto/subtle/aes-kw-generate-export-key-jwk-length-256-expected.txt: Added.
     27        * crypto/subtle/aes-kw-generate-export-key-jwk-length-256.html: Added.
     28        * crypto/subtle/aes-kw-generate-export-raw-key-expected.txt: Added.
     29        * crypto/subtle/aes-kw-generate-export-raw-key.html: Added.
     30        * crypto/subtle/export-key-malformed-parameters-expected.txt: Added.
     31        * crypto/subtle/export-key-malformed-parameters.html: Added.
     32        * crypto/subtle/hmac-export-key-malformed-parameters-expected.txt: Added.
     33        * crypto/subtle/hmac-export-key-malformed-parameters.html: Added.
     34        * crypto/subtle/hmac-generate-export-key-jwk-sha1-expected.txt: Added.
     35        * crypto/subtle/hmac-generate-export-key-jwk-sha1.html: Added.
     36        * crypto/subtle/hmac-generate-export-key-jwk-sha224-expected.txt: Added.
     37        * crypto/subtle/hmac-generate-export-key-jwk-sha224.html: Added.
     38        * crypto/subtle/hmac-generate-export-key-jwk-sha256-expected.txt: Added.
     39        * crypto/subtle/hmac-generate-export-key-jwk-sha256.html: Added.
     40        * crypto/subtle/hmac-generate-export-key-jwk-sha384-expected.txt: Added.
     41        * crypto/subtle/hmac-generate-export-key-jwk-sha384.html: Added.
     42        * crypto/subtle/hmac-generate-export-key-jwk-sha512-expected.txt: Added.
     43        * crypto/subtle/hmac-generate-export-key-jwk-sha512.html: Added.
     44        * crypto/subtle/hmac-generate-export-raw-key-expected.txt: Added.
     45        * crypto/subtle/hmac-generate-export-raw-key.html: Added.
     46        * crypto/subtle/hmac-import-key-malformed-parameters-expected.txt: Renamed from LayoutTests/crypto/subtle/hmac-import-malformed-parameters-expected.txt.
     47        * crypto/subtle/hmac-import-key-malformed-parameters.html: Renamed from LayoutTests/crypto/subtle/hmac-import-malformed-parameters.html.
     48        * crypto/subtle/rsa-export-key-malformed-parameters-expected.txt: Added.
     49        * crypto/subtle/rsa-export-key-malformed-parameters.html: Added.
     50        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha1-expected.txt: Added.
     51        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha1.html: Added.
     52        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha224-expected.txt: Added.
     53        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha224.html: Added.
     54        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha256-expected.txt: Added.
     55        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha256.html: Added.
     56        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha384-expected.txt: Added.
     57        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha384.html: Added.
     58        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha512-expected.txt: Added.
     59        * crypto/subtle/rsa-oaep-generate-export-key-jwk-sha512.html: Added.
     60        * crypto/subtle/rsaes-pkcs1-v1_5-generate-export-key-jwk-expected.txt: Added.
     61        * crypto/subtle/rsaes-pkcs1-v1_5-generate-export-key-jwk.html: Added.
     62        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha1-expected.txt: Added.
     63        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha1.html: Added.
     64        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha224-expected.txt: Added.
     65        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha224.html: Added.
     66        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha256-expected.txt: Added.
     67        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha256.html: Added.
     68        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha384-expected.txt: Added.
     69        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha384.html: Added.
     70        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha512-expected.txt: Added.
     71        * crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha512.html: Added.
     72        * crypto/workers/subtle/aes-generate-export-key-jwk-expected.txt: Added.
     73        * crypto/workers/subtle/aes-generate-export-key-jwk.html: Added.
     74        * crypto/workers/subtle/aes-generate-export-key-raw-expected.txt: Added.
     75        * crypto/workers/subtle/aes-generate-export-key-raw.html: Added.
     76        * crypto/workers/subtle/hmac-generate-export-key-jwk-expected.txt: Added.
     77        * crypto/workers/subtle/hmac-generate-export-key-jwk.html: Added.
     78        * crypto/workers/subtle/hmac-generate-export-key-raw-expected.txt: Added.
     79        * crypto/workers/subtle/hmac-generate-export-key-raw.html: Added.
     80        * crypto/workers/subtle/resources/aes-generate-export-key-jwk.js: Added.
     81        * crypto/workers/subtle/resources/aes-generate-export-key-raw.js: Added.
     82        * crypto/workers/subtle/resources/hmac-generate-export-key-jwk.js: Added.
     83        * crypto/workers/subtle/resources/hmac-generate-export-key-raw.js: Added.
     84        * crypto/workers/subtle/resources/rsa-generate-export-key-jwk.js: Added.
     85        * crypto/workers/subtle/rsa-generate-export-key-jwk-expected.txt: Added.
     86        * crypto/workers/subtle/rsa-generate-export-key-jwk.html: Added.
     87
    1882016-11-15  Jon Lee  <jonlee@apple.com>
    289
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r208684 r208737  
     12016-11-14  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        Update SubtleCrypto::exportKey to match the latest spec
     4        https://bugs.webkit.org/show_bug.cgi?id=164722
     5        <rdar://problem/29251740>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        * WebCryptoAPI/idlharness-expected.txt:
     10
    1112016-11-14  Youenn Fablet  <youenn@apple.com>
    212
  • trunk/LayoutTests/imported/w3c/WebCryptoAPI/idlharness-expected.txt

    r208548 r208737  
    6262PASS SubtleCrypto interface: crypto.subtle must inherit property "importKey" with the proper type (8)
    6363PASS SubtleCrypto interface: calling importKey(KeyFormat,[object Object],[object Object],AlgorithmIdentifier,boolean,[object Object]) on crypto.subtle with too few arguments must throw TypeError
    64 FAIL SubtleCrypto interface: crypto.subtle must inherit property "exportKey" with the proper type (9) assert_inherits: property "exportKey" not found in prototype chain
    65 FAIL SubtleCrypto interface: calling exportKey(KeyFormat,CryptoKey) on crypto.subtle with too few arguments must throw TypeError assert_inherits: property "exportKey" not found in prototype chain
     64PASS SubtleCrypto interface: crypto.subtle must inherit property "exportKey" with the proper type (9)
     65PASS SubtleCrypto interface: calling exportKey(KeyFormat,CryptoKey) on crypto.subtle with too few arguments must throw TypeError
    6666FAIL SubtleCrypto interface: crypto.subtle must inherit property "wrapKey" with the proper type (10) assert_inherits: property "wrapKey" not found in prototype chain
    6767FAIL SubtleCrypto interface: calling wrapKey(KeyFormat,CryptoKey,CryptoKey,AlgorithmIdentifier) on crypto.subtle with too few arguments must throw TypeError assert_inherits: property "wrapKey" not found in prototype chain
  • trunk/Source/WebCore/ChangeLog

    r208735 r208737  
     12016-11-14  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        Update SubtleCrypto::exportKey to match the latest spec
     4        https://bugs.webkit.org/show_bug.cgi?id=164722
     5        <rdar://problem/29251740>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        This patch does following few things:
     10        1. It updates the SubtleCrypto::exportKey method to match the latest spec:
     11           https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-exportKey.
     12           It also refers to the latest Editor's Draft to a certain degree:
     13           https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-exportKey.
     14        2. It implements exportKey operations of the following algorithms: AES-CBC, AES-KW,
     15           HMAC, RSAES-PKCS1-V1_5, RSASSA-PKCS1-V1_5, and RSA-OAEP.
     16        3. It also fixes the following bugs:
     17           https://bugs.webkit.org/show_bug.cgi?id=156114,
     18           <rdar://problem/21773066>.
     19        Note: We currently only support Raw and Jwk key format.
     20
     21        Tests: crypto/subtle/aes-cbc-generate-export-key-jwk-length-128.html
     22               crypto/subtle/aes-cbc-generate-export-key-jwk-length-192.html
     23               crypto/subtle/aes-cbc-generate-export-key-jwk-length-256.html
     24               crypto/subtle/aes-cbc-generate-export-key-raw.html
     25               crypto/subtle/aes-export-key-malformed-parameters.html
     26               crypto/subtle/aes-kw-generate-export-key-jwk-length-128.html
     27               crypto/subtle/aes-kw-generate-export-key-jwk-length-192.html
     28               crypto/subtle/aes-kw-generate-export-key-jwk-length-256.html
     29               crypto/subtle/aes-kw-generate-export-raw-key.html
     30               crypto/subtle/export-key-malformed-parameters.html
     31               crypto/subtle/hmac-export-key-malformed-parameters.html
     32               crypto/subtle/hmac-generate-export-key-jwk-sha1.html
     33               crypto/subtle/hmac-generate-export-key-jwk-sha224.html
     34               crypto/subtle/hmac-generate-export-key-jwk-sha256.html
     35               crypto/subtle/hmac-generate-export-key-jwk-sha384.html
     36               crypto/subtle/hmac-generate-export-key-jwk-sha512.html
     37               crypto/subtle/hmac-generate-export-raw-key.html
     38               crypto/subtle/hmac-import-key-malformed-parameters.html
     39               crypto/subtle/rsa-export-key-malformed-parameters.html
     40               crypto/subtle/rsa-oaep-generate-export-key-jwk-sha1.html
     41               crypto/subtle/rsa-oaep-generate-export-key-jwk-sha224.html
     42               crypto/subtle/rsa-oaep-generate-export-key-jwk-sha256.html
     43               crypto/subtle/rsa-oaep-generate-export-key-jwk-sha384.html
     44               crypto/subtle/rsa-oaep-generate-export-key-jwk-sha512.html
     45               crypto/subtle/rsaes-pkcs1-v1_5-generate-export-key-jwk.html
     46               crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha1.html
     47               crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha224.html
     48               crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha256.html
     49               crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha384.html
     50               crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-jwk-sha512.html
     51               crypto/workers/subtle/aes-generate-export-key-jwk.html
     52               crypto/workers/subtle/aes-generate-export-key-raw.html
     53               crypto/workers/subtle/hmac-generate-export-key-jwk.html
     54               crypto/workers/subtle/hmac-generate-export-key-raw.html
     55               crypto/workers/subtle/rsa-generate-export-key-jwk.html
     56
     57        * bindings/js/JSSubtleCryptoCustom.cpp:
     58        (WebCore::toJSValueFromJsonWebKey):
     59        (WebCore::jsSubtleCryptoFunctionExportKeyPromise):
     60        (WebCore::JSSubtleCrypto::exportKey):
     61        * crypto/CryptoAlgorithm.cpp:
     62        (WebCore::CryptoAlgorithm::exportKey):
     63        * crypto/CryptoAlgorithm.h:
     64        * crypto/SubtleCrypto.idl:
     65        * crypto/algorithms/CryptoAlgorithmAES_CBC.cpp:
     66        (WebCore::CryptoAlgorithmAES_CBC::importKey):
     67        (WebCore::CryptoAlgorithmAES_CBC::exportKey):
     68        * crypto/algorithms/CryptoAlgorithmAES_CBC.h:
     69        * crypto/algorithms/CryptoAlgorithmAES_KW.cpp:
     70        (WebCore::CryptoAlgorithmAES_KW::importKey):
     71        (WebCore::CryptoAlgorithmAES_KW::exportKey):
     72        * crypto/algorithms/CryptoAlgorithmAES_KW.h:
     73        * crypto/algorithms/CryptoAlgorithmHMAC.cpp:
     74        (WebCore::CryptoAlgorithmHMAC::importKey):
     75        (WebCore::CryptoAlgorithmHMAC::exportKey):
     76        * crypto/algorithms/CryptoAlgorithmHMAC.h:
     77        * crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp:
     78        (WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::importKey):
     79        (WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::exportKey):
     80        * crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.h:
     81        * crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp:
     82        (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey):
     83        (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::exportKey):
     84        * crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h:
     85        * crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp:
     86        (WebCore::CryptoAlgorithmRSA_OAEP::importKey):
     87        (WebCore::CryptoAlgorithmRSA_OAEP::exportKey):
     88        * crypto/algorithms/CryptoAlgorithmRSA_OAEP.h:
     89        * crypto/keys/CryptoKeyAES.cpp:
     90        (WebCore::CryptoKeyAES::exportJwk):
     91        * crypto/keys/CryptoKeyAES.h:
     92        * crypto/keys/CryptoKeyHMAC.cpp:
     93        (WebCore::CryptoKeyHMAC::exportJwk):
     94        * crypto/keys/CryptoKeyHMAC.h:
     95        * crypto/keys/CryptoKeyRSA.cpp:
     96        (WebCore::CryptoKeyRSA::exportJwk):
     97        * crypto/keys/CryptoKeyRSA.h:
     98
    1992016-11-15  Jon Lee  <jonlee@apple.com>
    2100
  • trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp

    r208669 r208737  
    4444#include <runtime/Error.h>
    4545#include <runtime/IteratorOperations.h>
     46#include <runtime/JSArray.h>
    4647
    4748using namespace JSC;
     
    308309}
    309310
     311// FIXME: We should get rid of this once https://bugs.webkit.org/show_bug.cgi?id=163711 is fixed.
     312static JSValue toJSValueFromJsonWebKey(JSDOMGlobalObject& globalObject, JsonWebKey&& key)
     313{
     314    ExecState& state = *globalObject.globalExec();
     315    VM& vm = state.vm();
     316
     317    auto* result = constructEmptyObject(&state);
     318    result->putDirect(vm, Identifier::fromString(&vm, "kty"), toJS<IDLDOMString>(state, key.kty));
     319    if (key.use)
     320        result->putDirect(vm, Identifier::fromString(&vm, "use"), toJS<IDLDOMString>(state, key.use.value()));
     321    if (key.key_ops)
     322        result->putDirect(vm, Identifier::fromString(&vm, "key_ops"), toJS<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(state, globalObject, key.key_ops.value()));
     323    if (key.alg)
     324        result->putDirect(vm, Identifier::fromString(&vm, "alg"), toJS<IDLDOMString>(state, key.alg.value()));
     325    if (key.ext)
     326        result->putDirect(vm, Identifier::fromString(&vm, "ext"), toJS<IDLBoolean>(state, key.ext.value()));
     327    if (key.crv)
     328        result->putDirect(vm, Identifier::fromString(&vm, "crv"), toJS<IDLDOMString>(state, key.crv.value()));
     329    if (key.x)
     330        result->putDirect(vm, Identifier::fromString(&vm, "x"), toJS<IDLDOMString>(state, key.x.value()));
     331    if (key.y)
     332        result->putDirect(vm, Identifier::fromString(&vm, "y"), toJS<IDLDOMString>(state, key.y.value()));
     333    if (key.d)
     334        result->putDirect(vm, Identifier::fromString(&vm, "d"), toJS<IDLDOMString>(state, key.d.value()));
     335    if (key.n)
     336        result->putDirect(vm, Identifier::fromString(&vm, "n"), toJS<IDLDOMString>(state, key.n.value()));
     337    if (key.e)
     338        result->putDirect(vm, Identifier::fromString(&vm, "e"), toJS<IDLDOMString>(state, key.e.value()));
     339    if (key.p)
     340        result->putDirect(vm, Identifier::fromString(&vm, "p"), toJS<IDLDOMString>(state, key.p.value()));
     341    if (key.q)
     342        result->putDirect(vm, Identifier::fromString(&vm, "q"), toJS<IDLDOMString>(state, key.q.value()));
     343    if (key.dp)
     344        result->putDirect(vm, Identifier::fromString(&vm, "dp"), toJS<IDLDOMString>(state, key.dp.value()));
     345    if (key.dq)
     346        result->putDirect(vm, Identifier::fromString(&vm, "dq"), toJS<IDLDOMString>(state, key.dq.value()));
     347    if (key.qi)
     348        result->putDirect(vm, Identifier::fromString(&vm, "qi"), toJS<IDLDOMString>(state, key.qi.value()));
     349    if (key.oth) {
     350        MarkedArgumentBuffer list;
     351        for (auto& value : key.oth.value()) {
     352            auto* info = constructEmptyObject(&state);
     353            info->putDirect(vm, Identifier::fromString(&vm, "r"), toJS<IDLDOMString>(state, value.r));
     354            info->putDirect(vm, Identifier::fromString(&vm, "d"), toJS<IDLDOMString>(state, value.d));
     355            info->putDirect(vm, Identifier::fromString(&vm, "t"), toJS<IDLDOMString>(state, value.t));
     356            list.append(info);
     357        }
     358        result->putDirect(vm, Identifier::fromString(&vm, "oth"), constructArray(&state, static_cast<Structure*>(nullptr), list));
     359    }
     360    if (key.k)
     361        result->putDirect(vm, Identifier::fromString(&vm, "k"), toJS<IDLDOMString>(state, key.k.value()));
     362
     363    return result;
     364}
     365
    310366static void jsSubtleCryptoFunctionGenerateKeyPromise(ExecState& state, Ref<DeferredPromise>&& promise)
    311367{
     
    351407    };
    352408
    353     // The spec suggests we should perform the following task asynchronously regardless what kind of keys it produces
    354     // as of 11 December 2014: https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-generateKey
     409    // The 11 December 2014 version of the specification suggests we should perform the following task asynchronously
     410    // regardless what kind of keys it produces: https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-generateKey
    355411    // That's simply not efficient for AES and HMAC keys. Therefore, we perform it as an async task conditionally.
    356412    algorithm->generateKey(WTFMove(params), extractable, keyUsages, WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContextFromExecState(&state));
     
    396452    };
    397453
    398     // The spec suggests we should perform the following task asynchronously as of 11 December 2014:
     454    // The 11 December 2014 version of the specification suggests we should perform the following task asynchronously:
    399455    // https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-importKey
    400     // That's simply not necessary. Therefore, we perform it synchronously.
     456    // It is not beneficial for less time consuming operations. Therefore, we perform it synchronously.
    401457    algorithm->importKey(format, WTFMove(keyData), WTFMove(params), extractable, keyUsages, WTFMove(callback), WTFMove(exceptionCallback));
    402458}
    403459
     460static void jsSubtleCryptoFunctionExportKeyPromise(ExecState& state, Ref<DeferredPromise>&& promise)
     461{
     462    VM& vm = state.vm();
     463    auto scope = DECLARE_THROW_SCOPE(vm);
     464
     465    if (UNLIKELY(state.argumentCount() < 2)) {
     466        promise->reject<JSValue>(createNotEnoughArgumentsError(&state));
     467        return;
     468    }
     469
     470    auto format = convertEnumeration<SubtleCrypto::KeyFormat>(state, state.uncheckedArgument(0));
     471    RETURN_IF_EXCEPTION(scope, void());
     472
     473    RefPtr<CryptoKey> key = JSCryptoKey::toWrapped(state.uncheckedArgument(1));
     474    if (!key) {
     475        promise->reject<JSValue>(createTypeError(&state, ASCIILiteral("Invalid CryptoKey")));
     476        return;
     477    }
     478
     479    switch (key->algorithmIdentifier()) {
     480    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
     481    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
     482    case CryptoAlgorithmIdentifier::RSA_PSS:
     483    case CryptoAlgorithmIdentifier::RSA_OAEP:
     484    case CryptoAlgorithmIdentifier::AES_CTR:
     485    case CryptoAlgorithmIdentifier::AES_CBC:
     486    case CryptoAlgorithmIdentifier::AES_CMAC:
     487    case CryptoAlgorithmIdentifier::AES_GCM:
     488    case CryptoAlgorithmIdentifier::AES_CFB:
     489    case CryptoAlgorithmIdentifier::AES_KW:
     490    case CryptoAlgorithmIdentifier::HMAC:
     491        break;
     492    default:
     493        promise->reject<JSValue>(createDOMException(&state, NOT_SUPPORTED_ERR, ASCIILiteral("The operation is not supported")));
     494        return;
     495    }
     496
     497    if (!key->extractable()) {
     498        promise->reject<JSValue>(createDOMException(&state, INVALID_ACCESS_ERR, ASCIILiteral("The CryptoKey is nonextractable")));
     499        return;
     500    }
     501
     502    auto algorithm = createAlgorithm(state, key->algorithmIdentifier());
     503    RETURN_IF_EXCEPTION(scope, void());
     504
     505    auto callback = [capturedPromise = promise.copyRef()](SubtleCrypto::KeyFormat format, KeyData&& key) mutable {
     506        switch (format) {
     507        case SubtleCrypto::KeyFormat::Spki:
     508        case SubtleCrypto::KeyFormat::Pkcs8:
     509        case SubtleCrypto::KeyFormat::Raw: {
     510            Vector<uint8_t>& rawKey = WTF::get<Vector<uint8_t>>(key);
     511            fulfillPromiseWithArrayBuffer(WTFMove(capturedPromise), rawKey.data(), rawKey.size());
     512            return;
     513        }
     514        case SubtleCrypto::KeyFormat::Jwk:
     515            capturedPromise->resolve(toJSValueFromJsonWebKey(*(capturedPromise->globalObject()), WTFMove(WTF::get<JsonWebKey>(key))));
     516            return;
     517        }
     518        ASSERT_NOT_REACHED();
     519    };
     520    auto exceptionCallback = [capturedPromise =  promise.copyRef()](ExceptionCode ec) mutable {
     521        rejectWithException(WTFMove(capturedPromise), ec);
     522    };
     523
     524    // The 11 December 2014 version of the specification suggests we should perform the following task asynchronously:
     525    // https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-exportKey
     526    // It is not beneficial for less time consuming operations. Therefore, we perform it synchronously.
     527    algorithm->exportKey(format, WTFMove(key), WTFMove(callback), WTFMove(exceptionCallback));
     528}
     529
    404530JSValue JSSubtleCrypto::generateKey(ExecState& state)
    405531{
     
    412538}
    413539
     540JSValue JSSubtleCrypto::exportKey(ExecState& state)
     541{
     542    return callPromiseFunction<jsSubtleCryptoFunctionExportKeyPromise, PromiseExecutionScope::WindowOrWorker>(state);
     543}
     544
    414545} // namespace WebCore
    415546
  • trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp

    r208669 r208737  
    3939
    4040void CryptoAlgorithm::importKey(SubtleCrypto::KeyFormat, KeyData&&, const std::unique_ptr<CryptoAlgorithmParameters>&&, bool, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&& exceptionCallback)
     41{
     42    exceptionCallback(NOT_SUPPORTED_ERR);
     43}
     44
     45void CryptoAlgorithm::exportKey(SubtleCrypto::KeyFormat, RefPtr<WebCore::CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&& exceptionCallback)
    4146{
    4247    exceptionCallback(NOT_SUPPORTED_ERR);
  • trunk/Source/WebCore/crypto/CryptoAlgorithm.h

    r208669 r208737  
    6262    using VoidCallback = WTF::Function<void()>;
    6363    using ExceptionCallback = WTF::Function<void(ExceptionCode)>;
     64    using KeyDataCallback = WTF::Function<void(SubtleCrypto::KeyFormat, KeyData&&)>;
    6465
    6566    virtual void generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&);
    6667    virtual void importKey(SubtleCrypto::KeyFormat, KeyData&&, const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&);
     68    virtual void exportKey(SubtleCrypto::KeyFormat, RefPtr<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&);
    6769
    6870    // The following will be deprecated.
  • trunk/Source/WebCore/crypto/SubtleCrypto.idl

    r208602 r208737  
    3535    [Custom] Promise<any> generateKey(AlgorithmIdentifier algorithm, boolean extractable, sequence<CryptoKeyUsage> keyUsages);
    3636    [Custom] Promise<CryptoKey> importKey(KeyFormat format, (BufferSource or JsonWebKey) keyData, AlgorithmIdentifier algorithm, boolen extractable, sequence<CryptoKeyUsage> keyUsages);
     37    [Custom] Promise<any> exportKey(KeyFormat format, CryptoKey key);
    3738};
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_CBC.cpp

    r208669 r208737  
    3838namespace WebCore {
    3939
     40static const char* const ALG128 = "A128CBC";
     41static const char* const ALG192 = "A192CBC";
     42static const char* const ALG256 = "A256CBC";
     43
    4044static inline bool usagesAreInvalidForCryptoAlgorithmAES_CBC(CryptoKeyUsageBitmap usages)
    4145{
     
    9599            switch (length) {
    96100            case CryptoKeyAES::s_length128:
    97                 return !alg || alg.value() == "A128CBC";
     101                return !alg || alg.value() == ALG128;
    98102            case CryptoKeyAES::s_length192:
    99                 return !alg || alg.value() == "A192CBC";
     103                return !alg || alg.value() == ALG192;
    100104            case CryptoKeyAES::s_length256:
    101                 return !alg || alg.value() == "A256CBC";
     105                return !alg || alg.value() == ALG256;
    102106            }
    103107            return false;
     
    116120
    117121    callback(*result);
     122}
     123
     124void CryptoAlgorithmAES_CBC::exportKey(SubtleCrypto::KeyFormat format, RefPtr<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
     125{
     126    const auto& aesKey = downcast<CryptoKeyAES>(*key);
     127
     128    if (aesKey.key().isEmpty()) {
     129        exceptionCallback(OperationError);
     130        return;
     131    }
     132
     133    KeyData result;
     134    switch (format) {
     135    case SubtleCrypto::KeyFormat::Raw:
     136        result = Vector<uint8_t>(aesKey.key());
     137        break;
     138    case SubtleCrypto::KeyFormat::Jwk: {
     139        JsonWebKey jwk = aesKey.exportJwk();
     140        switch (aesKey.key().size() * 8) {
     141        case CryptoKeyAES::s_length128:
     142            jwk.alg = String(ALG128);
     143            break;
     144        case CryptoKeyAES::s_length192:
     145            jwk.alg = String(ALG192);
     146            break;
     147        case CryptoKeyAES::s_length256:
     148            jwk.alg = String(ALG256);
     149            break;
     150        default:
     151            ASSERT_NOT_REACHED();
     152        }
     153        result = WTFMove(jwk);
     154        break;
     155    }
     156    default:
     157        exceptionCallback(NOT_SUPPORTED_ERR);
     158        return;
     159    }
     160
     161    callback(format, WTFMove(result));
    118162}
    119163
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_CBC.h

    r208669 r208737  
    4747    void generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
    4848    void importKey(SubtleCrypto::KeyFormat, KeyData&&, const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
     49    void exportKey(SubtleCrypto::KeyFormat, RefPtr<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
    4950
    5051    ExceptionOr<void> encrypt(const CryptoAlgorithmParametersDeprecated&, const CryptoKey&, const CryptoOperationData&, VectorCallback&&, VoidCallback&& failureCallback) final;
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.cpp

    r208669 r208737  
    3636
    3737namespace WebCore {
     38
     39static const char* const ALG128 = "A128KW";
     40static const char* const ALG192 = "A192KW";
     41static const char* const ALG256 = "A256KW";
    3842
    3943static inline bool usagesAreInvalidForCryptoAlgorithmAES_KW(CryptoKeyUsageBitmap usages)
     
    9296            switch (length) {
    9397            case CryptoKeyAES::s_length128:
    94                 return !alg || alg.value() == "A128KW";
     98                return !alg || alg.value() == ALG128;
    9599            case CryptoKeyAES::s_length192:
    96                 return !alg || alg.value() == "A192KW";
     100                return !alg || alg.value() == ALG192;
    97101            case CryptoKeyAES::s_length256:
    98                 return !alg || alg.value() == "A256KW";
     102                return !alg || alg.value() == ALG256;
    99103            }
    100104            return false;
     
    112116
    113117    callback(*result);
     118}
     119
     120void CryptoAlgorithmAES_KW::exportKey(SubtleCrypto::KeyFormat format, RefPtr<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
     121{
     122    const auto& aesKey = downcast<CryptoKeyAES>(*key);
     123
     124    if (aesKey.key().isEmpty()) {
     125        exceptionCallback(OperationError);
     126        return;
     127    }
     128
     129    KeyData result;
     130    switch (format) {
     131    case SubtleCrypto::KeyFormat::Raw:
     132        result = Vector<uint8_t>(aesKey.key());
     133        break;
     134    case SubtleCrypto::KeyFormat::Jwk: {
     135        JsonWebKey jwk = aesKey.exportJwk();
     136        switch (aesKey.key().size() * 8) {
     137        case CryptoKeyAES::s_length128:
     138            jwk.alg = String(ALG128);
     139            break;
     140        case CryptoKeyAES::s_length192:
     141            jwk.alg = String(ALG192);
     142            break;
     143        case CryptoKeyAES::s_length256:
     144            jwk.alg = String(ALG256);
     145            break;
     146        default:
     147            ASSERT_NOT_REACHED();
     148        }
     149        result = WTFMove(jwk);
     150        break;
     151    }
     152    default:
     153        exceptionCallback(NOT_SUPPORTED_ERR);
     154        return;
     155    }
     156
     157    callback(format, WTFMove(result));
    114158}
    115159
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.h

    r208669 r208737  
    4646    void generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
    4747    void importKey(SubtleCrypto::KeyFormat, KeyData&&, const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
     48    void exportKey(SubtleCrypto::KeyFormat, RefPtr<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
    4849
    4950    ExceptionOr<void> encryptForWrapKey(const CryptoAlgorithmParametersDeprecated&, const CryptoKey&, const CryptoOperationData&, VectorCallback&&, VoidCallback&& failureCallback) final;
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmHMAC.cpp

    r208669 r208737  
    3838namespace WebCore {
    3939
     40static const char* const ALG1 = "HS1";
     41static const char* const ALG224 = "HS224";
     42static const char* const ALG256 = "HS256";
     43static const char* const ALG384 = "HS384";
     44static const char* const ALG512 = "HS512";
     45
    4046static inline bool usagesAreInvalidForCryptoAlgorithmHMAC(CryptoKeyUsageBitmap usages)
    4147{
     
    105111            switch (hash) {
    106112            case CryptoAlgorithmIdentifier::SHA_1:
    107                 return !alg || alg.value() == "HS1";
     113                return !alg || alg.value() == ALG1;
    108114            case CryptoAlgorithmIdentifier::SHA_224:
    109                 return !alg || alg.value() == "HS224";
     115                return !alg || alg.value() == ALG224;
    110116            case CryptoAlgorithmIdentifier::SHA_256:
    111                 return !alg || alg.value() == "HS256";
     117                return !alg || alg.value() == ALG256;
    112118            case CryptoAlgorithmIdentifier::SHA_384:
    113                 return !alg || alg.value() == "HS384";
     119                return !alg || alg.value() == ALG384;
    114120            case CryptoAlgorithmIdentifier::SHA_512:
    115                 return !alg || alg.value() == "HS512";
     121                return !alg || alg.value() == ALG512;
    116122            default:
    117123                return false;
     
    134140}
    135141
     142void CryptoAlgorithmHMAC::exportKey(SubtleCrypto::KeyFormat format, RefPtr<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
     143{
     144    const auto& hmacKey = downcast<CryptoKeyHMAC>(*key);
     145
     146    if (hmacKey.key().isEmpty()) {
     147        exceptionCallback(OperationError);
     148        return;
     149    }
     150
     151    KeyData result;
     152    switch (format) {
     153    case SubtleCrypto::KeyFormat::Raw:
     154        result = Vector<uint8_t>(hmacKey.key());
     155        break;
     156    case SubtleCrypto::KeyFormat::Jwk: {
     157        JsonWebKey jwk = hmacKey.exportJwk();
     158        switch (hmacKey.hashAlgorithmIdentifier()) {
     159        case CryptoAlgorithmIdentifier::SHA_1:
     160            jwk.alg = String(ALG1);
     161            break;
     162        case CryptoAlgorithmIdentifier::SHA_224:
     163            jwk.alg = String(ALG224);
     164            break;
     165        case CryptoAlgorithmIdentifier::SHA_256:
     166            jwk.alg = String(ALG256);
     167            break;
     168        case CryptoAlgorithmIdentifier::SHA_384:
     169            jwk.alg = String(ALG384);
     170            break;
     171        case CryptoAlgorithmIdentifier::SHA_512:
     172            jwk.alg = String(ALG512);
     173            break;
     174        default:
     175            ASSERT_NOT_REACHED();
     176        }
     177        result = WTFMove(jwk);
     178        break;
     179    }
     180    default:
     181        exceptionCallback(NOT_SUPPORTED_ERR);
     182        return;
     183    }
     184
     185    callback(format, WTFMove(result));
     186}
     187
    136188ExceptionOr<void> CryptoAlgorithmHMAC::sign(const CryptoAlgorithmParametersDeprecated& parameters, const CryptoKey& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback)
    137189{
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmHMAC.h

    r208669 r208737  
    4747    void generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
    4848    void importKey(SubtleCrypto::KeyFormat, KeyData&&, const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
     49    void exportKey(SubtleCrypto::KeyFormat, RefPtr<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
    4950
    5051    // The following will be deprecated.
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp

    r208669 r208737  
    3838
    3939namespace WebCore {
     40
     41static const char* const ALG = "RSA1_5";
    4042
    4143Ref<CryptoAlgorithm> CryptoAlgorithmRSAES_PKCS1_v1_5::create()
     
    9395            return;
    9496        }
    95         if (key.alg && key.alg.value() != "RSA1_5") {
     97        if (key.alg && key.alg.value() != ALG) {
    9698            exceptionCallback(DataError);
    9799            return;
     
    110112
    111113    callback(*result);
     114}
     115
     116void CryptoAlgorithmRSAES_PKCS1_v1_5::exportKey(SubtleCrypto::KeyFormat format, RefPtr<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
     117{
     118    const auto& rsaKey = downcast<CryptoKeyRSA>(*key);
     119
     120    if (!rsaKey.keySizeInBits()) {
     121        exceptionCallback(OperationError);
     122        return;
     123    }
     124
     125    KeyData result;
     126    switch (format) {
     127    case SubtleCrypto::KeyFormat::Jwk: {
     128        JsonWebKey jwk = rsaKey.exportJwk();
     129        jwk.alg = String(ALG);
     130        result = WTFMove(jwk);
     131        break;
     132    }
     133    default:
     134        exceptionCallback(NOT_SUPPORTED_ERR);
     135        return;
     136    }
     137
     138    callback(format, WTFMove(result));
    112139}
    113140
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.h

    r208669 r208737  
    4747    void generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
    4848    void importKey(SubtleCrypto::KeyFormat, KeyData&&, const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
     49    void exportKey(SubtleCrypto::KeyFormat, RefPtr<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
    4950
    5051    // The following will be deprecated.
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp

    r208669 r208737  
    4141namespace WebCore {
    4242
     43static const char* const ALG1 = "RS1";
     44static const char* const ALG224 = "RS224";
     45static const char* const ALG256 = "RS256";
     46static const char* const ALG384 = "RS384";
     47static const char* const ALG512 = "RS512";
     48
    4349Ref<CryptoAlgorithm> CryptoAlgorithmRSASSA_PKCS1_v1_5::create()
    4450{
     
    104110        switch (rsaParameters.hashIdentifier) {
    105111        case CryptoAlgorithmIdentifier::SHA_1:
    106             isMatched = !key.alg || key.alg.value() == "RS1";
     112            isMatched = !key.alg || key.alg.value() == ALG1;
    107113            break;
    108114        case CryptoAlgorithmIdentifier::SHA_224:
    109             isMatched = !key.alg || key.alg.value() == "RS224";
     115            isMatched = !key.alg || key.alg.value() == ALG224;
    110116            break;
    111117        case CryptoAlgorithmIdentifier::SHA_256:
    112             isMatched = !key.alg || key.alg.value() == "RS256";
     118            isMatched = !key.alg || key.alg.value() == ALG256;
    113119            break;
    114120        case CryptoAlgorithmIdentifier::SHA_384:
    115             isMatched = !key.alg || key.alg.value() == "RS384";
     121            isMatched = !key.alg || key.alg.value() == ALG384;
    116122            break;
    117123        case CryptoAlgorithmIdentifier::SHA_512:
    118             isMatched = !key.alg || key.alg.value() == "RS512";
     124            isMatched = !key.alg || key.alg.value() == ALG512;
    119125            break;
    120126        default:
     
    139145
    140146    callback(*result);
     147}
     148
     149void CryptoAlgorithmRSASSA_PKCS1_v1_5::exportKey(SubtleCrypto::KeyFormat format, RefPtr<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
     150{
     151    const auto& rsaKey = downcast<CryptoKeyRSA>(*key);
     152
     153    if (!rsaKey.keySizeInBits()) {
     154        exceptionCallback(OperationError);
     155        return;
     156    }
     157
     158    KeyData result;
     159    switch (format) {
     160    case SubtleCrypto::KeyFormat::Jwk: {
     161        JsonWebKey jwk = rsaKey.exportJwk();
     162        switch (rsaKey.hashAlgorithmIdentifier()) {
     163        case CryptoAlgorithmIdentifier::SHA_1:
     164            jwk.alg = String(ALG1);
     165            break;
     166        case CryptoAlgorithmIdentifier::SHA_224:
     167            jwk.alg = String(ALG224);
     168            break;
     169        case CryptoAlgorithmIdentifier::SHA_256:
     170            jwk.alg = String(ALG256);
     171            break;
     172        case CryptoAlgorithmIdentifier::SHA_384:
     173            jwk.alg = String(ALG384);
     174            break;
     175        case CryptoAlgorithmIdentifier::SHA_512:
     176            jwk.alg = String(ALG512);
     177            break;
     178        default:
     179            ASSERT_NOT_REACHED();
     180        }
     181        result = WTFMove(jwk);
     182        break;
     183    }
     184    default:
     185        exceptionCallback(NOT_SUPPORTED_ERR);
     186        return;
     187    }
     188
     189    callback(format, WTFMove(result));
    141190}
    142191
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h

    r208669 r208737  
    4747    void generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
    4848    void importKey(SubtleCrypto::KeyFormat, KeyData&&, const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
     49    void exportKey(SubtleCrypto::KeyFormat, RefPtr<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
    4950
    5051    ExceptionOr<void> sign(const CryptoAlgorithmParametersDeprecated&, const CryptoKey&, const CryptoOperationData&, VectorCallback&&, VoidCallback&& failureCallback) final;
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp

    r208669 r208737  
    4141namespace WebCore {
    4242
     43static const char* const ALG1 = "RSA-OAEP";
     44static const char* const ALG224 = "RSA-OAEP-224";
     45static const char* const ALG256 = "RSA-OAEP-256";
     46static const char* const ALG384 = "RSA-OAEP-384";
     47static const char* const ALG512 = "RSA-OAEP-512";
     48
    4349Ref<CryptoAlgorithm> CryptoAlgorithmRSA_OAEP::create()
    4450{
     
    115121        switch (rsaParameters.hashIdentifier) {
    116122        case CryptoAlgorithmIdentifier::SHA_1:
    117             isMatched = !key.alg || key.alg.value() == "RSA-OAEP";
     123            isMatched = !key.alg || key.alg.value() == ALG1;
    118124            break;
    119125        case CryptoAlgorithmIdentifier::SHA_224:
    120             isMatched = !key.alg || key.alg.value() == "RSA-OAEP-224";
     126            isMatched = !key.alg || key.alg.value() == ALG224;
    121127            break;
    122128        case CryptoAlgorithmIdentifier::SHA_256:
    123             isMatched = !key.alg || key.alg.value() == "RSA-OAEP-256";
     129            isMatched = !key.alg || key.alg.value() == ALG256;
    124130            break;
    125131        case CryptoAlgorithmIdentifier::SHA_384:
    126             isMatched = !key.alg || key.alg.value() == "RSA-OAEP-384";
     132            isMatched = !key.alg || key.alg.value() == ALG384;
    127133            break;
    128134        case CryptoAlgorithmIdentifier::SHA_512:
    129             isMatched = !key.alg || key.alg.value() == "RSA-OAEP-512";
     135            isMatched = !key.alg || key.alg.value() == ALG512;
    130136            break;
    131137        default:
     
    150156
    151157    callback(*result);
     158}
     159
     160void CryptoAlgorithmRSA_OAEP::exportKey(SubtleCrypto::KeyFormat format, RefPtr<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
     161{
     162    const auto& rsaKey = downcast<CryptoKeyRSA>(*key);
     163
     164    if (!rsaKey.keySizeInBits()) {
     165        exceptionCallback(OperationError);
     166        return;
     167    }
     168
     169    KeyData result;
     170    switch (format) {
     171    case SubtleCrypto::KeyFormat::Jwk: {
     172        JsonWebKey jwk = rsaKey.exportJwk();
     173        switch (rsaKey.hashAlgorithmIdentifier()) {
     174        case CryptoAlgorithmIdentifier::SHA_1:
     175            jwk.alg = String(ALG1);
     176            break;
     177        case CryptoAlgorithmIdentifier::SHA_224:
     178            jwk.alg = String(ALG224);
     179            break;
     180        case CryptoAlgorithmIdentifier::SHA_256:
     181            jwk.alg = String(ALG256);
     182            break;
     183        case CryptoAlgorithmIdentifier::SHA_384:
     184            jwk.alg = String(ALG384);
     185            break;
     186        case CryptoAlgorithmIdentifier::SHA_512:
     187            jwk.alg = String(ALG512);
     188            break;
     189        default:
     190            ASSERT_NOT_REACHED();
     191        }
     192        result = WTFMove(jwk);
     193        break;
     194    }
     195    default:
     196        exceptionCallback(NOT_SUPPORTED_ERR);
     197        return;
     198    }
     199
     200    callback(format, WTFMove(result));
    152201}
    153202
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_OAEP.h

    r208669 r208737  
    4747    void generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
    4848    void importKey(SubtleCrypto::KeyFormat, KeyData&&, const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
     49    void exportKey(SubtleCrypto::KeyFormat, RefPtr<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
    4950
    5051    ExceptionOr<void> encrypt(const CryptoAlgorithmParametersDeprecated&, const CryptoKey&, const CryptoOperationData&, VectorCallback&&, VoidCallback&& failureCallback) final;
  • trunk/Source/WebCore/crypto/keys/CryptoKeyAES.cpp

    r208669 r208737  
    105105}
    106106
     107JsonWebKey CryptoKeyAES::exportJwk() const
     108{
     109    JsonWebKey result;
     110    result.kty = "oct";
     111    result.k = base64URLEncode(m_key);
     112    result.key_ops = usages();
     113    result.ext = extractable();
     114    return result;
     115}
     116
    107117std::unique_ptr<KeyAlgorithm> CryptoKeyAES::buildAlgorithm() const
    108118{
  • trunk/Source/WebCore/crypto/keys/CryptoKeyAES.h

    r208646 r208737  
    7575
    7676    const Vector<uint8_t>& key() const { return m_key; }
     77    JsonWebKey exportJwk() const;
    7778
    7879private:
  • trunk/Source/WebCore/crypto/keys/CryptoKeyHMAC.cpp

    r208669 r208737  
    115115}
    116116
     117JsonWebKey CryptoKeyHMAC::exportJwk() const
     118{
     119    JsonWebKey result;
     120    result.kty = "oct";
     121    result.k = base64URLEncode(m_key);
     122    result.key_ops = usages();
     123    result.ext = extractable();
     124    return result;
     125}
     126
    117127std::unique_ptr<KeyAlgorithm> CryptoKeyHMAC::buildAlgorithm() const
    118128{
  • trunk/Source/WebCore/crypto/keys/CryptoKeyHMAC.h

    r208646 r208737  
    7171
    7272    const Vector<uint8_t>& key() const { return m_key; }
     73    JsonWebKey exportJwk() const;
    7374
    7475    CryptoAlgorithmIdentifier hashAlgorithmIdentifier() const { return m_hash; }
  • trunk/Source/WebCore/crypto/keys/CryptoKeyRSA.cpp

    r208602 r208737  
    109109}
    110110
     111JsonWebKey CryptoKeyRSA::exportJwk() const
     112{
     113    JsonWebKey result;
     114    result.kty = "RSA";
     115    result.key_ops = usages();
     116    result.ext = extractable();
     117
     118    auto keyData = exportData();
     119    const auto& rsaKeyData = downcast<CryptoKeyDataRSAComponents>(*keyData);
     120    // public key
     121    result.n = base64URLEncode(rsaKeyData.modulus());
     122    result.e = base64URLEncode(rsaKeyData.exponent());
     123    if (rsaKeyData.type() == CryptoKeyDataRSAComponents::Type::Public)
     124        return result;
     125
     126    // private key
     127    result.d = base64URLEncode(rsaKeyData.privateExponent());
     128    if (!rsaKeyData.hasAdditionalPrivateKeyParameters())
     129        return result;
     130
     131    result.p = base64URLEncode(rsaKeyData.firstPrimeInfo().primeFactor);
     132    result.q = base64URLEncode(rsaKeyData.secondPrimeInfo().primeFactor);
     133    result.dp = base64URLEncode(rsaKeyData.firstPrimeInfo().factorCRTExponent);
     134    result.dq = base64URLEncode(rsaKeyData.secondPrimeInfo().factorCRTExponent);
     135    result.qi = base64URLEncode(rsaKeyData.secondPrimeInfo().factorCRTCoefficient);
     136    if (rsaKeyData.otherPrimeInfos().isEmpty())
     137        return result;
     138
     139    Vector<RsaOtherPrimesInfo> oth;
     140    for (auto info : rsaKeyData.otherPrimeInfos()) {
     141        RsaOtherPrimesInfo otherInfo;
     142        otherInfo.r = base64URLEncode(info.primeFactor);
     143        otherInfo.d = base64URLEncode(info.factorCRTExponent);
     144        otherInfo.t = base64URLEncode(info.factorCRTCoefficient);
     145        oth.append(WTFMove(otherInfo));
     146    }
     147    result.oth = WTFMove(oth);
     148    return result;
     149}
     150
    111151} // namespace WebCore
    112152
  • trunk/Source/WebCore/crypto/keys/CryptoKeyRSA.h

    r208646 r208737  
    104104
    105105    PlatformRSAKey platformKey() const { return m_platformKey; }
     106    JsonWebKey exportJwk() const;
     107
     108    CryptoAlgorithmIdentifier hashAlgorithmIdentifier() const { return m_hash; }
    106109
    107110private:
Note: See TracChangeset for help on using the changeset viewer.