Changeset 158427 in webkit


Ignore:
Timestamp:
Nov 1, 2013 12:15:45 AM (10 years ago)
Author:
ap@apple.com
Message:

Add a Mac WebCrypto implementation of HMAC importKey/sign/verify
https://bugs.webkit.org/show_bug.cgi?id=123598

Reviewed by Anders Carlsson.

Source/WebCore:

Test: crypto/subtle/hmac-sign-verify.html

  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/JSSubtleCryptoCustom.cpp: Added property svn:eol-style.

(WebCore::createAlgorithmFromJSValue):
(WebCore::cryptoOperationDataFromJSValue):
(WebCore::cryptoKeyFormatFromJSValue):
(WebCore::cryptoKeyUsagesFromJSValue):
(WebCore::JSSubtleCrypto::sign):
(WebCore::JSSubtleCrypto::verify):
(WebCore::JSSubtleCrypto::digest):
(WebCore::JSSubtleCrypto::importKey):

  • crypto/SubtleCrypto.idl:
  • crypto/algorithms/CryptoAlgorithmHMAC.cpp: Added.

(WebCore::CryptoAlgorithmHMAC::CryptoAlgorithmHMAC):
(WebCore::CryptoAlgorithmHMAC::~CryptoAlgorithmHMAC):
(WebCore::CryptoAlgorithmHMAC::create):
(WebCore::CryptoAlgorithmHMAC::identifier):
(WebCore::CryptoAlgorithmHMAC::importKey):
(WebCore::CryptoAlgorithmHMAC::exportKey):

  • crypto/algorithms/CryptoAlgorithmHMAC.h: Added.
  • crypto/keys: Added.
  • crypto/keys/CryptoKeyHMAC.cpp: Added.

(WebCore::CryptoKeyHMAC::CryptoKeyHMAC):
(WebCore::CryptoKeyHMAC::~CryptoKeyHMAC):
(WebCore::CryptoKeyHMAC::buildAlgorithmDescription):

  • crypto/keys/CryptoKeyHMAC.h: Added.
  • crypto/mac/CryptoAlgorithmHMACMac.cpp: Added.

(WebCore::getCommonCryptoAlgorithm):
(WebCore::calculateSignature):
(WebCore::CryptoAlgorithmHMAC::sign):
(WebCore::CryptoAlgorithmHMAC::verify):
(WebCore::CryptoAlgorithmHMAC::generateKey):

  • crypto/mac/CryptoAlgorithmRegistryMac.cpp:

(WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms):

LayoutTests:

  • crypto/subtle/hmac-sign-verify-expected.txt: Added.
  • crypto/subtle/hmac-sign-verify.html: Added.
Location:
trunk
Files:
4 added
6 edited
4 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r158425 r158427  
     12013-11-01  Alexey Proskuryakov  <ap@apple.com>
     2
     3        Add a Mac WebCrypto implementation of HMAC importKey/sign/verify
     4        https://bugs.webkit.org/show_bug.cgi?id=123598
     5
     6        Reviewed by Anders Carlsson.
     7
     8        * crypto/subtle/hmac-sign-verify-expected.txt: Added.
     9        * crypto/subtle/hmac-sign-verify.html: Added.
     10
    1112013-10-31  Oliver Hunt  <oliver@apple.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r158421 r158427  
     12013-11-01  Alexey Proskuryakov  <ap@apple.com>
     2
     3        Add a Mac WebCrypto implementation of HMAC importKey/sign/verify
     4        https://bugs.webkit.org/show_bug.cgi?id=123598
     5
     6        Reviewed by Anders Carlsson.
     7
     8        Test: crypto/subtle/hmac-sign-verify.html
     9
     10        * WebCore.xcodeproj/project.pbxproj:
     11        * bindings/js/JSSubtleCryptoCustom.cpp: Added property svn:eol-style.
     12        (WebCore::createAlgorithmFromJSValue):
     13        (WebCore::cryptoOperationDataFromJSValue):
     14        (WebCore::cryptoKeyFormatFromJSValue):
     15        (WebCore::cryptoKeyUsagesFromJSValue):
     16        (WebCore::JSSubtleCrypto::sign):
     17        (WebCore::JSSubtleCrypto::verify):
     18        (WebCore::JSSubtleCrypto::digest):
     19        (WebCore::JSSubtleCrypto::importKey):
     20        * crypto/SubtleCrypto.idl:
     21        * crypto/algorithms/CryptoAlgorithmHMAC.cpp: Added.
     22        (WebCore::CryptoAlgorithmHMAC::CryptoAlgorithmHMAC):
     23        (WebCore::CryptoAlgorithmHMAC::~CryptoAlgorithmHMAC):
     24        (WebCore::CryptoAlgorithmHMAC::create):
     25        (WebCore::CryptoAlgorithmHMAC::identifier):
     26        (WebCore::CryptoAlgorithmHMAC::importKey):
     27        (WebCore::CryptoAlgorithmHMAC::exportKey):
     28        * crypto/algorithms/CryptoAlgorithmHMAC.h: Added.
     29        * crypto/keys: Added.
     30        * crypto/keys/CryptoKeyHMAC.cpp: Added.
     31        (WebCore::CryptoKeyHMAC::CryptoKeyHMAC):
     32        (WebCore::CryptoKeyHMAC::~CryptoKeyHMAC):
     33        (WebCore::CryptoKeyHMAC::buildAlgorithmDescription):
     34        * crypto/keys/CryptoKeyHMAC.h: Added.
     35        * crypto/mac/CryptoAlgorithmHMACMac.cpp: Added.
     36        (WebCore::getCommonCryptoAlgorithm):
     37        (WebCore::calculateSignature):
     38        (WebCore::CryptoAlgorithmHMAC::sign):
     39        (WebCore::CryptoAlgorithmHMAC::verify):
     40        (WebCore::CryptoAlgorithmHMAC::generateKey):
     41        * crypto/mac/CryptoAlgorithmRegistryMac.cpp:
     42        (WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms):
     43
    1442013-10-31  Joseph Pecoraro  <pecoraro@apple.com>
    245
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r158417 r158427  
    55055505                E125F82C1822CFEC00D84CD9 /* CryptoAlgorithmSHA1.h in Headers */ = {isa = PBXBuildFile; fileRef = E125F82A1822CFEC00D84CD9 /* CryptoAlgorithmSHA1.h */; };
    55065506                E125F82E1822CFFF00D84CD9 /* CryptoAlgorithmSHA1Mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E125F82D1822CFFF00D84CD9 /* CryptoAlgorithmSHA1Mac.cpp */; };
     5507                E125F8311822F11B00D84CD9 /* CryptoAlgorithmHMAC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E125F82F1822F11B00D84CD9 /* CryptoAlgorithmHMAC.cpp */; };
     5508                E125F8321822F11B00D84CD9 /* CryptoAlgorithmHMAC.h in Headers */ = {isa = PBXBuildFile; fileRef = E125F8301822F11B00D84CD9 /* CryptoAlgorithmHMAC.h */; };
     5509                E125F8351822F18A00D84CD9 /* CryptoKeyHMAC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E125F8331822F18A00D84CD9 /* CryptoKeyHMAC.cpp */; };
     5510                E125F8361822F18A00D84CD9 /* CryptoKeyHMAC.h in Headers */ = {isa = PBXBuildFile; fileRef = E125F8341822F18A00D84CD9 /* CryptoKeyHMAC.h */; };
     5511                E125F8381822F1EB00D84CD9 /* CryptoAlgorithmHMACMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E125F8371822F1EB00D84CD9 /* CryptoAlgorithmHMACMac.cpp */; };
    55075512                E12719C70EEEC16800F61213 /* NavigatorBase.h in Headers */ = {isa = PBXBuildFile; fileRef = E12719C60EEEC16800F61213 /* NavigatorBase.h */; };
    55085513                E12719CA0EEEC21300F61213 /* NavigatorBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E12719C90EEEC21300F61213 /* NavigatorBase.cpp */; };
     
    1251012515                E125F82A1822CFEC00D84CD9 /* CryptoAlgorithmSHA1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmSHA1.h; sourceTree = "<group>"; };
    1251112516                E125F82D1822CFFF00D84CD9 /* CryptoAlgorithmSHA1Mac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CryptoAlgorithmSHA1Mac.cpp; path = mac/CryptoAlgorithmSHA1Mac.cpp; sourceTree = "<group>"; };
     12517                E125F82F1822F11B00D84CD9 /* CryptoAlgorithmHMAC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmHMAC.cpp; sourceTree = "<group>"; };
     12518                E125F8301822F11B00D84CD9 /* CryptoAlgorithmHMAC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmHMAC.h; sourceTree = "<group>"; };
     12519                E125F8331822F18A00D84CD9 /* CryptoKeyHMAC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CryptoKeyHMAC.cpp; path = keys/CryptoKeyHMAC.cpp; sourceTree = "<group>"; };
     12520                E125F8341822F18A00D84CD9 /* CryptoKeyHMAC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CryptoKeyHMAC.h; path = keys/CryptoKeyHMAC.h; sourceTree = "<group>"; };
     12521                E125F8371822F1EB00D84CD9 /* CryptoAlgorithmHMACMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CryptoAlgorithmHMACMac.cpp; path = mac/CryptoAlgorithmHMACMac.cpp; sourceTree = "<group>"; };
    1251212522                E12719C60EEEC16800F61213 /* NavigatorBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigatorBase.h; sourceTree = "<group>"; };
    1251312523                E12719C90EEEC21300F61213 /* NavigatorBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NavigatorBase.cpp; sourceTree = "<group>"; };
     
    2013220142                        isa = PBXGroup;
    2013320143                        children = (
     20144                                E125F8371822F1EB00D84CD9 /* CryptoAlgorithmHMACMac.cpp */,
    2013420145                                E1BB84AC1822CA7400525043 /* CryptoAlgorithmRegistryMac.cpp */,
    2013520146                                E125F82D1822CFFF00D84CD9 /* CryptoAlgorithmSHA1Mac.cpp */,
     
    2014120152                        isa = PBXGroup;
    2014220153                        children = (
     20154                                E125F82F1822F11B00D84CD9 /* CryptoAlgorithmHMAC.cpp */,
     20155                                E125F8301822F11B00D84CD9 /* CryptoAlgorithmHMAC.h */,
    2014320156                                E125F8291822CFEC00D84CD9 /* CryptoAlgorithmSHA1.cpp */,
    2014420157                                E125F82A1822CFEC00D84CD9 /* CryptoAlgorithmSHA1.h */,
     
    2015020163                        isa = PBXGroup;
    2015120164                        children = (
     20165                                E125F8331822F18A00D84CD9 /* CryptoKeyHMAC.cpp */,
     20166                                E125F8341822F18A00D84CD9 /* CryptoKeyHMAC.h */,
    2015220167                        );
    2015320168                        name = keys;
     
    2214622161                                85E7118D0AC5D5350053270F /* DOMAttrInternal.h in Headers */,
    2214722162                                BC946EEF107FDBAC00857193 /* DOMBeforeLoadEvent.h in Headers */,
     22163                                E125F8361822F18A00D84CD9 /* CryptoKeyHMAC.h in Headers */,
    2214822164                                2E2D99E710E2BC1C00496337 /* DOMBlob.h in Headers */,
    2214922165                                2E2D99EA10E2BC3800496337 /* DOMBlobInternal.h in Headers */,
     
    2439224408                                B2227AB60D00BF220071B782 /* SVGGraphicsElement.h in Headers */,
    2439324409                                650FBF2B0D9AF047008FC292 /* SVGHKernElement.h in Headers */,
     24410                                E125F8321822F11B00D84CD9 /* CryptoAlgorithmHMAC.h in Headers */,
    2439424411                                51D719BA181106E00016DC51 /* IDBAny.h in Headers */,
    2439524412                                B25599A40D00D8BA00BB825C /* SVGImage.h in Headers */,
     
    2549025507                                97BC6A201505F081001B74AC /* Database.cpp in Sources */,
    2549125508                                97BC6A231505F081001B74AC /* DatabaseAuthorizer.cpp in Sources */,
     25509                                E125F8351822F18A00D84CD9 /* CryptoKeyHMAC.cpp in Sources */,
    2549225510                                511EF2C517F0FD3500E4FA16 /* JSIDBIndex.cpp in Sources */,
    2549325511                                FE16CFD3169D1DED00D3A0C7 /* DatabaseBackend.cpp in Sources */,
     
    2563125649                                E157A8E818184C67009F821D /* JSCryptoKeyCustom.cpp in Sources */,
    2563225650                                0705852317FDC140005F2BCB /* MediaTrackConstraints.cpp in Sources */,
     25651                                E125F8311822F11B00D84CD9 /* CryptoAlgorithmHMAC.cpp in Sources */,
    2563325652                                D359D792129CA3C00006E5D2 /* DOMHTMLDetailsElement.mm in Sources */,
    2563425653                                85BA4D0C0AA688680088052D /* DOMHTMLDirectoryElement.mm in Sources */,
     
    2607026089                                A8EA79F30A1916DF00A8EF5F /* HTMLUListElement.cpp in Sources */,
    2607126090                                E44613AA0CD6331000FADA75 /* HTMLVideoElement.cpp in Sources */,
     26091                                E125F8381822F1EB00D84CD9 /* CryptoAlgorithmHMACMac.cpp in Sources */,
    2607226092                                BCCD74E50A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp in Sources */,
    2607326093                                977B3879122883E900B81FF8 /* HTMLViewSourceParser.cpp in Sources */,
  • trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp

    r158387 r158427  
    5050    }
    5151
    52     std::unique_ptr<CryptoAlgorithm> result(CryptoAlgorithmRegistry::shared().create(algorithmIdentifier));
     52    auto result = CryptoAlgorithmRegistry::shared().create(algorithmIdentifier);
    5353    if (!result)
    5454        setDOMException(exec, NOT_SUPPORTED_ERR);
     
    7979}
    8080
     81static bool cryptoOperationDataFromJSValue(ExecState* exec, JSValue value, CryptoOperationData& result)
     82{
     83    if (ArrayBuffer* buffer = toArrayBuffer(value))
     84        result = std::make_pair(static_cast<char*>(buffer->data()), buffer->byteLength());
     85    else if (RefPtr<ArrayBufferView> bufferView = toArrayBufferView(value))
     86        result = std::make_pair(static_cast<char*>(bufferView->baseAddress()), bufferView->byteLength());
     87    else {
     88        throwTypeError(exec, "Only ArrayBuffer and ArrayBufferView objects can be part of CryptoOperationData sequence");
     89        return false;
     90    }
     91    return true;
     92}
     93
     94static bool cryptoKeyFormatFromJSValue(ExecState* exec, JSValue value, CryptoKeyFormat& result)
     95{
     96    String keyFormatString = value.toString(exec)->value(exec);
     97    if (exec->hadException())
     98        return false;
     99    if (keyFormatString == "raw")
     100        result = CryptoKeyFormat::Raw;
     101    else if (keyFormatString == "pkcs8")
     102        result = CryptoKeyFormat::PKCS8;
     103    else if (keyFormatString == "spki")
     104        result = CryptoKeyFormat::SPKI;
     105    else if (keyFormatString == "jwk")
     106        result = CryptoKeyFormat::JWK;
     107    else {
     108        throwTypeError(exec);
     109        return false;
     110    }
     111    return true;
     112}
     113
     114static bool cryptoKeyUsagesFromJSValue(ExecState* exec, JSValue value, CryptoKeyUsage& result)
     115{
     116    if (!isJSArray(value)) {
     117        throwTypeError(exec);
     118        return false;
     119    }
     120
     121    result = 0;
     122
     123    JSC::JSArray* array = asArray(value);
     124    for (size_t i = 0; i < array->length(); ++i) {
     125        JSC::JSValue element = array->getIndex(exec, i);
     126        String usageString = element.toString(exec)->value(exec);
     127        if (exec->hadException())
     128            return false;
     129        if (usageString == "encrypt")
     130            result |= CryptoKeyUsageEncrypt;
     131        else if (usageString == "decrypt")
     132            result |= CryptoKeyUsageDecrypt;
     133        else if (usageString == "sign")
     134            result |= CryptoKeyUsageSign;
     135        else if (usageString == "verify")
     136            result |= CryptoKeyUsageVerify;
     137        else if (usageString == "deriveKey")
     138            result |= CryptoKeyUsageDeriveKey;
     139        else if (usageString == "deriveBits")
     140            result |= CryptoKeyUsageDeriveBits;
     141        else if (usageString == "wrapKey")
     142            result |= CryptoKeyUsageWrapKey;
     143        else if (usageString == "unwrapKey")
     144            result |= CryptoKeyUsageUnwrapKey;
     145    }
     146    return true;
     147}
     148
     149JSValue JSSubtleCrypto::sign(ExecState* exec)
     150{
     151    if (exec->argumentCount() < 3)
     152        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
     153
     154    auto algorithm = createAlgorithmFromJSValue(exec, exec->uncheckedArgument(0));
     155    if (!algorithm) {
     156        ASSERT(exec->hadException());
     157        return jsUndefined();
     158    }
     159
     160    auto parameters = JSCryptoAlgorithmDictionary::createParametersForSign(exec, algorithm->identifier(), exec->uncheckedArgument(0));
     161    if (!parameters) {
     162        ASSERT(exec->hadException());
     163        return jsUndefined();
     164    }
     165
     166    RefPtr<CryptoKey> key = toCryptoKey(exec->uncheckedArgument(1));
     167    if (!key)
     168        return throwTypeError(exec);
     169
     170    if (!key->allows(CryptoKeyUsageSign)) {
     171        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages does not include 'sign'");
     172        setDOMException(exec, NOT_SUPPORTED_ERR);
     173        return jsUndefined();
     174    }
     175
     176    Vector<CryptoOperationData> data;
     177    if (!sequenceOfCryptoOperationDataFromJSValue(exec, exec->uncheckedArgument(2), data)) {
     178        ASSERT(exec->hadException());
     179        return jsUndefined();
     180    }
     181
     182    JSPromise* promise = JSPromise::createWithResolver(exec->vm(), globalObject());
     183    auto promiseWrapper = PromiseWrapper::create(globalObject(), promise);
     184
     185    ExceptionCode ec = 0;
     186    algorithm->sign(*parameters, *key.get(), data, std::move(promiseWrapper), ec);
     187    if (ec) {
     188        setDOMException(exec, ec);
     189        return jsUndefined();
     190    }
     191
     192    return promise;
     193}
     194
     195JSValue JSSubtleCrypto::verify(ExecState* exec)
     196{
     197    if (exec->argumentCount() < 4)
     198        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
     199
     200    auto algorithm = createAlgorithmFromJSValue(exec, exec->uncheckedArgument(0));
     201    if (!algorithm) {
     202        ASSERT(exec->hadException());
     203        return jsUndefined();
     204    }
     205
     206    auto parameters = JSCryptoAlgorithmDictionary::createParametersForVerify(exec, algorithm->identifier(), exec->uncheckedArgument(0));
     207    if (!parameters) {
     208        ASSERT(exec->hadException());
     209        return jsUndefined();
     210    }
     211
     212    RefPtr<CryptoKey> key = toCryptoKey(exec->uncheckedArgument(1));
     213    if (!key)
     214        return throwTypeError(exec);
     215
     216    if (!key->allows(CryptoKeyUsageVerify)) {
     217        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages does not include 'verify'");
     218        setDOMException(exec, NOT_SUPPORTED_ERR);
     219        return jsUndefined();
     220    }
     221
     222    CryptoOperationData signature;
     223    if (!cryptoOperationDataFromJSValue(exec, exec->uncheckedArgument(2), signature)) {
     224        ASSERT(exec->hadException());
     225        return jsUndefined();
     226    }
     227
     228    Vector<CryptoOperationData> data;
     229    if (!sequenceOfCryptoOperationDataFromJSValue(exec, exec->uncheckedArgument(3), data)) {
     230        ASSERT(exec->hadException());
     231        return jsUndefined();
     232    }
     233
     234    JSPromise* promise = JSPromise::createWithResolver(exec->vm(), globalObject());
     235    auto promiseWrapper = PromiseWrapper::create(globalObject(), promise);
     236
     237    ExceptionCode ec = 0;
     238    algorithm->verify(*parameters, *key, signature, data, std::move(promiseWrapper), ec);
     239    if (ec) {
     240        setDOMException(exec, ec);
     241        return jsUndefined();
     242    }
     243
     244    return promise;
     245}
     246
    81247JSValue JSSubtleCrypto::digest(ExecState* exec)
    82248{
     
    84250        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
    85251
    86     std::unique_ptr<CryptoAlgorithm> algorithm = createAlgorithmFromJSValue(exec, exec->uncheckedArgument(0));
     252    auto algorithm = createAlgorithmFromJSValue(exec, exec->uncheckedArgument(0));
    87253    if (!algorithm) {
    88254        ASSERT(exec->hadException());
     
    90256    }
    91257
    92     std::unique_ptr<CryptoAlgorithmParameters> parameters = JSCryptoAlgorithmDictionary::createParametersForDigest(exec, algorithm->identifier(), exec->uncheckedArgument(0));
     258    auto parameters = JSCryptoAlgorithmDictionary::createParametersForDigest(exec, algorithm->identifier(), exec->uncheckedArgument(0));
    93259    if (!parameters) {
    94260        ASSERT(exec->hadException());
     
    115281}
    116282
     283JSValue JSSubtleCrypto::importKey(JSC::ExecState* exec)
     284{
     285    if (exec->argumentCount() < 3)
     286        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
     287
     288    CryptoKeyFormat keyFormat;
     289    if (!cryptoKeyFormatFromJSValue(exec, exec->argument(0), keyFormat)) {
     290        ASSERT(exec->hadException());
     291        return jsUndefined();
     292    }
     293
     294    CryptoOperationData data;
     295    if (!cryptoOperationDataFromJSValue(exec, exec->uncheckedArgument(1), data)) {
     296        ASSERT(exec->hadException());
     297        return jsUndefined();
     298    }
     299
     300    std::unique_ptr<CryptoAlgorithm> algorithm;
     301    if (!exec->uncheckedArgument(2).isNull()) {
     302        algorithm = createAlgorithmFromJSValue(exec, exec->uncheckedArgument(2));
     303        if (!algorithm) {
     304            ASSERT(exec->hadException());
     305            return jsUndefined();
     306        }
     307    }
     308    // The algorithm can presumably be null when we can deduce it from the key (JWE perhaps?)
     309    // But we only support raw key format right now.
     310    if (!algorithm) {
     311        setDOMException(exec, NOT_SUPPORTED_ERR);
     312        return jsUndefined();
     313    }
     314
     315    auto parameters = JSCryptoAlgorithmDictionary::createParametersForImportKey(exec, algorithm->identifier(), exec->uncheckedArgument(2));
     316    if (!parameters) {
     317        ASSERT(exec->hadException());
     318        return jsUndefined();
     319    }
     320
     321    bool extractable = false;
     322    if (exec->argumentCount() >= 4) {
     323        extractable = exec->uncheckedArgument(3).toBoolean(exec);
     324        if (exec->hadException())
     325            return jsUndefined();
     326    }
     327
     328    CryptoKeyUsage keyUsages = 0;
     329    if (exec->argumentCount() >= 5) {
     330        if (!cryptoKeyUsagesFromJSValue(exec, exec->argument(4), keyUsages)) {
     331            ASSERT(exec->hadException());
     332            return jsUndefined();
     333        }
     334    }
     335
     336    JSPromise* promise = JSPromise::createWithResolver(exec->vm(), globalObject());
     337    auto promiseWrapper = PromiseWrapper::create(globalObject(), promise);
     338
     339    ExceptionCode ec = 0;
     340    algorithm->importKey(*parameters, keyFormat, data, extractable, keyUsages, std::move(promiseWrapper), ec);
     341    if (ec) {
     342        setDOMException(exec, ec);
     343        return jsUndefined();
     344    }
     345
     346    return promise;
     347}
     348
    117349} // namespace WebCore
    118350
  • trunk/Source/WebCore/crypto/SubtleCrypto.idl

    r158387 r158427  
    3131    OperationsNotDeletable
    3232] interface SubtleCrypto {
     33    [Custom] Promise sign(AlgorithmIdentifier algorithm, Key key, sequence<CryptoOperationData> data);
     34    [Custom] Promise verify(AlgorithmIdentifier algorithm, Key key, CryptoOperationData signature, sequence<CryptoOperationData> data);
    3335    [Custom] Promise digest(AlgorithmIdentifier algorithm, sequence<CryptoOperationData> data);
     36    [Custom] Promise importKey(KeyFormat format, CryptoOperationData keyData, AlgorithmIdentifier? algorithm, optional boolean extractable, optional KeyUsage[] keyUsages);
    3437};
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmHMAC.cpp

    r158425 r158427  
    2525
    2626#include "config.h"
    27 #include "CryptoAlgorithmRegistry.h"
     27#include "CryptoAlgorithmHMAC.h"
    2828
    2929#if ENABLE(SUBTLE_CRYPTO)
    3030
    31 //#include "CryptoAlgorithmHMAC.h"
    32 #include "CryptoAlgorithmSHA1.h"
     31#include "CryptoAlgorithmHmacParams.h"
     32#include "CryptoKeyHMAC.h"
     33#include "ExceptionCode.h"
     34#include "JSDOMPromise.h"
    3335
    3436namespace WebCore {
    3537
    36 void CryptoAlgorithmRegistry::platformRegisterAlgorithms()
     38const char* const CryptoAlgorithmHMAC::s_name = "hmac";
     39
     40CryptoAlgorithmHMAC::CryptoAlgorithmHMAC()
    3741{
    38 //    registerAlgorithm(CryptoAlgorithmHMAC::s_name, CryptoAlgorithmHMAC::s_identifier, CryptoAlgorithmHMAC::create);
    39     registerAlgorithm(CryptoAlgorithmSHA1::s_name, CryptoAlgorithmSHA1::s_identifier, CryptoAlgorithmSHA1::create);
     42}
     43
     44CryptoAlgorithmHMAC::~CryptoAlgorithmHMAC()
     45{
     46}
     47
     48std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmHMAC::create()
     49{
     50    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmHMAC);
     51}
     52
     53CryptoAlgorithmIdentifier CryptoAlgorithmHMAC::identifier() const
     54{
     55    return s_identifier;
     56}
     57
     58void CryptoAlgorithmHMAC::importKey(const CryptoAlgorithmParameters& parameters, CryptoKeyFormat format, const CryptoOperationData& data, bool extractable, CryptoKeyUsage usage, std::unique_ptr<PromiseWrapper> promise, ExceptionCode& ec)
     59{
     60    if (format != CryptoKeyFormat::Raw) {
     61        ec = NOT_SUPPORTED_ERR;
     62        return;
     63    }
     64    const CryptoAlgorithmHmacParams& hmacParameters = static_cast<const CryptoAlgorithmHmacParams&>(parameters);
     65    Vector<char> keyData;
     66    keyData.append(data.first, data.second);
     67    RefPtr<CryptoKeyHMAC> result = CryptoKeyHMAC::create(keyData, hmacParameters.hash, extractable, usage);
     68    promise->fulfill(result.release());
     69}
     70
     71void CryptoAlgorithmHMAC::exportKey(const CryptoAlgorithmParameters&, CryptoKeyFormat, const CryptoKey&, std::unique_ptr<PromiseWrapper>, ExceptionCode& ec)
     72{
     73    // Not implemented yet.
     74    ec = NOT_SUPPORTED_ERR;
    4075}
    4176
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmHMAC.h

    r158425 r158427  
    2424 */
    2525
    26 #include "config.h"
    27 #include "CryptoAlgorithmRegistry.h"
     26#ifndef CryptoAlgorithmHMAC_h
     27#define CryptoAlgorithmHMAC_h
     28
     29#include "CryptoAlgorithm.h"
    2830
    2931#if ENABLE(SUBTLE_CRYPTO)
    3032
    31 //#include "CryptoAlgorithmHMAC.h"
    32 #include "CryptoAlgorithmSHA1.h"
    33 
    3433namespace WebCore {
    3534
    36 void CryptoAlgorithmRegistry::platformRegisterAlgorithms()
    37 {
    38 //    registerAlgorithm(CryptoAlgorithmHMAC::s_name, CryptoAlgorithmHMAC::s_identifier, CryptoAlgorithmHMAC::create);
    39     registerAlgorithm(CryptoAlgorithmSHA1::s_name, CryptoAlgorithmSHA1::s_identifier, CryptoAlgorithmSHA1::create);
    40 }
     35class CryptoAlgorithmHMAC FINAL : public CryptoAlgorithm {
     36public:
     37    static const char* const s_name;
     38    static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::HMAC;
     39
     40    static std::unique_ptr<CryptoAlgorithm> create();
     41
     42    virtual CryptoAlgorithmIdentifier identifier() const OVERRIDE;
     43
     44    virtual void sign(const CryptoAlgorithmParameters&, const CryptoKey&, const Vector<CryptoOperationData>&, std::unique_ptr<PromiseWrapper>, ExceptionCode&) OVERRIDE;
     45    virtual void verify(const CryptoAlgorithmParameters&, const CryptoKey&, const CryptoOperationData& signature, const Vector<CryptoOperationData>& data, std::unique_ptr<PromiseWrapper>, ExceptionCode&) OVERRIDE;
     46    virtual void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsage, std::unique_ptr<PromiseWrapper>, ExceptionCode&) OVERRIDE;
     47    virtual void importKey(const CryptoAlgorithmParameters&, CryptoKeyFormat, const CryptoOperationData&, bool extractable, CryptoKeyUsage, std::unique_ptr<PromiseWrapper>, ExceptionCode&) OVERRIDE;
     48    virtual void exportKey(const CryptoAlgorithmParameters&, CryptoKeyFormat, const CryptoKey&, std::unique_ptr<PromiseWrapper>, ExceptionCode&) OVERRIDE;
     49
     50private:
     51    CryptoAlgorithmHMAC();
     52    virtual ~CryptoAlgorithmHMAC();
     53};
    4154
    4255}
    4356
    4457#endif // ENABLE(SUBTLE_CRYPTO)
     58
     59
     60#endif // CryptoAlgorithmHMAC_h
  • trunk/Source/WebCore/crypto/keys/CryptoKeyHMAC.cpp

    r158425 r158427  
    2525
    2626#include "config.h"
    27 #include "CryptoAlgorithmRegistry.h"
     27#include "CryptoKeyHMAC.h"
    2828
    2929#if ENABLE(SUBTLE_CRYPTO)
    3030
    31 //#include "CryptoAlgorithmHMAC.h"
    32 #include "CryptoAlgorithmSHA1.h"
     31#include "CryptoAlgorithmDescriptionBuilder.h"
     32#include "CryptoAlgorithmRegistry.h"
     33#include <wtf/text/WTFString.h>
    3334
    3435namespace WebCore {
    3536
    36 void CryptoAlgorithmRegistry::platformRegisterAlgorithms()
     37CryptoKeyHMAC::CryptoKeyHMAC(const Vector<char>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsage usage)
     38    : CryptoKey(CryptoAlgorithmIdentifier::HMAC, CryptoKeyType::Secret, extractable, usage)
     39    , m_hash(hash)
     40    , m_key(key)
    3741{
    38 //    registerAlgorithm(CryptoAlgorithmHMAC::s_name, CryptoAlgorithmHMAC::s_identifier, CryptoAlgorithmHMAC::create);
    39     registerAlgorithm(CryptoAlgorithmSHA1::s_name, CryptoAlgorithmSHA1::s_identifier, CryptoAlgorithmSHA1::create);
    4042}
    4143
     44CryptoKeyHMAC::~CryptoKeyHMAC()
     45{
    4246}
    4347
     48void CryptoKeyHMAC::buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder& builder) const
     49{
     50    CryptoKey::buildAlgorithmDescription(builder);
     51
     52    auto hashDescriptionBuilder = builder.createEmptyClone();
     53    hashDescriptionBuilder->add("name", CryptoAlgorithmRegistry::shared().nameForIdentifier(m_hash));
     54    builder.add("hash", *hashDescriptionBuilder);
     55
     56    builder.add("length", m_key.size());
     57}
     58
     59} // namespace WebCore
     60
    4461#endif // ENABLE(SUBTLE_CRYPTO)
  • trunk/Source/WebCore/crypto/keys/CryptoKeyHMAC.h

    r158425 r158427  
    2424 */
    2525
    26 #include "config.h"
    27 #include "CryptoAlgorithmRegistry.h"
     26#ifndef CryptoKeyHMAC_h
     27#define CryptoKeyHMAC_h
     28
     29#include "CryptoKey.h"
     30#include <wtf/Ref.h>
     31#include <wtf/Vector.h>
    2832
    2933#if ENABLE(SUBTLE_CRYPTO)
    3034
    31 //#include "CryptoAlgorithmHMAC.h"
    32 #include "CryptoAlgorithmSHA1.h"
    33 
    3435namespace WebCore {
    3536
    36 void CryptoAlgorithmRegistry::platformRegisterAlgorithms()
    37 {
    38 //    registerAlgorithm(CryptoAlgorithmHMAC::s_name, CryptoAlgorithmHMAC::s_identifier, CryptoAlgorithmHMAC::create);
    39     registerAlgorithm(CryptoAlgorithmSHA1::s_name, CryptoAlgorithmSHA1::s_identifier, CryptoAlgorithmSHA1::create);
    40 }
     37class CryptoKeyHMAC FINAL : public CryptoKey {
     38public:
     39    static PassRefPtr<CryptoKeyHMAC> create(const Vector<char>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsage usage)
     40    {
     41        return adoptRef(new CryptoKeyHMAC(key, hash, extractable, usage));
     42    }
     43    virtual ~CryptoKeyHMAC();
    4144
    42 }
     45    const Vector<char>& key() const { return m_key; }
     46
     47    virtual void buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder&) const OVERRIDE;
     48
     49private:
     50    CryptoKeyHMAC(const Vector<char>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsage);
     51
     52    CryptoAlgorithmIdentifier m_hash;
     53    Vector<char> m_key;
     54};
     55
     56} // namespace WebCore
    4357
    4458#endif // ENABLE(SUBTLE_CRYPTO)
     59#endif // CryptoKeyHMAC_h
  • trunk/Source/WebCore/crypto/mac/CryptoAlgorithmRegistryMac.cpp

    r158387 r158427  
    2929#if ENABLE(SUBTLE_CRYPTO)
    3030
    31 //#include "CryptoAlgorithmHMAC.h"
     31#include "CryptoAlgorithmHMAC.h"
    3232#include "CryptoAlgorithmSHA1.h"
    3333
     
    3636void CryptoAlgorithmRegistry::platformRegisterAlgorithms()
    3737{
    38 //    registerAlgorithm(CryptoAlgorithmHMAC::s_name, CryptoAlgorithmHMAC::s_identifier, CryptoAlgorithmHMAC::create);
     38    registerAlgorithm(CryptoAlgorithmHMAC::s_name, CryptoAlgorithmHMAC::s_identifier, CryptoAlgorithmHMAC::create);
    3939    registerAlgorithm(CryptoAlgorithmSHA1::s_name, CryptoAlgorithmSHA1::s_identifier, CryptoAlgorithmSHA1::create);
    4040}
Note: See TracChangeset for help on using the changeset viewer.