1/*
2 * Copyright (C) 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "JSCryptoAlgorithmDictionary.h"
28
29#if ENABLE(SUBTLE_CRYPTO)
30
31#include "CryptoAlgorithmAesCbcParams.h"
32#include "CryptoAlgorithmAesKeyGenParams.h"
33#include "CryptoAlgorithmHmacKeyParams.h"
34#include "CryptoAlgorithmHmacParams.h"
35#include "CryptoAlgorithmRegistry.h"
36#include "CryptoAlgorithmRsaKeyGenParams.h"
37#include "CryptoAlgorithmRsaKeyParamsWithHash.h"
38#include "CryptoAlgorithmRsaOaepParams.h"
39#include "CryptoAlgorithmRsaSsaParams.h"
40#include "ExceptionCode.h"
41#include "JSCryptoOperationData.h"
42#include "JSDOMBinding.h"
43#include "JSDictionary.h"
44
45using namespace JSC;
46
47namespace WebCore {
48
49bool JSCryptoAlgorithmDictionary::getAlgorithmIdentifier(ExecState* exec, JSValue value, CryptoAlgorithmIdentifier& algorithmIdentifier)
50{
51    // typedef (Algorithm or DOMString) AlgorithmIdentifier;
52
53    String algorithmName;
54
55    if (value.isString())
56        algorithmName = value.toString(exec)->value(exec);
57    else if (value.isObject()) {
58        if (value.getObject()->inherits(StringObject::info()))
59            algorithmName = asString(asStringObject(value)->internalValue())->value(exec);
60        else {
61            // FIXME: This doesn't perform some checks mandated by WebIDL for dictionaries:
62            // - null and undefined input should be treated as if all elements in the dictionary were undefined;
63            // - undefined elements should be treated as having a default value, or as not present if there isn't such;
64            // - RegExp and Date objects cannot be converted to dictionaries.
65            //
66            // This is partially because we don't implement it elsewhere in WebCore yet, and partially because
67            // WebCrypto doesn't yet clearly specify what to do with non-present values in most cases anyway.
68
69            JSDictionary dictionary(exec, value.getObject());
70            dictionary.get("name", algorithmName);
71        }
72    }
73
74    if (exec->hadException())
75        return false;
76
77    if (!algorithmName.containsOnlyASCII()) {
78        throwSyntaxError(exec);
79        return false;
80    }
81
82    if (!CryptoAlgorithmRegistry::shared().getIdentifierForName(algorithmName, algorithmIdentifier)) {
83        setDOMException(exec, NOT_SUPPORTED_ERR);
84        return false;
85    }
86
87    return true;
88}
89
90static JSValue getProperty(ExecState* exec, JSObject* object, const char* name)
91{
92    Identifier identifier(exec, name);
93    PropertySlot slot(object);
94
95    if (object->getPropertySlot(exec, identifier, slot))
96        return slot.getValue(exec, identifier);
97
98    return jsUndefined();
99}
100
101static bool getHashAlgorithm(JSDictionary& dictionary, CryptoAlgorithmIdentifier& result)
102{
103    // FXIME: Teach JSDictionary how to return JSValues, and use that to get hash element value.
104
105    ExecState* exec = dictionary.execState();
106    JSObject* object = dictionary.initializerObject();
107
108    Identifier identifier(exec, "hash");
109    PropertySlot slot(object);
110
111    JSValue hash = getProperty(exec, object, "hash");
112    if (exec->hadException())
113        return false;
114
115    if (hash.isUndefinedOrNull()) {
116        setDOMException(exec, NOT_SUPPORTED_ERR);
117        return false;
118    }
119
120    return JSCryptoAlgorithmDictionary::getAlgorithmIdentifier(exec, hash, result);
121}
122
123static std::unique_ptr<CryptoAlgorithmParameters> createAesCbcParams(ExecState* exec, JSValue value)
124{
125    if (!value.isObject()) {
126        throwTypeError(exec);
127        return nullptr;
128    }
129
130    JSValue iv = getProperty(exec, value.getObject(), "iv");
131    if (exec->hadException())
132        return nullptr;
133
134    auto result = std::make_unique<CryptoAlgorithmAesCbcParams>();
135
136    CryptoOperationData ivData;
137    if (!cryptoOperationDataFromJSValue(exec, iv, ivData)) {
138        ASSERT(exec->hadException());
139        return nullptr;
140    }
141
142    if (ivData.second != 16) {
143        exec->vm().throwException(exec, createError(exec, "AES-CBC initialization data must be 16 bytes"));
144        return nullptr;
145    }
146
147    memcpy(result->iv.data(), ivData.first, ivData.second);
148
149    return WTF::move(result);
150}
151
152static std::unique_ptr<CryptoAlgorithmParameters> createAesKeyGenParams(ExecState* exec, JSValue value)
153{
154    if (!value.isObject()) {
155        throwTypeError(exec);
156        return nullptr;
157    }
158
159    auto result = std::make_unique<CryptoAlgorithmAesKeyGenParams>();
160
161    JSValue lengthValue = getProperty(exec, value.getObject(), "length");
162    if (exec->hadException())
163        return nullptr;
164
165    result->length = toUInt16(exec, lengthValue, EnforceRange);
166
167    return WTF::move(result);
168}
169
170static std::unique_ptr<CryptoAlgorithmParameters> createHmacParams(ExecState* exec, JSValue value)
171{
172    if (!value.isObject()) {
173        throwTypeError(exec);
174        return nullptr;
175    }
176
177    JSDictionary jsDictionary(exec, value.getObject());
178    auto result = std::make_unique<CryptoAlgorithmHmacParams>();
179
180    if (!getHashAlgorithm(jsDictionary, result->hash)) {
181        ASSERT(exec->hadException());
182        return nullptr;
183    }
184
185    return WTF::move(result);
186}
187
188static std::unique_ptr<CryptoAlgorithmParameters> createHmacKeyParams(ExecState* exec, JSValue value)
189{
190    if (!value.isObject()) {
191        throwTypeError(exec);
192        return nullptr;
193    }
194
195    JSDictionary jsDictionary(exec, value.getObject());
196    auto result = std::make_unique<CryptoAlgorithmHmacKeyParams>();
197
198    if (!getHashAlgorithm(jsDictionary, result->hash)) {
199        ASSERT(exec->hadException());
200        return nullptr;
201    }
202
203    result->hasLength = jsDictionary.get("length", result->length);
204    if (exec->hadException())
205        return nullptr;
206
207    return WTF::move(result);
208}
209
210static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecState* exec, JSValue value)
211{
212    if (!value.isObject()) {
213        throwTypeError(exec);
214        return nullptr;
215    }
216
217    auto result = std::make_unique<CryptoAlgorithmRsaKeyGenParams>();
218
219    JSValue modulusLengthValue = getProperty(exec, value.getObject(), "modulusLength");
220    if (exec->hadException())
221        return nullptr;
222
223    // FIXME: Why no EnforceRange? Filed as <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23779>.
224    result->modulusLength = toUInt32(exec, modulusLengthValue, NormalConversion);
225    if (exec->hadException())
226        return nullptr;
227
228    JSValue publicExponentValue = getProperty(exec, value.getObject(), "publicExponent");
229    if (exec->hadException())
230        return nullptr;
231
232    RefPtr<Uint8Array> publicExponentArray = toUint8Array(publicExponentValue);
233    if (!publicExponentArray) {
234        throwTypeError(exec, "Expected a Uint8Array in publicExponent");
235        return nullptr;
236    }
237    result->publicExponent.append(publicExponentArray->data(), publicExponentArray->byteLength());
238
239    return WTF::move(result);
240}
241
242static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyParamsWithHash(ExecState*, JSValue)
243{
244    // WebCrypto RSA algorithms currently do not take any parameters to importKey.
245    return std::make_unique<CryptoAlgorithmRsaKeyParamsWithHash>();
246}
247
248static std::unique_ptr<CryptoAlgorithmParameters> createRsaOaepParams(ExecState* exec, JSValue value)
249{
250    if (!value.isObject()) {
251        throwTypeError(exec);
252        return nullptr;
253    }
254
255    JSDictionary jsDictionary(exec, value.getObject());
256    auto result = std::make_unique<CryptoAlgorithmRsaOaepParams>();
257
258    if (!getHashAlgorithm(jsDictionary, result->hash)) {
259        ASSERT(exec->hadException());
260        return nullptr;
261    }
262
263    JSValue labelValue = getProperty(exec, value.getObject(), "label");
264    if (exec->hadException())
265        return nullptr;
266
267    result->hasLabel = !labelValue.isUndefinedOrNull();
268    if (!result->hasLabel)
269        return WTF::move(result);
270
271    CryptoOperationData labelData;
272    if (!cryptoOperationDataFromJSValue(exec, labelValue, labelData)) {
273        ASSERT(exec->hadException());
274        return nullptr;
275    }
276
277    result->label.append(labelData.first, labelData.second);
278
279    return WTF::move(result);
280}
281
282static std::unique_ptr<CryptoAlgorithmParameters> createRsaSsaParams(ExecState* exec, JSValue value)
283{
284    if (!value.isObject()) {
285        throwTypeError(exec);
286        return nullptr;
287    }
288
289    JSDictionary jsDictionary(exec, value.getObject());
290    auto result = std::make_unique<CryptoAlgorithmRsaSsaParams>();
291
292    if (!getHashAlgorithm(jsDictionary, result->hash)) {
293        ASSERT(exec->hadException());
294        return nullptr;
295    }
296
297    return WTF::move(result);
298}
299
300std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForEncrypt(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
301{
302    switch (algorithm) {
303    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
304        return std::make_unique<CryptoAlgorithmParameters>();
305    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
306    case CryptoAlgorithmIdentifier::RSA_PSS:
307        setDOMException(exec, NOT_SUPPORTED_ERR);
308        return nullptr;
309    case CryptoAlgorithmIdentifier::RSA_OAEP:
310        return createRsaOaepParams(exec, value);
311    case CryptoAlgorithmIdentifier::ECDSA:
312    case CryptoAlgorithmIdentifier::ECDH:
313    case CryptoAlgorithmIdentifier::AES_CTR:
314        setDOMException(exec, NOT_SUPPORTED_ERR);
315        return nullptr;
316    case CryptoAlgorithmIdentifier::AES_CBC:
317        return createAesCbcParams(exec, value);
318    case CryptoAlgorithmIdentifier::AES_CMAC:
319    case CryptoAlgorithmIdentifier::AES_GCM:
320    case CryptoAlgorithmIdentifier::AES_CFB:
321        setDOMException(exec, NOT_SUPPORTED_ERR);
322        return nullptr;
323    case CryptoAlgorithmIdentifier::AES_KW:
324        return std::make_unique<CryptoAlgorithmParameters>();
325    case CryptoAlgorithmIdentifier::HMAC:
326    case CryptoAlgorithmIdentifier::DH:
327    case CryptoAlgorithmIdentifier::SHA_1:
328    case CryptoAlgorithmIdentifier::SHA_224:
329    case CryptoAlgorithmIdentifier::SHA_256:
330    case CryptoAlgorithmIdentifier::SHA_384:
331    case CryptoAlgorithmIdentifier::SHA_512:
332    case CryptoAlgorithmIdentifier::CONCAT:
333    case CryptoAlgorithmIdentifier::HKDF_CTR:
334    case CryptoAlgorithmIdentifier::PBKDF2:
335        setDOMException(exec, NOT_SUPPORTED_ERR);
336        return nullptr;
337    }
338}
339
340std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDecrypt(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
341{
342    switch (algorithm) {
343    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
344        return std::make_unique<CryptoAlgorithmParameters>();
345    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
346    case CryptoAlgorithmIdentifier::RSA_PSS:
347        setDOMException(exec, NOT_SUPPORTED_ERR);
348        return nullptr;
349    case CryptoAlgorithmIdentifier::RSA_OAEP:
350        return createRsaOaepParams(exec, value);
351    case CryptoAlgorithmIdentifier::ECDSA:
352    case CryptoAlgorithmIdentifier::ECDH:
353    case CryptoAlgorithmIdentifier::AES_CTR:
354        setDOMException(exec, NOT_SUPPORTED_ERR);
355        return nullptr;
356    case CryptoAlgorithmIdentifier::AES_CBC:
357        return createAesCbcParams(exec, value);
358    case CryptoAlgorithmIdentifier::AES_CMAC:
359    case CryptoAlgorithmIdentifier::AES_GCM:
360    case CryptoAlgorithmIdentifier::AES_CFB:
361        setDOMException(exec, NOT_SUPPORTED_ERR);
362        return nullptr;
363    case CryptoAlgorithmIdentifier::AES_KW:
364        return std::make_unique<CryptoAlgorithmParameters>();
365    case CryptoAlgorithmIdentifier::HMAC:
366    case CryptoAlgorithmIdentifier::DH:
367    case CryptoAlgorithmIdentifier::SHA_1:
368    case CryptoAlgorithmIdentifier::SHA_224:
369    case CryptoAlgorithmIdentifier::SHA_256:
370    case CryptoAlgorithmIdentifier::SHA_384:
371    case CryptoAlgorithmIdentifier::SHA_512:
372    case CryptoAlgorithmIdentifier::CONCAT:
373    case CryptoAlgorithmIdentifier::HKDF_CTR:
374    case CryptoAlgorithmIdentifier::PBKDF2:
375        setDOMException(exec, NOT_SUPPORTED_ERR);
376        return nullptr;
377    }
378}
379
380std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForSign(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
381{
382    switch (algorithm) {
383    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
384        setDOMException(exec, NOT_SUPPORTED_ERR);
385        return nullptr;
386    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
387        return createRsaSsaParams(exec, value);
388    case CryptoAlgorithmIdentifier::RSA_PSS:
389    case CryptoAlgorithmIdentifier::RSA_OAEP:
390    case CryptoAlgorithmIdentifier::ECDSA:
391    case CryptoAlgorithmIdentifier::ECDH:
392    case CryptoAlgorithmIdentifier::AES_CTR:
393    case CryptoAlgorithmIdentifier::AES_CBC:
394    case CryptoAlgorithmIdentifier::AES_CMAC:
395    case CryptoAlgorithmIdentifier::AES_GCM:
396    case CryptoAlgorithmIdentifier::AES_CFB:
397    case CryptoAlgorithmIdentifier::AES_KW:
398        setDOMException(exec, NOT_SUPPORTED_ERR);
399        return nullptr;
400    case CryptoAlgorithmIdentifier::HMAC:
401        return createHmacParams(exec, value);
402    case CryptoAlgorithmIdentifier::DH:
403    case CryptoAlgorithmIdentifier::SHA_1:
404    case CryptoAlgorithmIdentifier::SHA_224:
405    case CryptoAlgorithmIdentifier::SHA_256:
406    case CryptoAlgorithmIdentifier::SHA_384:
407    case CryptoAlgorithmIdentifier::SHA_512:
408    case CryptoAlgorithmIdentifier::CONCAT:
409    case CryptoAlgorithmIdentifier::HKDF_CTR:
410    case CryptoAlgorithmIdentifier::PBKDF2:
411        setDOMException(exec, NOT_SUPPORTED_ERR);
412        return nullptr;
413    }
414}
415
416std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForVerify(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
417{
418    switch (algorithm) {
419    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
420        setDOMException(exec, NOT_SUPPORTED_ERR);
421        return nullptr;
422    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
423        return createRsaSsaParams(exec, value);
424    case CryptoAlgorithmIdentifier::RSA_PSS:
425    case CryptoAlgorithmIdentifier::RSA_OAEP:
426    case CryptoAlgorithmIdentifier::ECDSA:
427    case CryptoAlgorithmIdentifier::ECDH:
428    case CryptoAlgorithmIdentifier::AES_CTR:
429    case CryptoAlgorithmIdentifier::AES_CBC:
430    case CryptoAlgorithmIdentifier::AES_CMAC:
431    case CryptoAlgorithmIdentifier::AES_GCM:
432    case CryptoAlgorithmIdentifier::AES_CFB:
433    case CryptoAlgorithmIdentifier::AES_KW:
434        setDOMException(exec, NOT_SUPPORTED_ERR);
435        return nullptr;
436    case CryptoAlgorithmIdentifier::HMAC:
437        return createHmacParams(exec, value);
438    case CryptoAlgorithmIdentifier::DH:
439    case CryptoAlgorithmIdentifier::SHA_1:
440    case CryptoAlgorithmIdentifier::SHA_224:
441    case CryptoAlgorithmIdentifier::SHA_256:
442    case CryptoAlgorithmIdentifier::SHA_384:
443    case CryptoAlgorithmIdentifier::SHA_512:
444    case CryptoAlgorithmIdentifier::CONCAT:
445    case CryptoAlgorithmIdentifier::HKDF_CTR:
446    case CryptoAlgorithmIdentifier::PBKDF2:
447        setDOMException(exec, NOT_SUPPORTED_ERR);
448        return nullptr;
449    }
450}
451
452std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDigest(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
453{
454    switch (algorithm) {
455    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
456    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
457    case CryptoAlgorithmIdentifier::RSA_PSS:
458    case CryptoAlgorithmIdentifier::RSA_OAEP:
459    case CryptoAlgorithmIdentifier::ECDSA:
460    case CryptoAlgorithmIdentifier::ECDH:
461    case CryptoAlgorithmIdentifier::AES_CTR:
462    case CryptoAlgorithmIdentifier::AES_CBC:
463    case CryptoAlgorithmIdentifier::AES_CMAC:
464    case CryptoAlgorithmIdentifier::AES_GCM:
465    case CryptoAlgorithmIdentifier::AES_CFB:
466    case CryptoAlgorithmIdentifier::AES_KW:
467    case CryptoAlgorithmIdentifier::HMAC:
468    case CryptoAlgorithmIdentifier::DH:
469        setDOMException(exec, NOT_SUPPORTED_ERR);
470        return nullptr;
471    case CryptoAlgorithmIdentifier::SHA_1:
472    case CryptoAlgorithmIdentifier::SHA_224:
473    case CryptoAlgorithmIdentifier::SHA_256:
474    case CryptoAlgorithmIdentifier::SHA_384:
475    case CryptoAlgorithmIdentifier::SHA_512:
476        return std::make_unique<CryptoAlgorithmParameters>();
477    case CryptoAlgorithmIdentifier::CONCAT:
478    case CryptoAlgorithmIdentifier::HKDF_CTR:
479    case CryptoAlgorithmIdentifier::PBKDF2:
480        setDOMException(exec, NOT_SUPPORTED_ERR);
481        return nullptr;
482    }
483}
484
485std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForGenerateKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
486{
487    switch (algorithm) {
488    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
489    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
490    case CryptoAlgorithmIdentifier::RSA_PSS:
491    case CryptoAlgorithmIdentifier::RSA_OAEP:
492        return createRsaKeyGenParams(exec, value);
493    case CryptoAlgorithmIdentifier::ECDSA:
494    case CryptoAlgorithmIdentifier::ECDH:
495        setDOMException(exec, NOT_SUPPORTED_ERR);
496        return nullptr;
497    case CryptoAlgorithmIdentifier::AES_CTR:
498    case CryptoAlgorithmIdentifier::AES_CBC:
499    case CryptoAlgorithmIdentifier::AES_CMAC:
500    case CryptoAlgorithmIdentifier::AES_GCM:
501    case CryptoAlgorithmIdentifier::AES_CFB:
502    case CryptoAlgorithmIdentifier::AES_KW:
503        return createAesKeyGenParams(exec, value);
504    case CryptoAlgorithmIdentifier::HMAC:
505        return createHmacKeyParams(exec, value);
506    case CryptoAlgorithmIdentifier::DH:
507    case CryptoAlgorithmIdentifier::SHA_1:
508    case CryptoAlgorithmIdentifier::SHA_224:
509    case CryptoAlgorithmIdentifier::SHA_256:
510    case CryptoAlgorithmIdentifier::SHA_384:
511    case CryptoAlgorithmIdentifier::SHA_512:
512    case CryptoAlgorithmIdentifier::CONCAT:
513    case CryptoAlgorithmIdentifier::HKDF_CTR:
514    case CryptoAlgorithmIdentifier::PBKDF2:
515        setDOMException(exec, NOT_SUPPORTED_ERR);
516        return nullptr;
517    }
518}
519
520std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
521{
522    switch (algorithm) {
523    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
524    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
525    case CryptoAlgorithmIdentifier::RSA_PSS:
526    case CryptoAlgorithmIdentifier::RSA_OAEP:
527    case CryptoAlgorithmIdentifier::ECDSA:
528    case CryptoAlgorithmIdentifier::ECDH:
529    case CryptoAlgorithmIdentifier::AES_CTR:
530    case CryptoAlgorithmIdentifier::AES_CBC:
531    case CryptoAlgorithmIdentifier::AES_CMAC:
532    case CryptoAlgorithmIdentifier::AES_GCM:
533    case CryptoAlgorithmIdentifier::AES_CFB:
534    case CryptoAlgorithmIdentifier::AES_KW:
535    case CryptoAlgorithmIdentifier::HMAC:
536    case CryptoAlgorithmIdentifier::DH:
537    case CryptoAlgorithmIdentifier::SHA_1:
538    case CryptoAlgorithmIdentifier::SHA_224:
539    case CryptoAlgorithmIdentifier::SHA_256:
540    case CryptoAlgorithmIdentifier::SHA_384:
541    case CryptoAlgorithmIdentifier::SHA_512:
542    case CryptoAlgorithmIdentifier::CONCAT:
543    case CryptoAlgorithmIdentifier::HKDF_CTR:
544    case CryptoAlgorithmIdentifier::PBKDF2:
545        setDOMException(exec, NOT_SUPPORTED_ERR);
546        return nullptr;
547    }
548}
549
550std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveBits(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
551{
552    switch (algorithm) {
553    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
554    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
555    case CryptoAlgorithmIdentifier::RSA_PSS:
556    case CryptoAlgorithmIdentifier::RSA_OAEP:
557    case CryptoAlgorithmIdentifier::ECDSA:
558    case CryptoAlgorithmIdentifier::ECDH:
559    case CryptoAlgorithmIdentifier::AES_CTR:
560    case CryptoAlgorithmIdentifier::AES_CBC:
561    case CryptoAlgorithmIdentifier::AES_CMAC:
562    case CryptoAlgorithmIdentifier::AES_GCM:
563    case CryptoAlgorithmIdentifier::AES_CFB:
564    case CryptoAlgorithmIdentifier::AES_KW:
565    case CryptoAlgorithmIdentifier::HMAC:
566    case CryptoAlgorithmIdentifier::DH:
567    case CryptoAlgorithmIdentifier::SHA_1:
568    case CryptoAlgorithmIdentifier::SHA_224:
569    case CryptoAlgorithmIdentifier::SHA_256:
570    case CryptoAlgorithmIdentifier::SHA_384:
571    case CryptoAlgorithmIdentifier::SHA_512:
572    case CryptoAlgorithmIdentifier::CONCAT:
573    case CryptoAlgorithmIdentifier::HKDF_CTR:
574    case CryptoAlgorithmIdentifier::PBKDF2:
575        setDOMException(exec, NOT_SUPPORTED_ERR);
576        return nullptr;
577    }
578}
579
580std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForImportKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
581{
582    switch (algorithm) {
583    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
584        return std::make_unique<CryptoAlgorithmParameters>();
585    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
586        return createRsaKeyParamsWithHash(exec, value);
587    case CryptoAlgorithmIdentifier::RSA_PSS:
588        return std::make_unique<CryptoAlgorithmParameters>();
589    case CryptoAlgorithmIdentifier::RSA_OAEP:
590        return createRsaKeyParamsWithHash(exec, value);
591    case CryptoAlgorithmIdentifier::ECDSA:
592    case CryptoAlgorithmIdentifier::ECDH:
593    case CryptoAlgorithmIdentifier::AES_CTR:
594    case CryptoAlgorithmIdentifier::AES_CBC:
595    case CryptoAlgorithmIdentifier::AES_CMAC:
596    case CryptoAlgorithmIdentifier::AES_GCM:
597    case CryptoAlgorithmIdentifier::AES_CFB:
598    case CryptoAlgorithmIdentifier::AES_KW:
599        return std::make_unique<CryptoAlgorithmParameters>();
600    case CryptoAlgorithmIdentifier::HMAC:
601        return createHmacParams(exec, value);
602    case CryptoAlgorithmIdentifier::DH:
603        return std::make_unique<CryptoAlgorithmParameters>();
604    case CryptoAlgorithmIdentifier::SHA_1:
605    case CryptoAlgorithmIdentifier::SHA_224:
606    case CryptoAlgorithmIdentifier::SHA_256:
607    case CryptoAlgorithmIdentifier::SHA_384:
608    case CryptoAlgorithmIdentifier::SHA_512:
609    case CryptoAlgorithmIdentifier::CONCAT:
610    case CryptoAlgorithmIdentifier::HKDF_CTR:
611    case CryptoAlgorithmIdentifier::PBKDF2:
612        setDOMException(exec, NOT_SUPPORTED_ERR);
613        return nullptr;
614    }
615}
616
617std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForExportKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
618{
619    switch (algorithm) {
620    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
621    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
622    case CryptoAlgorithmIdentifier::RSA_PSS:
623    case CryptoAlgorithmIdentifier::RSA_OAEP:
624    case CryptoAlgorithmIdentifier::ECDSA:
625    case CryptoAlgorithmIdentifier::ECDH:
626    case CryptoAlgorithmIdentifier::AES_CTR:
627    case CryptoAlgorithmIdentifier::AES_CBC:
628    case CryptoAlgorithmIdentifier::AES_CMAC:
629    case CryptoAlgorithmIdentifier::AES_GCM:
630    case CryptoAlgorithmIdentifier::AES_CFB:
631    case CryptoAlgorithmIdentifier::AES_KW:
632    case CryptoAlgorithmIdentifier::HMAC:
633    case CryptoAlgorithmIdentifier::DH:
634        return std::make_unique<CryptoAlgorithmParameters>();
635    case CryptoAlgorithmIdentifier::SHA_1:
636    case CryptoAlgorithmIdentifier::SHA_224:
637    case CryptoAlgorithmIdentifier::SHA_256:
638    case CryptoAlgorithmIdentifier::SHA_384:
639    case CryptoAlgorithmIdentifier::SHA_512:
640    case CryptoAlgorithmIdentifier::CONCAT:
641    case CryptoAlgorithmIdentifier::HKDF_CTR:
642    case CryptoAlgorithmIdentifier::PBKDF2:
643        setDOMException(exec, NOT_SUPPORTED_ERR);
644        return nullptr;
645    }
646}
647
648}
649
650#endif // ENABLE(SUBTLE_CRYPTO)
651