aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bun.js/bindings/ScriptExecutionContext.cpp51
-rw-r--r--src/bun.js/bindings/ScriptExecutionContext.h21
-rw-r--r--src/bun.js/bindings/WebCoreOpaqueRoot.h86
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp78
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h9
-rw-r--r--src/bun.js/bindings/bindings.zig5
-rw-r--r--src/bun.js/bindings/root.h14
-rw-r--r--src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h4
-rw-r--r--src/bun.js/bindings/webcore/DOMIsoSubspaces.h4
-rw-r--r--src/bun.js/bindings/webcore/EventEmitter.cpp7
-rw-r--r--src/bun.js/bindings/webcore/EventEmitter.h4
-rw-r--r--src/bun.js/bindings/webcrypto/AesCbcCfbParams.idl35
-rw-r--r--src/bun.js/bindings/webcrypto/AesCtrParams.idl40
-rw-r--r--src/bun.js/bindings/webcrypto/AesGcmParams.idl35
-rw-r--r--src/bun.js/bindings/webcrypto/AesKeyParams.idl35
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAesKeyAlgorithm.h37
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAesKeyAlgorithm.idl32
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithm.cpp123
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithm.h86
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBC.cpp199
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBC.h66
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBCOpenSSL.cpp138
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFB.cpp199
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFB.h60
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFBOpenSSL.cpp105
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTR.cpp320
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTR.h88
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTROpenSSL.cpp145
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCM.cpp247
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCM.h60
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCMOpenSSL.cpp184
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KW.cpp189
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KW.h59
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KWOpenSSL.cpp86
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAesCbcCfbParams.h68
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAesCtrParams.h70
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAesGcmParams.h88
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmAesKeyParams.h45
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmECDH.cpp235
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmECDH.h57
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmECDHOpenSSL.cpp65
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSA.cpp223
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSA.h59
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSAOpenSSL.cpp103
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmEcKeyParams.h54
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmEcdhKeyDeriveParams.h47
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmEcdsaParams.h59
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDF.cpp86
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDF.h56
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDFOpenSSL.cpp53
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmHMAC.cpp202
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmHMAC.h60
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmHMACOpenSSL.cpp89
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmHkdfParams.h86
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmHmacKeyParams.h61
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmIdentifier.h56
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2.cpp86
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2.h56
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2OpenSSL.cpp57
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmParameters.h74
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmParameters.idl30
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmPbkdf2Params.h76
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp191
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5.h58
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5OpenSSL.cpp86
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp245
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5.h58
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5OpenSSL.cpp101
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEP.cpp261
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEP.h59
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEPOpenSSL.cpp137
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSS.cpp247
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSS.h59
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSSOpenSSL.cpp122
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistry.cpp102
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistry.h73
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistryOpenSSL.cpp78
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaHashedImportParams.h59
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaHashedKeyGenParams.h50
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaKeyGenParams.h59
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaOaepParams.h74
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaPssParams.h54
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA1.cpp65
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA1.h48
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA224.cpp65
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA224.h48
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA256.cpp65
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA256.h48
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA384.cpp65
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA384.h48
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA512.cpp65
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA512.h48
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoDigest.cpp151
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoDigest.h64
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoEcKeyAlgorithm.h38
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoEcKeyAlgorithm.idl34
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoHmacKeyAlgorithm.h41
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoHmacKeyAlgorithm.idl34
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKey.cpp88
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKey.h101
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKey.idl45
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyAES.cpp134
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyAES.h81
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyAlgorithm.h36
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyAlgorithm.idl31
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyEC.cpp234
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyEC.h122
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyECOpenSSL.cpp464
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyFormat.h41
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyHMAC.cpp153
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyHMAC.h76
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyPair.h43
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyPair.idl32
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyRSA.cpp178
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyRSA.h114
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyRSAComponents.cpp93
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyRSAComponents.h115
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyRSAOpenSSL.cpp408
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyRaw.cpp50
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyRaw.h57
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyType.h40
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyUsage.h59
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoKeyUsage.idl37
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoRsaHashedKeyAlgorithm.h38
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoRsaHashedKeyAlgorithm.idl32
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoRsaKeyAlgorithm.h41
-rw-r--r--src/bun.js/bindings/webcrypto/CryptoRsaKeyAlgorithm.idl36
-rw-r--r--src/bun.js/bindings/webcrypto/EcKeyParams.idl34
-rw-r--r--src/bun.js/bindings/webcrypto/EcdhKeyDeriveParams.idl33
-rw-r--r--src/bun.js/bindings/webcrypto/EcdsaParams.idl34
-rw-r--r--src/bun.js/bindings/webcrypto/HkdfParams.idl38
-rw-r--r--src/bun.js/bindings/webcrypto/HmacKeyParams.idl41
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.cpp85
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesCtrParams.cpp100
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesCtrParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesCtrParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesGcmParams.cpp108
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesGcmParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesGcmParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesKeyParams.cpp83
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesKeyParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSAesKeyParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.cpp101
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.h36
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.cpp68
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.dep1
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.cpp100
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.h36
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.cpp119
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.h36
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKey.cpp361
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKey.dep1
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKey.h108
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.cpp83
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.dep1
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.h36
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKeyPair.cpp99
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKeyPair.dep1
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKeyPair.h36
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKeyUsage.cpp91
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoKeyUsage.h38
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.cpp137
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.dep3
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.h36
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.cpp119
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.h36
-rw-r--r--src/bun.js/bindings/webcrypto/JSEcKeyParams.cpp82
-rw-r--r--src/bun.js/bindings/webcrypto/JSEcKeyParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSEcKeyParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.cpp84
-rw-r--r--src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSEcdsaParams.cpp85
-rw-r--r--src/bun.js/bindings/webcrypto/JSEcdsaParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSEcdsaParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSHkdfParams.cpp114
-rw-r--r--src/bun.js/bindings/webcrypto/JSHkdfParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSHkdfParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSHmacKeyParams.cpp97
-rw-r--r--src/bun.js/bindings/webcrypto/JSHmacKeyParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSHmacKeyParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSJsonWebKey.cpp361
-rw-r--r--src/bun.js/bindings/webcrypto/JSJsonWebKey.dep1
-rw-r--r--src/bun.js/bindings/webcrypto/JSJsonWebKey.h36
-rw-r--r--src/bun.js/bindings/webcrypto/JSPbkdf2Params.cpp115
-rw-r--r--src/bun.js/bindings/webcrypto/JSPbkdf2Params.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSPbkdf2Params.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.cpp85
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.cpp115
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.dep3
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.cpp98
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaOaepParams.cpp82
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaOaepParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaOaepParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.cpp117
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.dep1
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.h36
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaPssParams.cpp83
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaPssParams.dep2
-rw-r--r--src/bun.js/bindings/webcrypto/JSRsaPssParams.h34
-rw-r--r--src/bun.js/bindings/webcrypto/JSSubtleCrypto.cpp678
-rw-r--r--src/bun.js/bindings/webcrypto/JSSubtleCrypto.dep1
-rw-r--r--src/bun.js/bindings/webcrypto/JSSubtleCrypto.h104
-rw-r--r--src/bun.js/bindings/webcrypto/JsonWebKey.h63
-rw-r--r--src/bun.js/bindings/webcrypto/JsonWebKey.idl53
-rw-r--r--src/bun.js/bindings/webcrypto/OpenSSLCryptoUniquePtr.h89
-rw-r--r--src/bun.js/bindings/webcrypto/OpenSSLUtilities.cpp138
-rw-r--r--src/bun.js/bindings/webcrypto/OpenSSLUtilities.h65
-rw-r--r--src/bun.js/bindings/webcrypto/Pbkdf2Params.idl35
-rw-r--r--src/bun.js/bindings/webcrypto/RsaHashedImportParams.idl34
-rw-r--r--src/bun.js/bindings/webcrypto/RsaHashedKeyGenParams.idl34
-rw-r--r--src/bun.js/bindings/webcrypto/RsaKeyGenParams.idl34
-rw-r--r--src/bun.js/bindings/webcrypto/RsaOaepParams.idl32
-rw-r--r--src/bun.js/bindings/webcrypto/RsaOtherPrimesInfo.h42
-rw-r--r--src/bun.js/bindings/webcrypto/RsaOtherPrimesInfo.idl34
-rw-r--r--src/bun.js/bindings/webcrypto/RsaPssParams.idl32
-rw-r--r--src/bun.js/bindings/webcrypto/SerializedCryptoKeyWrap.h50
-rw-r--r--src/bun.js/bindings/webcrypto/SerializedCryptoKeyWrapOpenSSL.cpp68
-rw-r--r--src/bun.js/bindings/webcrypto/SubtleCrypto.cpp1193
-rw-r--r--src/bun.js/bindings/webcrypto/SubtleCrypto.h91
-rw-r--r--src/bun.js/bindings/webcrypto/SubtleCrypto.idl48
-rw-r--r--src/bun.js/event_loop.zig2
-rw-r--r--src/bun.js/javascript.zig19
-rw-r--r--src/bun.js/webcore.zig27
236 files changed, 18571 insertions, 40 deletions
diff --git a/src/bun.js/bindings/ScriptExecutionContext.cpp b/src/bun.js/bindings/ScriptExecutionContext.cpp
index 5b8d88871..151c66495 100644
--- a/src/bun.js/bindings/ScriptExecutionContext.cpp
+++ b/src/bun.js/bindings/ScriptExecutionContext.cpp
@@ -10,6 +10,16 @@ extern "C" void Bun__startLoop(us_loop_t* loop);
namespace WebCore {
+static unsigned lastUniqueIdentifier = 0;
+
+static Lock allScriptExecutionContextsMapLock;
+static HashMap<ScriptExecutionContextIdentifier, ScriptExecutionContext*>& allScriptExecutionContextsMap() WTF_REQUIRES_LOCK(allScriptExecutionContextsMapLock)
+{
+ static NeverDestroyed<HashMap<ScriptExecutionContextIdentifier, ScriptExecutionContext*>> contexts;
+ ASSERT(allScriptExecutionContextsMapLock.isLocked());
+ return contexts;
+}
+
template<bool SSL, bool isServer>
static void registerHTTPContextForWebSocket(ScriptExecutionContext* script, us_socket_context_t* ctx, us_loop_t* loop)
{
@@ -39,6 +49,18 @@ us_socket_context_t* ScriptExecutionContext::webSocketContextSSL()
return m_ssl_client_websockets_ctx;
}
+bool ScriptExecutionContext::postTaskTo(ScriptExecutionContextIdentifier identifier, Function<void(ScriptExecutionContext&)>&& task)
+{
+ Locker locker { allScriptExecutionContextsMapLock };
+ auto* context = allScriptExecutionContextsMap().get(identifier);
+
+ if (!context)
+ return false;
+
+ context->postTaskConcurrently(WTFMove(task));
+ return true;
+}
+
us_socket_context_t* ScriptExecutionContext::webSocketContextNoSSL()
{
if (!m_client_websockets_ctx) {
@@ -78,4 +100,31 @@ us_socket_context_t* ScriptExecutionContext::connectedWebSocketKindClientSSL()
return registerWebSocketClientContext<true>(this, webSocketContextSSL());
}
-} \ No newline at end of file
+void ScriptExecutionContext::regenerateIdentifier()
+{
+ Locker locker { allScriptExecutionContextsMapLock };
+
+ ASSERT(allScriptExecutionContextsMap().contains(m_identifier));
+ allScriptExecutionContextsMap().remove(m_identifier);
+
+ m_identifier = ++lastUniqueIdentifier;
+
+ ASSERT(!allScriptExecutionContextsMap().contains(m_identifier));
+ allScriptExecutionContextsMap().add(m_identifier, this);
+}
+
+void ScriptExecutionContext::addToContextsMap()
+{
+ Locker locker { allScriptExecutionContextsMapLock };
+ ASSERT(!allScriptExecutionContextsMap().contains(m_identifier));
+ allScriptExecutionContextsMap().add(m_identifier, this);
+}
+
+void ScriptExecutionContext::removeFromContextsMap()
+{
+ Locker locker { allScriptExecutionContextsMapLock };
+ ASSERT(allScriptExecutionContextsMap().contains(m_identifier));
+ allScriptExecutionContextsMap().remove(m_identifier);
+}
+
+}
diff --git a/src/bun.js/bindings/ScriptExecutionContext.h b/src/bun.js/bindings/ScriptExecutionContext.h
index ab86b6816..1643820dd 100644
--- a/src/bun.js/bindings/ScriptExecutionContext.h
+++ b/src/bun.js/bindings/ScriptExecutionContext.h
@@ -68,13 +68,17 @@ protected:
bool m_isCleanupTask;
};
+using ScriptExecutionContextIdentifier = uint32_t;
+
class ScriptExecutionContext : public CanMakeWeakPtr<ScriptExecutionContext> {
-public:
+
public:
ScriptExecutionContext(JSC::VM* vm, JSC::JSGlobalObject* globalObject)
: m_vm(vm)
, m_globalObject(globalObject)
+ , m_identifier(0)
{
+ regenerateIdentifier();
}
JSC::JSGlobalObject* jsGlobalObject()
@@ -106,12 +110,23 @@ public:
// {
// }
+ static bool postTaskTo(ScriptExecutionContextIdentifier identifier, Function<void(ScriptExecutionContext&)>&& task);
+
+ void regenerateIdentifier();
+ void addToContextsMap();
+ void removeFromContextsMap();
+
+ void postTaskConcurrently(Function<void(ScriptExecutionContext&)>&& lambda)
+ {
+ auto* task = new EventLoopTask(WTFMove(lambda));
+ reinterpret_cast<Zig::GlobalObject*>(m_globalObject)->queueTaskConcurrently(task);
+ } // Executes the task on context's thread asynchronously.
+
void postTask(Function<void(ScriptExecutionContext&)>&& lambda)
{
auto* task = new EventLoopTask(WTFMove(lambda));
reinterpret_cast<Zig::GlobalObject*>(m_globalObject)->queueTask(task);
} // Executes the task on context's thread asynchronously.
-
void postTask(EventLoopTask* task)
{
reinterpret_cast<Zig::GlobalObject*>(m_globalObject)->queueTask(task);
@@ -126,11 +141,13 @@ public:
}
JSC::VM& vm() { return *m_vm; }
+ ScriptExecutionContextIdentifier identifier() const { return m_identifier; }
private:
JSC::VM* m_vm = nullptr;
JSC::JSGlobalObject* m_globalObject = nullptr;
WTF::URL m_url = WTF::URL();
+ ScriptExecutionContextIdentifier m_identifier;
us_socket_context_t* webSocketContextSSL();
us_socket_context_t* webSocketContextNoSSL();
diff --git a/src/bun.js/bindings/WebCoreOpaqueRoot.h b/src/bun.js/bindings/WebCoreOpaqueRoot.h
new file mode 100644
index 000000000..93388c5c0
--- /dev/null
+++ b/src/bun.js/bindings/WebCoreOpaqueRoot.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+
+namespace WebCore {
+
+class WebCoreOpaqueRoot {
+public:
+ template<typename T, typename = typename std::enable_if_t<!std::is_same_v<T, void>>>
+ explicit WebCoreOpaqueRoot(T* pointer)
+ : m_pointer(static_cast<void*>(pointer))
+ {
+ }
+
+ WebCoreOpaqueRoot(std::nullptr_t) { }
+
+ bool isNode() const { return false; }
+ void* pointer() const { return m_pointer; }
+
+private:
+ void* m_pointer { nullptr };
+ bool m_isNode { false };
+};
+
+template<typename Visitor>
+ALWAYS_INLINE void addWebCoreOpaqueRoot(Visitor& visitor, WebCoreOpaqueRoot root)
+{
+ visitor.addOpaqueRoot(root.pointer());
+}
+
+template<typename Visitor, typename ImplType>
+ALWAYS_INLINE void addWebCoreOpaqueRoot(Visitor& visitor, ImplType* impl)
+{
+ addWebCoreOpaqueRoot(visitor, root(impl));
+}
+
+template<typename Visitor, typename ImplType>
+ALWAYS_INLINE void addWebCoreOpaqueRoot(Visitor& visitor, ImplType& impl)
+{
+ addWebCoreOpaqueRoot(visitor, root(&impl));
+}
+
+template<typename Visitor>
+ALWAYS_INLINE bool containsWebCoreOpaqueRoot(Visitor& visitor, WebCoreOpaqueRoot root)
+{
+ return visitor.containsOpaqueRoot(root.pointer());
+}
+
+template<typename Visitor, typename ImplType>
+ALWAYS_INLINE bool containsWebCoreOpaqueRoot(Visitor& visitor, ImplType& impl)
+{
+ return containsWebCoreOpaqueRoot(visitor, root(&impl));
+}
+
+template<typename Visitor, typename ImplType>
+ALWAYS_INLINE bool containsWebCoreOpaqueRoot(Visitor& visitor, ImplType* impl)
+{
+ return containsWebCoreOpaqueRoot(visitor, root(impl));
+}
+
+} // namespace WebCore
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index c91a232e6..71113e9a6 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -163,6 +163,9 @@ using JSBuffer = WebCore::JSBuffer;
#include "DOMJITHelpers.h"
#include <JavaScriptCore/DFGAbstractHeap.h>
+#include "JSCryptoKey.h"
+#include "JSSubtleCrypto.h"
+
#include "OnigurumaRegExp.h"
#ifdef __APPLE__
@@ -427,7 +430,10 @@ GlobalObject::GlobalObject(JSC::VM& vm, JSC::Structure* structure)
m_scriptExecutionContext = new WebCore::ScriptExecutionContext(&vm, this);
}
-GlobalObject::~GlobalObject() = default;
+GlobalObject::~GlobalObject()
+{
+ scriptExecutionContext()->removeFromContextsMap();
+}
void GlobalObject::destroy(JSCell* cell)
{
@@ -1264,6 +1270,40 @@ JSC_DEFINE_CUSTOM_GETTER(jsServiceWorkerGlobalScope_WritableStreamDefaultWriterC
return IDLAttribute<Zig::GlobalObject>::get<jsServiceWorkerGlobalScope_WritableStreamDefaultWriterConstructorGetter>(*lexicalGlobalObject, thisValue, attributeName);
}
+static inline JSValue getterSubtleCryptoBodyConstructor(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
+{
+ UNUSED_PARAM(lexicalGlobalObject);
+ return JSSubtleCrypto::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
+}
+
+JSC_DEFINE_CUSTOM_GETTER(getterSubtleCryptoConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ return IDLAttribute<Zig::GlobalObject>::get<getterSubtleCryptoBodyConstructor>(*lexicalGlobalObject, thisValue, attributeName);
+}
+
+static inline JSValue getterCryptoKeyBodyConstructor(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
+{
+ UNUSED_PARAM(lexicalGlobalObject);
+ return JSCryptoKey::getConstructor(JSC::getVM(&lexicalGlobalObject), &thisObject);
+}
+
+JSC_DEFINE_CUSTOM_GETTER(getterCryptoKeyConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ return IDLAttribute<Zig::GlobalObject>::get<getterCryptoKeyBodyConstructor>(*lexicalGlobalObject, thisValue, attributeName);
+}
+
+static inline JSValue getterSubtleCryptoBody(JSGlobalObject& lexicalGlobalObject, Zig::GlobalObject& thisObject)
+{
+ UNUSED_PARAM(lexicalGlobalObject);
+ return thisObject.subtleCrypto();
+}
+
+JSC_DEFINE_CUSTOM_GETTER(getterSubtleCrypto, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ return JSValue::encode(
+ getterSubtleCryptoBody(*lexicalGlobalObject, *reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)));
+}
+
JSC_DECLARE_HOST_FUNCTION(makeThisTypeErrorForBuiltins);
JSC_DECLARE_HOST_FUNCTION(makeGetterTypeErrorForBuiltins);
JSC_DECLARE_HOST_FUNCTION(makeDOMExceptionForBuiltins);
@@ -1951,6 +1991,15 @@ void GlobalObject::finishCreation(VM& vm)
this->initGeneratedLazyClasses();
+ m_subtleCryptoObject.initLater(
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
+ auto& global = *reinterpret_cast<Zig::GlobalObject*>(init.owner);
+ RefPtr<WebCore::SubtleCrypto> crypto = WebCore::SubtleCrypto::create(global.scriptExecutionContext());
+
+ init.set(
+ toJSNewlyCreated<IDLInterface<SubtleCrypto>>(*init.owner, global, WTFMove(crypto)).getObject());
+ });
+
m_NapiClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
init.setStructure(Zig::NapiClass::createStructure(init.vm, init.global, init.global->functionPrototype()));
@@ -2218,7 +2267,7 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
auto& builtinNames = WebCore::builtinNames(vm);
WTF::Vector<GlobalPropertyInfo> extraStaticGlobals;
- extraStaticGlobals.reserveCapacity(40);
+ extraStaticGlobals.reserveCapacity(42);
JSC::Identifier queueMicrotaskIdentifier = JSC::Identifier::fromString(vm, "queueMicrotask"_s);
extraStaticGlobals.uncheckedAppend(
@@ -2272,6 +2321,18 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
"atob"_s, functionATOB, ImplementationVisibility::Public),
JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
+ JSC::Identifier SubtleCryptoIdentifier = JSC::Identifier::fromString(vm, "SubtleCrypto"_s);
+ extraStaticGlobals.uncheckedAppend(
+ GlobalPropertyInfo { SubtleCryptoIdentifier,
+ JSC::CustomGetterSetter::create(vm, getterSubtleCryptoConstructor, nullptr),
+ JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0 });
+
+ JSC::Identifier CryptoKeyIdentifier = JSC::Identifier::fromString(vm, "CryptoKey"_s);
+ extraStaticGlobals.uncheckedAppend(
+ GlobalPropertyInfo { CryptoKeyIdentifier,
+ JSC::CustomGetterSetter::create(vm, getterCryptoKeyConstructor, nullptr),
+ JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0 });
+
JSC::Identifier btoaIdentifier = JSC::Identifier::fromString(vm, "btoa"_s);
extraStaticGlobals.uncheckedAppend(
GlobalPropertyInfo { btoaIdentifier,
@@ -2598,6 +2659,8 @@ void GlobalObject::installAPIGlobals(JSClassRef* globals, int count, JSC::VM& vm
Crypto__getRandomValues__put(this, JSValue::encode(object));
Crypto__randomUUID__put(this, JSValue::encode(object));
+ object->putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "subtle"_s), JSC::CustomGetterSetter::create(vm, getterSubtleCrypto, nullptr),
+ JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
extraStaticGlobals.uncheckedAppend(
GlobalPropertyInfo { JSC::Identifier::fromString(vm, jsClass->className()),
JSC::JSValue(object), JSC::PropertyAttribute::DontDelete | 0 });
@@ -2688,6 +2751,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_processObject.visit(visitor);
thisObject->m_performanceObject.visit(visitor);
thisObject->m_navigatorObject.visit(visitor);
+ thisObject->m_subtleCryptoObject.visit(visitor);
thisObject->m_JSHTTPResponseSinkClassStructure.visit(visitor);
thisObject->m_JSHTTPSResponseSinkClassStructure.visit(visitor);
@@ -2719,7 +2783,8 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
visitor.addOpaqueRoot(context);
}
-extern "C" void Bun__queueMicrotask(JSC__JSGlobalObject*, WebCore::EventLoopTask* task);
+extern "C" void Bun__queueTask(JSC__JSGlobalObject*, WebCore::EventLoopTask* task);
+extern "C" void Bun__queueTaskConcurrently(JSC__JSGlobalObject*, WebCore::EventLoopTask* task);
extern "C" void Bun__performTask(Zig::GlobalObject* globalObject, WebCore::EventLoopTask* task)
{
task->performTask(*globalObject->scriptExecutionContext());
@@ -2727,7 +2792,12 @@ extern "C" void Bun__performTask(Zig::GlobalObject* globalObject, WebCore::Event
void GlobalObject::queueTask(WebCore::EventLoopTask* task)
{
- Bun__queueMicrotask(this, task);
+ Bun__queueTask(this, task);
+}
+
+void GlobalObject::queueTaskConcurrently(WebCore::EventLoopTask* task)
+{
+ Bun__queueTaskConcurrently(this, task);
}
extern "C" void Bun__handleRejectedPromise(Zig::GlobalObject* JSGlobalObject, JSC::JSPromise* promise);
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index 8c0cc4796..9bd954a60 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -138,6 +138,7 @@ public:
WebCore::ScriptExecutionContext* scriptExecutionContext() const;
void queueTask(WebCore::EventLoopTask* task);
+ void queueTaskConcurrently(WebCore::EventLoopTask* task);
JSDOMStructureMap& structures() WTF_REQUIRES_LOCK(m_gcLock) { return m_structures; }
JSDOMStructureMap& structures(NoLockingNecessaryTag) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
@@ -238,6 +239,11 @@ public:
void* bunVM() { return m_bunVM; }
bool isThreadLocalDefaultGlobalObject = false;
+ JSObject* subtleCrypto()
+ {
+ return m_subtleCryptoObject.getInitializedOnMainThread(this);
+ }
+
EncodedJSValue assignToStream(JSValue stream, JSValue controller);
enum class PromiseFunctions : uint8_t {
@@ -368,7 +374,6 @@ public:
BunPlugin::OnResolve onResolvePlugins[BunPluginTargetMax + 1] {};
BunPluginTarget defaultBunPluginTarget = BunPluginTargetBun;
-
void reload();
JSC::Structure* pendingVirtualModuleResultStructure() { return m_pendingVirtualModuleResultStructure.get(this); }
@@ -419,6 +424,8 @@ private:
LazyProperty<JSGlobalObject, JSMap> m_requireMap;
LazyProperty<JSGlobalObject, JSObject> m_performanceObject;
+ LazyProperty<JSGlobalObject, JSObject> m_subtleCryptoObject;
+
LazyProperty<JSGlobalObject, JSC::Structure> m_pendingVirtualModuleResultStructure;
LazyProperty<JSGlobalObject, JSObject> m_encodeIntoObjectPrototype;
diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig
index f927e47c7..a8737dd54 100644
--- a/src/bun.js/bindings/bindings.zig
+++ b/src/bun.js/bindings/bindings.zig
@@ -2148,6 +2148,11 @@ pub const JSGlobalObject = extern struct {
return @ptrCast(*JSC.VirtualMachine, @alignCast(std.meta.alignment(JSC.VirtualMachine), this.bunVM_()));
}
+ /// We can't do the threadlocal check when queued from another thread
+ pub fn bunVMConcurrently(this: *JSGlobalObject) *JSC.VirtualMachine {
+ return @ptrCast(*JSC.VirtualMachine, @alignCast(std.meta.alignment(JSC.VirtualMachine), this.bunVM_()));
+ }
+
pub fn handleRejectedPromises(this: *JSGlobalObject) void {
return cppFn("handleRejectedPromises", .{this});
}
diff --git a/src/bun.js/bindings/root.h b/src/bun.js/bindings/root.h
index 0e8f2b262..69698bf8c 100644
--- a/src/bun.js/bindings/root.h
+++ b/src/bun.js/bindings/root.h
@@ -71,12 +71,18 @@
#include "wtf/PlatformCallingConventions.h"
#include "JavaScriptCore/JSCInlines.h"
+#include "wtf/IsoMalloc.h"
+#include "wtf/IsoMallocInlines.h"
-#define WTF_MAKE_ISO_ALLOCATED(className) \
- WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(className)
+#define ENABLE_WEB_CRYPTO 1
+#define USE_OPENSSL 1
+#define HAVE_RSA_PSS 1
-#define WTF_MAKE_ISO_ALLOCATED_EXPORT(className, a) WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(className);
+// #define WTF_MAKE_ISO_ALLOCATED(className) \
+// WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(className)
-#define WTF_MAKE_ISO_ALLOCATED_IMPL(className)
+// #define WTF_MAKE_ISO_ALLOCATED_EXPORT(className, a) WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(className);
+
+// #define WTF_MAKE_ISO_ALLOCATED_IMPL(className)
#endif \ No newline at end of file
diff --git a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
index 1477cc4b2..b6641ea4d 100644
--- a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
+++ b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
@@ -324,8 +324,8 @@ public:
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDocumentTimeline;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForKeyframeEffect;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebAnimation;
- // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCryptoKey;
- // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSubtleCrypto;
+ std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCryptoKey;
+ std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSubtleCrypto;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSConditionRule;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSCounterStyleRule;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSFontFaceRule;
diff --git a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
index e1e9a35c3..32c367014 100644
--- a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
+++ b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
@@ -314,8 +314,8 @@ public:
// std::unique_ptr<IsoSubspace> m_subspaceForDocumentTimeline;
// std::unique_ptr<IsoSubspace> m_subspaceForKeyframeEffect;
// std::unique_ptr<IsoSubspace> m_subspaceForWebAnimation;
- // std::unique_ptr<IsoSubspace> m_subspaceForCryptoKey;
- // std::unique_ptr<IsoSubspace> m_subspaceForSubtleCrypto;
+ std::unique_ptr<IsoSubspace> m_subspaceForCryptoKey;
+ std::unique_ptr<IsoSubspace> m_subspaceForSubtleCrypto;
// std::unique_ptr<IsoSubspace> m_subspaceForCSSConditionRule;
// std::unique_ptr<IsoSubspace> m_subspaceForCSSCounterStyleRule;
// std::unique_ptr<IsoSubspace> m_subspaceForCSSFontFaceRule;
diff --git a/src/bun.js/bindings/webcore/EventEmitter.cpp b/src/bun.js/bindings/webcore/EventEmitter.cpp
index 8d34ab7a2..d997019d6 100644
--- a/src/bun.js/bindings/webcore/EventEmitter.cpp
+++ b/src/bun.js/bindings/webcore/EventEmitter.cpp
@@ -1,9 +1,7 @@
-#include <iostream>
-#include "config.h"
-#include "Event.h"
-
#include "EventEmitter.h"
+#include "Event.h"
+
#include "DOMWrapperWorld.h"
#include "EventNames.h"
#include "JSErrorHandler.h"
@@ -18,7 +16,6 @@
namespace WebCore {
WTF_MAKE_ISO_ALLOCATED_IMPL(EventEmitter);
-WTF_MAKE_ISO_ALLOCATED_IMPL(EventEmitterWithInlineData);
Ref<EventEmitter> EventEmitter::create(ScriptExecutionContext& context)
{
diff --git a/src/bun.js/bindings/webcore/EventEmitter.h b/src/bun.js/bindings/webcore/EventEmitter.h
index 4aa143604..ae337fd8a 100644
--- a/src/bun.js/bindings/webcore/EventEmitter.h
+++ b/src/bun.js/bindings/webcore/EventEmitter.h
@@ -1,5 +1,7 @@
#pragma once
+#include "root.h"
+
#include "IdentifierEventListenerMap.h"
#include "ExceptionOr.h"
#include "ContextDestructionObserver.h"
@@ -10,8 +12,6 @@
#include <wtf/WeakPtr.h>
-#include "root.h"
-
namespace JSC {
class JSValue;
class JSObject;
diff --git a/src/bun.js/bindings/webcrypto/AesCbcCfbParams.idl b/src/bun.js/bindings/webcrypto/AesCbcCfbParams.idl
new file mode 100644
index 000000000..85e5a6536
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/AesCbcCfbParams.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This is a unified dictionary for AesCbcParams and AesCfbParams.
+// https://www.w3.org/TR/WebCryptoAPI/#dfn-AesCbcParams, and
+// https://www.w3.org/TR/2014/CR-WebCryptoAPI-20141211/#dfn-AesCfbParams
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmAesCbcCfbParams
+] dictionary AesCbcCfbParams : CryptoAlgorithmParameters {
+ // The initialization vector. MUST be 16 bytes.
+ required BufferSource iv;
+};
diff --git a/src/bun.js/bindings/webcrypto/AesCtrParams.idl b/src/bun.js/bindings/webcrypto/AesCtrParams.idl
new file mode 100644
index 000000000..2f5e295b2
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/AesCtrParams.idl
@@ -0,0 +1,40 @@
+/* Copyright (C) 2017 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmAesCtrParams
+] dictionary AesCtrParams : CryptoAlgorithmParameters {
+ // The initial value of the counter block. counter MUST be 16 bytes
+ // (the AES block size). The counter bits are the rightmost length
+ // bits of the counter block. The rest of the counter block is for
+ // the nonce. The counter bits are incremented using the standard
+ // incrementing function specified in NIST SP 800-38A Appendix B.1:
+ // the counter bits are interpreted as a big-endian integer and
+ // incremented by one.
+ required BufferSource counter;
+ // The length, in bits, of the rightmost part of the counter block
+ // that is incremented.
+ required [EnforceRange] octet length;
+};
diff --git a/src/bun.js/bindings/webcrypto/AesGcmParams.idl b/src/bun.js/bindings/webcrypto/AesGcmParams.idl
new file mode 100644
index 000000000..3d1c6f87c
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/AesGcmParams.idl
@@ -0,0 +1,35 @@
+/* Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmAesGcmParams
+] dictionary AesGcmParams : CryptoAlgorithmParameters {
+ // The initialization vector to use. May be up to 2^64-1 bytes long.
+ required BufferSource iv;
+ // The additional authentication data to include.
+ BufferSource additionalData;
+ // The desired length of the authentication tag. May be 0 - 128.
+ [EnforceRange] octet tagLength;
+};
diff --git a/src/bun.js/bindings/webcrypto/AesKeyParams.idl b/src/bun.js/bindings/webcrypto/AesKeyParams.idl
new file mode 100644
index 000000000..fdc4574f2
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/AesKeyParams.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This is a unified dictionary for AesDerivedKeyParams and AesKeyGenParams.
+// https://www.w3.org/TR/WebCryptoAPI/#aes-derivedkey-params, and
+// https://www.w3.org/TR/WebCryptoAPI/#aes-keygen-params
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmAesKeyParams
+] dictionary AesKeyParams : CryptoAlgorithmParameters {
+ // The length, in bits, of the key.
+ required [EnforceRange] unsigned short length;
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoAesKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/CryptoAesKeyAlgorithm.h
new file mode 100644
index 000000000..e2aa6cfba
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAesKeyAlgorithm.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoKeyAlgorithm.h"
+
+namespace WebCore {
+
+struct CryptoAesKeyAlgorithm : CryptoKeyAlgorithm {
+ // The length, in bits, of the key.
+ unsigned short length;
+};
+
+}
diff --git a/src/bun.js/bindings/webcrypto/CryptoAesKeyAlgorithm.idl b/src/bun.js/bindings/webcrypto/CryptoAesKeyAlgorithm.idl
new file mode 100644
index 000000000..4f7513e35
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAesKeyAlgorithm.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ JSGenerateToJSObject
+] dictionary CryptoAesKeyAlgorithm : CryptoKeyAlgorithm {
+ // The length, in bits, of the key.
+ required unsigned short length;
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithm.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithm.cpp
new file mode 100644
index 000000000..ca3b97bff
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithm.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "ScriptExecutionContext.h"
+
+namespace WebCore {
+
+void CryptoAlgorithm::encrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&, WorkQueue&)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::decrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&, WorkQueue&)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::sign(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&, WorkQueue&)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::verify(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, Vector<uint8_t>&&, BoolCallback&&, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&, WorkQueue&)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&, WorkQueue&)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::generateKey(const CryptoAlgorithmParameters&, bool, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::deriveBits(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, size_t, VectorCallback&&, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&, WorkQueue&)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&& exceptionCallback)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&& exceptionCallback)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::wrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&& exceptionCallback)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+void CryptoAlgorithm::unwrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&& exceptionCallback)
+{
+ exceptionCallback(NotSupportedError);
+}
+
+ExceptionOr<size_t> CryptoAlgorithm::getKeyLength(const CryptoAlgorithmParameters&)
+{
+ return Exception { NotSupportedError };
+}
+
+template<typename ResultCallbackType, typename OperationType>
+static void dispatchAlgorithmOperation(WorkQueue& workQueue, ScriptExecutionContext& context, ResultCallbackType&& callback, CryptoAlgorithm::ExceptionCallback&& exceptionCallback, OperationType&& operation)
+{
+ workQueue.dispatch(
+ [operation = WTFMove(operation), callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback), contextIdentifier = context.identifier()]() mutable {
+ auto result = operation();
+ ScriptExecutionContext::postTaskTo(contextIdentifier, [result = crossThreadCopy(WTFMove(result)), callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback)](auto&) mutable {
+ if (result.hasException()) {
+ exceptionCallback(result.releaseException().code());
+ return;
+ }
+ callback(result.releaseReturnValue());
+ });
+ });
+}
+
+void CryptoAlgorithm::dispatchOperationInWorkQueue(WorkQueue& workQueue, ScriptExecutionContext& context, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, Function<ExceptionOr<Vector<uint8_t>>()>&& operation)
+{
+ dispatchAlgorithmOperation(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback), WTFMove(operation));
+}
+
+void CryptoAlgorithm::dispatchOperationInWorkQueue(WorkQueue& workQueue, ScriptExecutionContext& context, BoolCallback&& callback, ExceptionCallback&& exceptionCallback, Function<ExceptionOr<bool>()>&& operation)
+{
+ dispatchAlgorithmOperation(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback), WTFMove(operation));
+}
+
+}
+
+#endif
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithm.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithm.h
new file mode 100644
index 000000000..40dbb0ad6
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithm.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmIdentifier.h"
+#include "CryptoKeyFormat.h"
+#include "CryptoKeyPair.h"
+#include "CryptoKeyUsage.h"
+#include "ExceptionOr.h"
+#include "JsonWebKey.h"
+#include <variant>
+#include <wtf/Function.h>
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/WorkQueue.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmParameters;
+class CryptoKey;
+class ScriptExecutionContext;
+
+using KeyData = std::variant<Vector<uint8_t>, JsonWebKey>;
+using KeyOrKeyPair = std::variant<RefPtr<CryptoKey>, CryptoKeyPair>;
+
+class CryptoAlgorithm : public ThreadSafeRefCounted<CryptoAlgorithm> {
+public:
+ virtual ~CryptoAlgorithm() = default;
+
+ virtual CryptoAlgorithmIdentifier identifier() const = 0;
+
+ using BoolCallback = Function<void(bool)>;
+ using KeyCallback = Function<void(CryptoKey&)>;
+ using KeyOrKeyPairCallback = Function<void(KeyOrKeyPair&&)>;
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=169395
+ using VectorCallback = Function<void(const Vector<uint8_t>&)>;
+ using VoidCallback = Function<void()>;
+ using ExceptionCallback = Function<void(ExceptionCode)>;
+ using KeyDataCallback = Function<void(CryptoKeyFormat, KeyData&&)>;
+
+ virtual void encrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&);
+ virtual void decrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&);
+ virtual void sign(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&);
+ virtual void verify(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&& signature, Vector<uint8_t>&&, BoolCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&);
+ virtual void digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&);
+ virtual void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&);
+ virtual void deriveBits(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, size_t length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&);
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=169262
+ virtual void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&);
+ virtual void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&);
+ virtual void wrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&);
+ virtual void unwrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&);
+ virtual ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&);
+
+ static void dispatchOperationInWorkQueue(WorkQueue&, ScriptExecutionContext&, VectorCallback&&, ExceptionCallback&&, Function<ExceptionOr<Vector<uint8_t>>()>&&);
+ static void dispatchOperationInWorkQueue(WorkQueue&, ScriptExecutionContext&, BoolCallback&&, ExceptionCallback&&, Function<ExceptionOr<bool>()>&&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBC.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBC.cpp
new file mode 100644
index 000000000..c13df346e
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBC.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_CBC.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesCbcCfbParams.h"
+#include "CryptoAlgorithmAesKeyParams.h"
+#include "CryptoKeyAES.h"
+#include <wtf/CrossThreadCopier.h>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmAES_CBCInternal {
+static constexpr auto ALG128 = "A128CBC"_s;
+static constexpr auto ALG192 = "A192CBC"_s;
+static constexpr auto ALG256 = "A256CBC"_s;
+static const size_t IVSIZE = 16;
+}
+
+static inline bool usagesAreInvalidForCryptoAlgorithmAES_CBC(CryptoKeyUsageBitmap usages)
+{
+ return usages & (CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits);
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmAES_CBC::create()
+{
+ return adoptRef(*new CryptoAlgorithmAES_CBC);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmAES_CBC::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmAES_CBC::encrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& plainText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ using namespace CryptoAlgorithmAES_CBCInternal;
+
+ auto& aesParameters = downcast<CryptoAlgorithmAesCbcCfbParams>(parameters);
+ if (aesParameters.ivVector().size() != IVSIZE) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(aesParameters), key = WTFMove(key), plainText = WTFMove(plainText)] {
+ return platformEncrypt(parameters, downcast<CryptoKeyAES>(key.get()), plainText);
+ });
+}
+
+void CryptoAlgorithmAES_CBC::decrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& cipherText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ using namespace CryptoAlgorithmAES_CBCInternal;
+
+ auto& aesParameters = downcast<CryptoAlgorithmAesCbcCfbParams>(parameters);
+ if (aesParameters.ivVector().size() != IVSIZE) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(aesParameters), key = WTFMove(key), cipherText = WTFMove(cipherText)] {
+ return platformDecrypt(parameters, downcast<CryptoKeyAES>(key.get()), cipherText);
+ });
+}
+
+void CryptoAlgorithmAES_CBC::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
+{
+ const auto& aesParameters = downcast<CryptoAlgorithmAesKeyParams>(parameters);
+
+ if (usagesAreInvalidForCryptoAlgorithmAES_CBC(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_CBC, aesParameters.length, extractable, usages);
+ if (!result) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ callback(WTFMove(result));
+}
+
+void CryptoAlgorithmAES_CBC::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_CBCInternal;
+
+ if (usagesAreInvalidForCryptoAlgorithmAES_CBC(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ RefPtr<CryptoKeyAES> result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = CryptoKeyAES::importRaw(parameters.identifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Jwk: {
+ auto checkAlgCallback = [](size_t length, const String& alg) -> bool {
+ switch (length) {
+ case CryptoKeyAES::s_length128:
+ return alg.isNull() || alg == ALG128;
+ case CryptoKeyAES::s_length192:
+ return alg.isNull() || alg == ALG192;
+ case CryptoKeyAES::s_length256:
+ return alg.isNull() || alg == ALG256;
+ }
+ return false;
+ };
+ result = CryptoKeyAES::importJwk(parameters.identifier, WTFMove(std::get<JsonWebKey>(data)), extractable, usages, WTFMove(checkAlgCallback));
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmAES_CBC::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_CBCInternal;
+ const auto& aesKey = downcast<CryptoKeyAES>(key.get());
+
+ if (aesKey.key().isEmpty()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = Vector<uint8_t>(aesKey.key());
+ break;
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = aesKey.exportJwk();
+ switch (aesKey.key().size() * 8) {
+ case CryptoKeyAES::s_length128:
+ jwk.alg = String(ALG128);
+ break;
+ case CryptoKeyAES::s_length192:
+ jwk.alg = String(ALG192);
+ break;
+ case CryptoKeyAES::s_length256:
+ jwk.alg = String(ALG256);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = WTFMove(jwk);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+ExceptionOr<size_t> CryptoAlgorithmAES_CBC::getKeyLength(const CryptoAlgorithmParameters& parameters)
+{
+ return CryptoKeyAES::getKeyLength(parameters);
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBC.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBC.h
new file mode 100644
index 000000000..b7443a733
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBC.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmAesCbcCfbParams;
+class CryptoKeyAES;
+
+class CryptoAlgorithmAES_CBC final : public CryptoAlgorithm {
+public:
+ enum class Padding : uint8_t {
+ Yes,
+ No
+ };
+
+ static constexpr ASCIILiteral s_name = "AES-CBC"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::AES_CBC;
+ static Ref<CryptoAlgorithm> create();
+
+ // Operations can be performed directly.
+ WEBCORE_EXPORT static ExceptionOr<Vector<uint8_t>> platformEncrypt(const CryptoAlgorithmAesCbcCfbParams&, const CryptoKeyAES&, const Vector<uint8_t>&, Padding padding = Padding::Yes);
+ WEBCORE_EXPORT static ExceptionOr<Vector<uint8_t>> platformDecrypt(const CryptoAlgorithmAesCbcCfbParams&, const CryptoKeyAES&, const Vector<uint8_t>&, Padding padding = Padding::Yes);
+
+private:
+ CryptoAlgorithmAES_CBC() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void encrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void decrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+ ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&) final;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBCOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBCOpenSSL.cpp
new file mode 100644
index 000000000..c271c067f
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CBCOpenSSL.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_CBC.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesCbcCfbParams.h"
+#include "CryptoKeyAES.h"
+#include "OpenSSLCryptoUniquePtr.h"
+#include <openssl/evp.h>
+
+namespace WebCore {
+
+static const EVP_CIPHER* aesAlgorithm(size_t keySize)
+{
+ if (keySize * 8 == 128)
+ return EVP_aes_128_cbc();
+
+ if (keySize * 8 == 192)
+ return EVP_aes_192_cbc();
+
+ if (keySize * 8 == 256)
+ return EVP_aes_256_cbc();
+
+ return nullptr;
+}
+
+static std::optional<Vector<uint8_t>> cryptEncrypt(const Vector<uint8_t>& key, const Vector<uint8_t>& iv, Vector<uint8_t>&& plainText)
+{
+ const EVP_CIPHER* algorithm = aesAlgorithm(key.size());
+ if (!algorithm)
+ return std::nullopt;
+
+ EvpCipherCtxPtr ctx;
+ int len;
+
+ // Create and initialize the context
+ if (!(ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new())))
+ return std::nullopt;
+
+ size_t plainSize = plainText.size();
+ const size_t cipherTextLen = roundUpToMultipleOf(EVP_CIPHER_block_size(algorithm), plainSize + 1);
+ Vector<uint8_t> cipherText(cipherTextLen);
+
+ // Initialize the encryption operation
+ if (1 != EVP_EncryptInit_ex(ctx.get(), algorithm, nullptr, key.data(), iv.data()))
+ return std::nullopt;
+
+ // Provide the message to be encrypted, and obtain the encrypted output
+ if (1 != EVP_EncryptUpdate(ctx.get(), cipherText.data(), &len, plainText.data(), plainSize))
+ return std::nullopt;
+
+ // Finalize the encryption. Further ciphertext bytes may be written at this stage
+ if (1 != EVP_EncryptFinal_ex(ctx.get(), cipherText.data() + len, &len))
+ return std::nullopt;
+
+ return cipherText;
+}
+
+static std::optional<Vector<uint8_t>> cryptDecrypt(const Vector<uint8_t>& key, const Vector<uint8_t>& iv, const Vector<uint8_t>& cipherText)
+{
+ const EVP_CIPHER* algorithm = aesAlgorithm(key.size());
+ if (!algorithm)
+ return std::nullopt;
+
+ EvpCipherCtxPtr ctx;
+
+ size_t cipherSize = cipherText.size();
+ Vector<uint8_t> plainText(cipherSize);
+ int len;
+ int plainTextLen;
+
+ // Create and initialize the context
+ if (!(ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new())))
+ return std::nullopt;
+
+ // Initialize the decryption operation
+ if (1 != EVP_DecryptInit_ex(ctx.get(), algorithm, nullptr, key.data(), iv.data()))
+ return std::nullopt;
+
+ // Provide the message to be decrypted, and obtain the plaintext output
+ if (1 != EVP_DecryptUpdate(ctx.get(), plainText.data(), &len, cipherText.data(), cipherSize))
+ return std::nullopt;
+ plainTextLen = len;
+
+ // Finalize the decryption. Further plaintext bytes may be written at this stage
+ if (1 != EVP_DecryptFinal_ex(ctx.get(), plainText.data() + len, &len))
+ return std::nullopt;
+ plainTextLen += len;
+
+ plainText.shrink(plainTextLen);
+
+ return plainText;
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_CBC::platformEncrypt(const CryptoAlgorithmAesCbcCfbParams& parameters, const CryptoKeyAES& key, const Vector<uint8_t>& plainText, Padding)
+{
+ auto output = cryptEncrypt(key.key(), parameters.ivVector(), Vector<uint8_t>(plainText));
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_CBC::platformDecrypt(const CryptoAlgorithmAesCbcCfbParams& parameters, const CryptoKeyAES& key, const Vector<uint8_t>& cipherText, Padding)
+{
+ auto output = cryptDecrypt(key.key(), parameters.ivVector(), cipherText);
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFB.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFB.cpp
new file mode 100644
index 000000000..88e8075b6
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFB.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_CFB.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesCbcCfbParams.h"
+#include "CryptoAlgorithmAesKeyParams.h"
+#include "CryptoKeyAES.h"
+#include <wtf/CrossThreadCopier.h>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmAES_CFBInternal {
+static constexpr auto ALG128 = "A128CFB8"_s;
+static constexpr auto ALG192 = "A192CFB8"_s;
+static constexpr auto ALG256 = "A256CFB8"_s;
+static const size_t IVSIZE = 16;
+}
+
+static inline bool usagesAreInvalidForCryptoAlgorithmAES_CFB(CryptoKeyUsageBitmap usages)
+{
+ return usages & (CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits);
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmAES_CFB::create()
+{
+ return adoptRef(*new CryptoAlgorithmAES_CFB);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmAES_CFB::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmAES_CFB::encrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& plainText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ using namespace CryptoAlgorithmAES_CFBInternal;
+
+ auto& aesParameters = downcast<CryptoAlgorithmAesCbcCfbParams>(parameters);
+ if (aesParameters.ivVector().size() != IVSIZE) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(aesParameters), key = WTFMove(key), plainText = WTFMove(plainText)] {
+ return platformEncrypt(parameters, downcast<CryptoKeyAES>(key.get()), plainText);
+ });
+}
+
+void CryptoAlgorithmAES_CFB::decrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& cipherText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ using namespace CryptoAlgorithmAES_CFBInternal;
+
+ auto& aesParameters = downcast<CryptoAlgorithmAesCbcCfbParams>(parameters);
+ if (aesParameters.ivVector().size() != IVSIZE) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(aesParameters), key = WTFMove(key), cipherText = WTFMove(cipherText)] {
+ return platformDecrypt(parameters, downcast<CryptoKeyAES>(key.get()), cipherText);
+ });
+}
+
+void CryptoAlgorithmAES_CFB::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
+{
+ const auto& aesParameters = downcast<CryptoAlgorithmAesKeyParams>(parameters);
+
+ if (usagesAreInvalidForCryptoAlgorithmAES_CFB(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_CFB, aesParameters.length, extractable, usages);
+ if (!result) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ callback(WTFMove(result));
+}
+
+void CryptoAlgorithmAES_CFB::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_CFBInternal;
+
+ if (usagesAreInvalidForCryptoAlgorithmAES_CFB(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ RefPtr<CryptoKeyAES> result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = CryptoKeyAES::importRaw(parameters.identifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Jwk: {
+ auto checkAlgCallback = [](size_t length, const String& alg) -> bool {
+ switch (length) {
+ case CryptoKeyAES::s_length128:
+ return alg.isNull() || alg == ALG128;
+ case CryptoKeyAES::s_length192:
+ return alg.isNull() || alg == ALG192;
+ case CryptoKeyAES::s_length256:
+ return alg.isNull() || alg == ALG256;
+ }
+ return false;
+ };
+ result = CryptoKeyAES::importJwk(parameters.identifier, WTFMove(std::get<JsonWebKey>(data)), extractable, usages, WTFMove(checkAlgCallback));
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmAES_CFB::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_CFBInternal;
+ const auto& aesKey = downcast<CryptoKeyAES>(key.get());
+
+ if (aesKey.key().isEmpty()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = Vector<uint8_t>(aesKey.key());
+ break;
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = aesKey.exportJwk();
+ switch (aesKey.key().size() * 8) {
+ case CryptoKeyAES::s_length128:
+ jwk.alg = String(ALG128);
+ break;
+ case CryptoKeyAES::s_length192:
+ jwk.alg = String(ALG192);
+ break;
+ case CryptoKeyAES::s_length256:
+ jwk.alg = String(ALG256);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = WTFMove(jwk);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+ExceptionOr<size_t> CryptoAlgorithmAES_CFB::getKeyLength(const CryptoAlgorithmParameters& parameters)
+{
+ return CryptoKeyAES::getKeyLength(parameters);
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFB.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFB.h
new file mode 100644
index 000000000..508a20336
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFB.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmAesCbcCfbParams;
+class CryptoKeyAES;
+
+class CryptoAlgorithmAES_CFB final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "AES-CFB-8"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::AES_CFB;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmAES_CFB() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void encrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void decrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+ ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformEncrypt(const CryptoAlgorithmAesCbcCfbParams&, const CryptoKeyAES&, const Vector<uint8_t>&);
+ static ExceptionOr<Vector<uint8_t>> platformDecrypt(const CryptoAlgorithmAesCbcCfbParams&, const CryptoKeyAES&, const Vector<uint8_t>&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFBOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFBOpenSSL.cpp
new file mode 100644
index 000000000..bfa431d68
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CFBOpenSSL.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2022 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_CFB.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesCbcCfbParams.h"
+#include "CryptoKeyAES.h"
+#include "OpenSSLUtilities.h"
+
+namespace WebCore {
+
+static std::optional<Vector<uint8_t>> cfb8(const Vector<uint8_t>& key, const Vector<uint8_t>& iv, const Vector<uint8_t>& input, bool encrypt)
+{
+ if (iv.size() != AES_BLOCK_SIZE)
+ return std::nullopt;
+
+ AESKey aesKey;
+ if (!aesKey.setKey(key, AES_ENCRYPT))
+ return std::nullopt;
+
+ // Instead of memmoving the input vector every time, we have a AES_BLOCK_SIZE * 2 length buffer
+ // and shift the input position (shiftRegister + shift) as well as the feedback position
+ // (shiftRegister + shift + AES_BLOCK_SIZE) until the feedback position reaches
+ // the end of the buffer.
+ uint8_t shiftRegister[AES_BLOCK_SIZE * 2];
+ memcpy(shiftRegister, iv.data(), AES_BLOCK_SIZE);
+ size_t shift = 0;
+
+ Vector<uint8_t> output(input.size());
+
+ uint8_t encryptedBlock[AES_BLOCK_SIZE];
+ for (size_t i = 0; i < output.size(); i++) {
+ AES_encrypt(shiftRegister + shift, encryptedBlock, aesKey.key());
+
+ // In the CFB8 mode the first byte (most significant 8 bits) of the encrypted block
+ // is used as a key stream. The output stream is generated by XORing the input and the key stream.
+ output[i] = input[i] ^ encryptedBlock[0];
+
+ // Feed back the 8 bit cipher to the shift register. The cipher stream is
+ // "output" in the encryption mode and "input" in the decryption mode.
+ shiftRegister[AES_BLOCK_SIZE + (shift++)] = encrypt ? output[i] : input[i];
+ if (shift == AES_BLOCK_SIZE) {
+ memcpy(shiftRegister, shiftRegister + AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+ shift = 0;
+ }
+ }
+ memset(encryptedBlock, 0, sizeof encryptedBlock);
+
+ return output;
+}
+
+static std::optional<Vector<uint8_t>> cryptEncrypt(const Vector<uint8_t>& key, const Vector<uint8_t>& iv, Vector<uint8_t>&& plainText)
+{
+ return cfb8(key, iv, plainText, true);
+}
+
+static std::optional<Vector<uint8_t>> cryptDecrypt(const Vector<uint8_t>& key, const Vector<uint8_t>& iv, const Vector<uint8_t>& cipherText)
+{
+ return cfb8(key, iv, cipherText, false);
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_CFB::platformEncrypt(const CryptoAlgorithmAesCbcCfbParams& parameters, const CryptoKeyAES& key, const Vector<uint8_t>& plainText)
+{
+ auto output = cryptEncrypt(key.key(), parameters.ivVector(), Vector<uint8_t>(plainText));
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_CFB::platformDecrypt(const CryptoAlgorithmAesCbcCfbParams& parameters, const CryptoKeyAES& key, const Vector<uint8_t>& cipherText)
+{
+ auto output = cryptDecrypt(key.key(), parameters.ivVector(), cipherText);
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTR.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTR.cpp
new file mode 100644
index 000000000..9b2648e8a
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTR.cpp
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_CTR.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesCtrParams.h"
+#include "CryptoAlgorithmAesKeyParams.h"
+#include "CryptoKeyAES.h"
+#include <wtf/CrossThreadCopier.h>
+#include <wtf/FlipBytes.h>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmAES_CTRInternal {
+static constexpr auto ALG128 = "A128CTR"_s;
+static constexpr auto ALG192 = "A192CTR"_s;
+static constexpr auto ALG256 = "A256CTR"_s;
+static const size_t CounterSize = 16;
+static const uint64_t AllBitsSet = ~(uint64_t)0;
+}
+
+static inline bool usagesAreInvalidForCryptoAlgorithmAES_CTR(CryptoKeyUsageBitmap usages)
+{
+ return usages & (CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits);
+}
+
+static bool parametersAreValid(const CryptoAlgorithmAesCtrParams& parameters)
+{
+ using namespace CryptoAlgorithmAES_CTRInternal;
+ if (parameters.counterVector().size() != CounterSize)
+ return false;
+ if (!parameters.length || parameters.length > 128)
+ return false;
+ return true;
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmAES_CTR::create()
+{
+ return adoptRef(*new CryptoAlgorithmAES_CTR);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmAES_CTR::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmAES_CTR::encrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& plainText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ auto& aesParameters = downcast<CryptoAlgorithmAesCtrParams>(parameters);
+ if (!parametersAreValid(aesParameters)) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(aesParameters), key = WTFMove(key), plainText = WTFMove(plainText)] {
+ return platformEncrypt(parameters, downcast<CryptoKeyAES>(key.get()), plainText);
+ });
+}
+
+void CryptoAlgorithmAES_CTR::decrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& cipherText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ auto& aesParameters = downcast<CryptoAlgorithmAesCtrParams>(parameters);
+ if (!parametersAreValid(aesParameters)) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(aesParameters), key = WTFMove(key), cipherText = WTFMove(cipherText)] {
+ return platformDecrypt(parameters, downcast<CryptoKeyAES>(key.get()), cipherText);
+ });
+}
+
+void CryptoAlgorithmAES_CTR::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
+{
+ const auto& aesParameters = downcast<CryptoAlgorithmAesKeyParams>(parameters);
+
+ if (usagesAreInvalidForCryptoAlgorithmAES_CTR(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_CTR, aesParameters.length, extractable, usages);
+ if (!result) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ callback(WTFMove(result));
+}
+
+void CryptoAlgorithmAES_CTR::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_CTRInternal;
+
+ if (usagesAreInvalidForCryptoAlgorithmAES_CTR(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ RefPtr<CryptoKeyAES> result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = CryptoKeyAES::importRaw(parameters.identifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Jwk: {
+ auto checkAlgCallback = [](size_t length, const String& alg) -> bool {
+ switch (length) {
+ case CryptoKeyAES::s_length128:
+ return alg.isNull() || alg == ALG128;
+ case CryptoKeyAES::s_length192:
+ return alg.isNull() || alg == ALG192;
+ case CryptoKeyAES::s_length256:
+ return alg.isNull() || alg == ALG256;
+ }
+ return false;
+ };
+ result = CryptoKeyAES::importJwk(parameters.identifier, WTFMove(std::get<JsonWebKey>(data)), extractable, usages, WTFMove(checkAlgCallback));
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmAES_CTR::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_CTRInternal;
+ const auto& aesKey = downcast<CryptoKeyAES>(key.get());
+
+ if (aesKey.key().isEmpty()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = Vector<uint8_t>(aesKey.key());
+ break;
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = aesKey.exportJwk();
+ switch (aesKey.key().size() * 8) {
+ case CryptoKeyAES::s_length128:
+ jwk.alg = String(ALG128);
+ break;
+ case CryptoKeyAES::s_length192:
+ jwk.alg = String(ALG192);
+ break;
+ case CryptoKeyAES::s_length256:
+ jwk.alg = String(ALG256);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = WTFMove(jwk);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+ExceptionOr<size_t> CryptoAlgorithmAES_CTR::getKeyLength(const CryptoAlgorithmParameters& parameters)
+{
+ return CryptoKeyAES::getKeyLength(parameters);
+}
+
+CryptoAlgorithmAES_CTR::CounterBlockHelper::CounterBlockHelper(const Vector<uint8_t>& counterVector, size_t counterLength)
+ : m_counterLength(counterLength)
+{
+ using namespace CryptoAlgorithmAES_CTRInternal;
+
+ ASSERT(counterVector.size() == CounterSize);
+ ASSERT(counterLength <= CounterSize * 8);
+ bool littleEndian = false; // counterVector is stored in big-endian.
+ memcpy(&m_bits.m_hi, counterVector.data(), 8);
+ m_bits.m_hi = flipBytesIfLittleEndian(m_bits.m_hi, littleEndian);
+ memcpy(&m_bits.m_lo, counterVector.data() + 8, 8);
+ m_bits.m_lo = flipBytesIfLittleEndian(m_bits.m_lo, littleEndian);
+}
+
+size_t CryptoAlgorithmAES_CTR::CounterBlockHelper::countToOverflowSaturating() const
+{
+ CounterBlockBits counterMask;
+ counterMask.set();
+ counterMask <<= m_counterLength;
+ counterMask = ~counterMask;
+
+ auto countMinusOne = ~m_bits & counterMask;
+
+ CounterBlockBits sizeTypeMask;
+ sizeTypeMask.set();
+ sizeTypeMask <<= sizeof(size_t) * 8;
+ if ((sizeTypeMask & countMinusOne).any()) {
+ // Saturating to the size_t max since the count is greater than that.
+ return std::numeric_limits<size_t>::max();
+ }
+
+ countMinusOne &= ~sizeTypeMask;
+ if (countMinusOne.all()) {
+ // As all bits are set, adding one would result in an overflow.
+ // Return size_t max instead.
+ return std::numeric_limits<size_t>::max();
+ }
+
+ static_assert(sizeof(size_t) <= sizeof(uint64_t));
+ return countMinusOne.m_lo + 1;
+}
+
+Vector<uint8_t> CryptoAlgorithmAES_CTR::CounterBlockHelper::counterVectorAfterOverflow() const
+{
+ using namespace CryptoAlgorithmAES_CTRInternal;
+
+ CounterBlockBits nonceMask;
+ nonceMask.set();
+ nonceMask <<= m_counterLength;
+ auto bits = m_bits & nonceMask;
+
+ bool littleEndian = false; // counterVector is stored in big-endian.
+ Vector<uint8_t> counterVector(CounterSize);
+ uint64_t hi = flipBytesIfLittleEndian(bits.m_hi, littleEndian);
+ memcpy(counterVector.data(), &hi, 8);
+ uint64_t lo = flipBytesIfLittleEndian(bits.m_lo, littleEndian);
+ memcpy(counterVector.data() + 8, &lo, 8);
+
+ return counterVector;
+}
+
+void CryptoAlgorithmAES_CTR::CounterBlockHelper::CounterBlockBits::set()
+{
+ using namespace CryptoAlgorithmAES_CTRInternal;
+ m_hi = AllBitsSet;
+ m_lo = AllBitsSet;
+}
+
+bool CryptoAlgorithmAES_CTR::CounterBlockHelper::CounterBlockBits::all() const
+{
+ using namespace CryptoAlgorithmAES_CTRInternal;
+ return m_hi == AllBitsSet && m_lo == AllBitsSet;
+}
+
+bool CryptoAlgorithmAES_CTR::CounterBlockHelper::CounterBlockBits::any() const
+{
+ return m_hi || m_lo;
+}
+
+auto CryptoAlgorithmAES_CTR::CounterBlockHelper::CounterBlockBits::operator&(const CounterBlockBits& rhs) const -> CounterBlockBits
+{
+ return { m_hi & rhs.m_hi, m_lo & rhs.m_lo };
+}
+
+auto CryptoAlgorithmAES_CTR::CounterBlockHelper::CounterBlockBits::operator~() const -> CounterBlockBits
+{
+ return { ~m_hi, ~m_lo };
+}
+
+auto CryptoAlgorithmAES_CTR::CounterBlockHelper::CounterBlockBits::operator <<=(unsigned shift) -> CounterBlockBits&
+{
+ if (shift < 64) {
+ m_hi = (m_hi << shift) | m_lo >> (64 - shift);
+ m_lo <<= shift;
+ } else if (shift < 128) {
+ shift -= 64;
+ m_hi = m_lo << shift;
+ m_lo = 0;
+ } else {
+ m_hi = 0;
+ m_lo = 0;
+ }
+ return *this;
+}
+
+auto CryptoAlgorithmAES_CTR::CounterBlockHelper::CounterBlockBits::operator &=(const CounterBlockBits& rhs) -> CounterBlockBits&
+{
+ m_hi &= rhs.m_hi;
+ m_lo &= rhs.m_lo;
+ return *this;
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTR.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTR.h
new file mode 100644
index 000000000..8bd39339d
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTR.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmAesCtrParams;
+class CryptoKeyAES;
+
+class CryptoAlgorithmAES_CTR final : public CryptoAlgorithm {
+public:
+ class CounterBlockHelper {
+ public:
+ CounterBlockHelper(const Vector<uint8_t>& counterVector, size_t counterLength);
+
+ size_t countToOverflowSaturating() const;
+ Vector<uint8_t> counterVectorAfterOverflow() const;
+
+ private:
+ // 128 bits integer with miminum required operators.
+ struct CounterBlockBits {
+ void set();
+ bool all() const;
+ bool any() const;
+
+ CounterBlockBits operator&(const CounterBlockBits&) const;
+ CounterBlockBits operator~() const;
+ CounterBlockBits& operator <<=(unsigned);
+ CounterBlockBits& operator &=(const CounterBlockBits&);
+
+ uint64_t m_hi { 0 };
+ uint64_t m_lo { 0 };
+ };
+
+ CounterBlockBits m_bits;
+ const size_t m_counterLength;
+ };
+
+ static constexpr ASCIILiteral s_name = "AES-CTR"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::AES_CTR;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmAES_CTR() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void encrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void decrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+ ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformEncrypt(const CryptoAlgorithmAesCtrParams&, const CryptoKeyAES&, const Vector<uint8_t>&);
+ static ExceptionOr<Vector<uint8_t>> platformDecrypt(const CryptoAlgorithmAesCtrParams&, const CryptoKeyAES&, const Vector<uint8_t>&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTROpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTROpenSSL.cpp
new file mode 100644
index 000000000..ca2f9b559
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_CTROpenSSL.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_CTR.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesCtrParams.h"
+#include "CryptoKeyAES.h"
+#include "OpenSSLCryptoUniquePtr.h"
+#include <openssl/evp.h>
+
+namespace WebCore {
+
+static const EVP_CIPHER* aesAlgorithm(size_t keySize)
+{
+ if (keySize * 8 == 128)
+ return EVP_aes_128_ctr();
+
+ if (keySize * 8 == 192)
+ return EVP_aes_192_ctr();
+
+ if (keySize * 8 == 256)
+ return EVP_aes_256_ctr();
+
+ return nullptr;
+}
+
+static std::optional<Vector<uint8_t>> crypt(int operation, const Vector<uint8_t>& key, const Vector<uint8_t>& counter, size_t counterLength, const Vector<uint8_t>& inputText)
+{
+ constexpr size_t blockSize = 16;
+ const EVP_CIPHER* algorithm = aesAlgorithm(key.size());
+ if (!algorithm)
+ return std::nullopt;
+
+ EvpCipherCtxPtr ctx;
+ int len;
+
+ // Create and initialize the context
+ if (!(ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new())))
+ return std::nullopt;
+
+ const size_t blocks = roundUpToMultipleOf(blockSize, inputText.size()) / blockSize;
+
+ // Detect loop
+ if (counterLength < sizeof(size_t) * 8 && blocks > ((size_t)1 << counterLength))
+ return std::nullopt;
+
+ // Calculate capacity before overflow
+ CryptoAlgorithmAES_CTR::CounterBlockHelper counterBlockHelper(counter, counterLength);
+ size_t capacity = counterBlockHelper.countToOverflowSaturating();
+
+ // Divide data into two parts if necessary
+ size_t headSize = inputText.size();
+ if (capacity < blocks)
+ headSize = capacity * blockSize;
+
+ Vector<uint8_t> outputText(inputText.size());
+ // First part
+ {
+ // Initialize the encryption(decryption) operation
+ if (1 != EVP_CipherInit_ex(ctx.get(), algorithm, nullptr, key.data(), counter.data(), operation))
+ return std::nullopt;
+
+ // Disable padding
+ if (1 != EVP_CIPHER_CTX_set_padding(ctx.get(), 0))
+ return std::nullopt;
+
+ // Provide the message to be encrypted(decrypted), and obtain the encrypted(decrypted) output
+ if (1 != EVP_CipherUpdate(ctx.get(), outputText.data(), &len, inputText.data(), headSize))
+ return std::nullopt;
+
+ // Finalize the encryption(decryption)
+ if (1 != EVP_CipherFinal_ex(ctx.get(), outputText.data() + len, &len))
+ return std::nullopt;
+ }
+
+ // Sedond part
+ if (capacity < blocks) {
+ size_t tailSize = inputText.size() - headSize;
+
+ Vector<uint8_t> remainingCounter = counterBlockHelper.counterVectorAfterOverflow();
+
+ // Initialize the encryption(decryption) operation
+ if (1 != EVP_CipherInit_ex(ctx.get(), algorithm, nullptr, key.data(), remainingCounter.data(), operation))
+ return std::nullopt;
+
+ // Disable padding
+ if (1 != EVP_CIPHER_CTX_set_padding(ctx.get(), 0))
+ return std::nullopt;
+
+ // Provide the message to be encrypted(decrypted), and obtain the encrypted(decrypted) output
+ if (1 != EVP_CipherUpdate(ctx.get(), outputText.data() + headSize, &len, inputText.data() + headSize, tailSize))
+ return std::nullopt;
+
+ // Finalize the encryption(decryption)
+ if (1 != EVP_CipherFinal_ex(ctx.get(), outputText.data() + headSize + len, &len))
+ return std::nullopt;
+ }
+
+ return outputText;
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_CTR::platformEncrypt(const CryptoAlgorithmAesCtrParams& parameters, const CryptoKeyAES& key, const Vector<uint8_t>& plainText)
+{
+ auto output = crypt(1, key.key(), parameters.counterVector(), parameters.length, plainText);
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_CTR::platformDecrypt(const CryptoAlgorithmAesCtrParams& parameters, const CryptoKeyAES& key, const Vector<uint8_t>& cipherText)
+{
+ auto output = crypt(0, key.key(), parameters.counterVector(), parameters.length, cipherText);
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCM.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCM.cpp
new file mode 100644
index 000000000..2dcbbb7b8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCM.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_GCM.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesGcmParams.h"
+#include "CryptoAlgorithmAesKeyParams.h"
+#include "CryptoKeyAES.h"
+#include <wtf/CrossThreadCopier.h>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmAES_GCMInternal {
+static constexpr auto ALG128 = "A128GCM"_s;
+static constexpr auto ALG192 = "A192GCM"_s;
+static constexpr auto ALG256 = "A256GCM"_s;
+#if CPU(ADDRESS64)
+static const uint64_t PlainTextMaxLength = 549755813632ULL; // 2^39 - 256
+#endif
+static const uint8_t DefaultTagLength = 128;
+static const uint8_t ValidTagLengths[] = { 32, 64, 96, 104, 112, 120, 128 };
+}
+
+static inline bool usagesAreInvalidForCryptoAlgorithmAES_GCM(CryptoKeyUsageBitmap usages)
+{
+ return usages & (CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits);
+}
+
+static inline bool tagLengthIsValid(uint8_t tagLength)
+{
+ using namespace CryptoAlgorithmAES_GCMInternal;
+ for (size_t i = 0; i < sizeof(ValidTagLengths); i++) {
+ if (tagLength == ValidTagLengths[i])
+ return true;
+ }
+ return false;
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmAES_GCM::create()
+{
+ return adoptRef(*new CryptoAlgorithmAES_GCM);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmAES_GCM::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmAES_GCM::encrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& plainText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ using namespace CryptoAlgorithmAES_GCMInternal;
+
+ auto& aesParameters = downcast<CryptoAlgorithmAesGcmParams>(parameters);
+
+#if CPU(ADDRESS64)
+ if (plainText.size() > PlainTextMaxLength) {
+ exceptionCallback(OperationError);
+ return;
+ }
+ if (aesParameters.ivVector().size() > UINT64_MAX) {
+ exceptionCallback(OperationError);
+ return;
+ }
+ if (aesParameters.additionalDataVector().size() > UINT64_MAX) {
+ exceptionCallback(OperationError);
+ return;
+ }
+#endif
+
+ aesParameters.tagLength = aesParameters.tagLength ? aesParameters.tagLength : DefaultTagLength;
+ if (!tagLengthIsValid(*(aesParameters.tagLength))) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(aesParameters), key = WTFMove(key), plainText = WTFMove(plainText)] {
+ return platformEncrypt(parameters, downcast<CryptoKeyAES>(key.get()), plainText);
+ });
+}
+
+void CryptoAlgorithmAES_GCM::decrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& cipherText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ using namespace CryptoAlgorithmAES_GCMInternal;
+
+ auto& aesParameters = downcast<CryptoAlgorithmAesGcmParams>(parameters);
+
+ aesParameters.tagLength = aesParameters.tagLength ? aesParameters.tagLength : DefaultTagLength;
+ if (!tagLengthIsValid(*(aesParameters.tagLength))) {
+ exceptionCallback(OperationError);
+ return;
+ }
+ if (cipherText.size() < *(aesParameters.tagLength) / 8) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+#if CPU(ADDRESS64)
+ if (aesParameters.ivVector().size() > UINT64_MAX) {
+ exceptionCallback(OperationError);
+ return;
+ }
+ if (aesParameters.additionalDataVector().size() > UINT64_MAX) {
+ exceptionCallback(OperationError);
+ return;
+ }
+#endif
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(aesParameters), key = WTFMove(key), cipherText = WTFMove(cipherText)] {
+ return platformDecrypt(parameters, downcast<CryptoKeyAES>(key.get()), cipherText);
+ });
+}
+
+void CryptoAlgorithmAES_GCM::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
+{
+ const auto& aesParameters = downcast<CryptoAlgorithmAesKeyParams>(parameters);
+
+ if (usagesAreInvalidForCryptoAlgorithmAES_GCM(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_GCM, aesParameters.length, extractable, usages);
+ if (!result) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ callback(WTFMove(result));
+}
+
+void CryptoAlgorithmAES_GCM::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_GCMInternal;
+
+ if (usagesAreInvalidForCryptoAlgorithmAES_GCM(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ RefPtr<CryptoKeyAES> result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = CryptoKeyAES::importRaw(parameters.identifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Jwk: {
+ auto checkAlgCallback = [](size_t length, const String& alg) -> bool {
+ switch (length) {
+ case CryptoKeyAES::s_length128:
+ return alg.isNull() || alg == ALG128;
+ case CryptoKeyAES::s_length192:
+ return alg.isNull() || alg == ALG192;
+ case CryptoKeyAES::s_length256:
+ return alg.isNull() || alg == ALG256;
+ }
+ return false;
+ };
+ result = CryptoKeyAES::importJwk(parameters.identifier, WTFMove(std::get<JsonWebKey>(data)), extractable, usages, WTFMove(checkAlgCallback));
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmAES_GCM::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_GCMInternal;
+ const auto& aesKey = downcast<CryptoKeyAES>(key.get());
+
+ if (aesKey.key().isEmpty()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = Vector<uint8_t>(aesKey.key());
+ break;
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = aesKey.exportJwk();
+ switch (aesKey.key().size() * 8) {
+ case CryptoKeyAES::s_length128:
+ jwk.alg = String(ALG128);
+ break;
+ case CryptoKeyAES::s_length192:
+ jwk.alg = String(ALG192);
+ break;
+ case CryptoKeyAES::s_length256:
+ jwk.alg = String(ALG256);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = WTFMove(jwk);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+ExceptionOr<size_t> CryptoAlgorithmAES_GCM::getKeyLength(const CryptoAlgorithmParameters& parameters)
+{
+ return CryptoKeyAES::getKeyLength(parameters);
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCM.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCM.h
new file mode 100644
index 000000000..53310e111
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCM.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmAesGcmParams;
+class CryptoKeyAES;
+
+class CryptoAlgorithmAES_GCM final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "AES-GCM"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::AES_GCM;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmAES_GCM() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void encrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void decrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+ ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformEncrypt(const CryptoAlgorithmAesGcmParams&, const CryptoKeyAES&, const Vector<uint8_t>&);
+ static ExceptionOr<Vector<uint8_t>> platformDecrypt(const CryptoAlgorithmAesGcmParams&, const CryptoKeyAES&, const Vector<uint8_t>&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCMOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCMOpenSSL.cpp
new file mode 100644
index 000000000..0117524c8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_GCMOpenSSL.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_GCM.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesGcmParams.h"
+#include "CryptoKeyAES.h"
+#include "OpenSSLCryptoUniquePtr.h"
+#include <openssl/evp.h>
+
+namespace WebCore {
+
+static const EVP_CIPHER* aesAlgorithm(size_t keySize)
+{
+ if (keySize * 8 == 128)
+ return EVP_aes_128_gcm();
+
+ if (keySize * 8 == 192)
+ return EVP_aes_192_gcm();
+
+ if (keySize * 8 == 256)
+ return EVP_aes_256_gcm();
+
+ return nullptr;
+}
+
+static std::optional<Vector<uint8_t>> cryptEncrypt(const Vector<uint8_t>& key, const Vector<uint8_t>& iv, const Vector<uint8_t>& plainText, const Vector<uint8_t>& additionalData, uint8_t tagLength)
+{
+ const EVP_CIPHER* algorithm = aesAlgorithm(key.size());
+ if (!algorithm)
+ return std::nullopt;
+
+ EvpCipherCtxPtr ctx;
+ int len;
+
+ Vector<uint8_t> cipherText(plainText.size() + tagLength);
+ size_t tagOffset = plainText.size();
+
+ // Create and initialize the context
+ if (!(ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new())))
+ return std::nullopt;
+
+ // Disable padding
+ if (1 != EVP_CIPHER_CTX_set_padding(ctx.get(), 0))
+ return std::nullopt;
+
+ // Initialize the encryption operation
+ if (1 != EVP_EncryptInit_ex(ctx.get(), algorithm, nullptr, nullptr, nullptr))
+ return std::nullopt;
+
+ // Set IV length
+ if (1 != EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, iv.size(), nullptr))
+ return std::nullopt;
+
+ // Initialize key and IV
+ if (1 != EVP_EncryptInit_ex(ctx.get(), nullptr, nullptr, key.data(), iv.data()))
+ return std::nullopt;
+
+ // Provide any AAD data
+ if (additionalData.size() > 0) {
+ if (1 != EVP_EncryptUpdate(ctx.get(), nullptr, &len, additionalData.data(), additionalData.size()))
+ return std::nullopt;
+ }
+
+ // Provide the message to be encrypted, and obtain the encrypted output
+ if (1 != EVP_EncryptUpdate(ctx.get(), cipherText.data(), &len, plainText.data(), plainText.size()))
+ return std::nullopt;
+
+ // Finalize the encryption. Normally ciphertext bytes may be written at
+ // this stage, but this does not occur in GCM mode
+ if (1 != EVP_EncryptFinal_ex(ctx.get(), cipherText.data() + len, &len))
+ return std::nullopt;
+
+ // Get the tag
+ if (1 != EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, tagLength, cipherText.data() + tagOffset))
+ return std::nullopt;
+
+ return cipherText;
+}
+
+static std::optional<Vector<uint8_t>> cryptDecrypt(const Vector<uint8_t>& key, const Vector<uint8_t>& iv, const Vector<uint8_t>& cipherText, const Vector<uint8_t>& additionalData, uint8_t tagLength)
+{
+ const EVP_CIPHER* algorithm = aesAlgorithm(key.size());
+ if (!algorithm)
+ return std::nullopt;
+
+ EvpCipherCtxPtr ctx;
+ int len;
+ int plainTextLen;
+ int cipherTextLen = cipherText.size() - tagLength;
+
+ Vector<uint8_t> plainText(cipherText.size());
+ Vector<uint8_t> tag { cipherText.data() + cipherTextLen, tagLength };
+
+ // Create and initialize the context
+ if (!(ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new())))
+ return std::nullopt;
+
+ // Disable padding
+ if (1 != EVP_CIPHER_CTX_set_padding(ctx.get(), 0))
+ return std::nullopt;
+
+ // Initialize the encryption operation
+ if (1 != EVP_DecryptInit_ex(ctx.get(), algorithm, nullptr, nullptr, nullptr))
+ return std::nullopt;
+
+ // Set IV length
+ if (1 != EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, iv.size(), nullptr))
+ return std::nullopt;
+
+ // Initialize key and IV
+ if (1 != EVP_DecryptInit_ex(ctx.get(), nullptr, nullptr, key.data(), iv.data()))
+ return std::nullopt;
+
+ // Provide any AAD data
+ if (additionalData.size() > 0) {
+ if (1 != EVP_DecryptUpdate(ctx.get(), nullptr, &len, additionalData.data(), additionalData.size()))
+ return std::nullopt;
+ }
+
+ // Set expected tag value
+ if (1 != EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, tag.size(), tag.data()))
+ return std::nullopt;
+
+ // Provide the message to be encrypted, and obtain the encrypted output
+ if (1 != EVP_DecryptUpdate(ctx.get(), plainText.data(), &len, cipherText.data(), cipherTextLen))
+ return std::nullopt;
+ plainTextLen = len;
+
+ // Finalize the decryption
+ if (1 != EVP_DecryptFinal_ex(ctx.get(), plainText.data() + len, &len))
+ return std::nullopt;
+
+ plainTextLen += len;
+
+ plainText.shrink(plainTextLen);
+
+ return plainText;
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_GCM::platformEncrypt(const CryptoAlgorithmAesGcmParams& parameters, const CryptoKeyAES& key, const Vector<uint8_t>& plainText)
+{
+ auto output = cryptEncrypt(key.key(), parameters.ivVector(), plainText, parameters.additionalDataVector(), parameters.tagLength.value_or(0) / 8);
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_GCM::platformDecrypt(const CryptoAlgorithmAesGcmParams& parameters, const CryptoKeyAES& key, const Vector<uint8_t>& cipherText)
+{
+ auto output = cryptDecrypt(key.key(), parameters.ivVector(), cipherText, parameters.additionalDataVector(), parameters.tagLength.value_or(0) / 8);
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KW.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KW.cpp
new file mode 100644
index 000000000..adc65b645
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KW.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_KW.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesKeyParams.h"
+#include "CryptoKeyAES.h"
+#include <variant>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmAES_KWInternal {
+static constexpr auto ALG128 = "A128KW"_s;
+static constexpr auto ALG192 = "A192KW"_s;
+static constexpr auto ALG256 = "A256KW"_s;
+}
+
+static inline bool usagesAreInvalidForCryptoAlgorithmAES_KW(CryptoKeyUsageBitmap usages)
+{
+ return usages & (CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt);
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmAES_KW::create()
+{
+ return adoptRef(*new CryptoAlgorithmAES_KW);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmAES_KW::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmAES_KW::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
+{
+ if (usagesAreInvalidForCryptoAlgorithmAES_KW(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_KW, downcast<CryptoAlgorithmAesKeyParams>(parameters).length, extractable, usages);
+ if (!result) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ callback(WTFMove(result));
+}
+
+void CryptoAlgorithmAES_KW::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_KWInternal;
+
+ if (usagesAreInvalidForCryptoAlgorithmAES_KW(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ RefPtr<CryptoKeyAES> result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = CryptoKeyAES::importRaw(parameters.identifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Jwk: {
+ result = CryptoKeyAES::importJwk(parameters.identifier, WTFMove(std::get<JsonWebKey>(data)), extractable, usages, [](size_t length, const String& alg) -> bool {
+ switch (length) {
+ case CryptoKeyAES::s_length128:
+ return alg.isNull() || alg == ALG128;
+ case CryptoKeyAES::s_length192:
+ return alg.isNull() || alg == ALG192;
+ case CryptoKeyAES::s_length256:
+ return alg.isNull() || alg == ALG256;
+ }
+ return false;
+ });
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmAES_KW::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmAES_KWInternal;
+ const auto& aesKey = downcast<CryptoKeyAES>(key.get());
+
+ if (aesKey.key().isEmpty()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = Vector<uint8_t>(aesKey.key());
+ break;
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = aesKey.exportJwk();
+ switch (aesKey.key().size() * 8) {
+ case CryptoKeyAES::s_length128:
+ jwk.alg = String(ALG128);
+ break;
+ case CryptoKeyAES::s_length192:
+ jwk.alg = String(ALG192);
+ break;
+ case CryptoKeyAES::s_length256:
+ jwk.alg = String(ALG256);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = WTFMove(jwk);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+void CryptoAlgorithmAES_KW::wrapKey(Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ if (data.size() % 8) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ auto result = platformWrapKey(downcast<CryptoKeyAES>(key.get()), WTFMove(data));
+ if (result.hasException()) {
+ exceptionCallback(result.releaseException().code());
+ return;
+ }
+
+ callback(result.releaseReturnValue());
+}
+
+void CryptoAlgorithmAES_KW::unwrapKey(Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ auto result = platformUnwrapKey(downcast<CryptoKeyAES>(key.get()), WTFMove(data));
+ if (result.hasException()) {
+ exceptionCallback(result.releaseException().code());
+ return;
+ }
+
+ callback(result.releaseReturnValue());
+}
+
+ExceptionOr<size_t> CryptoAlgorithmAES_KW::getKeyLength(const CryptoAlgorithmParameters& parameters)
+{
+ return CryptoKeyAES::getKeyLength(parameters);
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KW.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KW.h
new file mode 100644
index 000000000..a08dec3f2
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KW.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKeyAES;
+
+class CryptoAlgorithmAES_KW final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "AES-KW"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::AES_KW;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmAES_KW() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+ void wrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&) final;
+ void unwrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&) final;
+ ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformWrapKey(const CryptoKeyAES&, const Vector<uint8_t>&);
+ static ExceptionOr<Vector<uint8_t>> platformUnwrapKey(const CryptoKeyAES&, const Vector<uint8_t>&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KWOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KWOpenSSL.cpp
new file mode 100644
index 000000000..606747201
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAES_KWOpenSSL.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmAES_KW.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKeyAES.h"
+#include "OpenSSLUtilities.h"
+
+namespace WebCore {
+
+static std::optional<Vector<uint8_t>> cryptWrapKey(const Vector<uint8_t>& key, const Vector<uint8_t>& data)
+{
+ if (data.size() % 8)
+ return std::nullopt;
+
+ AESKey aesKey;
+ if (!aesKey.setKey(key, AES_ENCRYPT))
+ return std::nullopt;
+
+ Vector<uint8_t> cipherText(data.size() + 8);
+ if (AES_wrap_key(aesKey.key(), nullptr, cipherText.data(), data.data(), data.size()) < 0)
+ return std::nullopt;
+
+ return cipherText;
+}
+
+static std::optional<Vector<uint8_t>> cryptUnwrapKey(const Vector<uint8_t>& key, const Vector<uint8_t>& data)
+{
+ if (data.size() % 8 || !data.size())
+ return std::nullopt;
+
+ AESKey aesKey;
+ if (!aesKey.setKey(key, AES_DECRYPT))
+ return std::nullopt;
+
+ Vector<uint8_t> plainText(data.size() - 8);
+ if (AES_unwrap_key(aesKey.key(), nullptr, plainText.data(), data.data(), data.size()) < 0)
+ return std::nullopt;
+
+ return plainText;
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_KW::platformWrapKey(const CryptoKeyAES& key, const Vector<uint8_t>& data)
+{
+ auto output = cryptWrapKey(key.key(), data);
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmAES_KW::platformUnwrapKey(const CryptoKeyAES& key, const Vector<uint8_t>& data)
+{
+ auto output = cryptUnwrapKey(key.key(), data);
+ if (!output)
+ return Exception { OperationError };
+ return WTFMove(*output);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesCbcCfbParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesCbcCfbParams.h
new file mode 100644
index 000000000..b2d8d8958
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesCbcCfbParams.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BufferSource.h"
+#include "CryptoAlgorithmParameters.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmAesCbcCfbParams final : public CryptoAlgorithmParameters {
+public:
+ BufferSource iv;
+
+ Class parametersClass() const final { return Class::AesCbcCfbParams; }
+
+ const Vector<uint8_t>& ivVector() const
+ {
+ if (!m_ivVector.isEmpty() || !iv.length())
+ return m_ivVector;
+
+ m_ivVector.append(iv.data(), iv.length());
+ return m_ivVector;
+ }
+
+ CryptoAlgorithmAesCbcCfbParams isolatedCopy() const
+ {
+ CryptoAlgorithmAesCbcCfbParams result;
+ result.identifier = identifier;
+ result.m_ivVector = ivVector();
+
+ return result;
+ }
+
+private:
+ mutable Vector<uint8_t> m_ivVector;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(AesCbcCfbParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesCtrParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesCtrParams.h
new file mode 100644
index 000000000..ded52af74
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesCtrParams.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BufferSource.h"
+#include "CryptoAlgorithmParameters.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmAesCtrParams final : public CryptoAlgorithmParameters {
+public:
+ BufferSource counter;
+ size_t length;
+
+ Class parametersClass() const final { return Class::AesCtrParams; }
+
+ const Vector<uint8_t>& counterVector() const
+ {
+ if (!m_counterVector.isEmpty() || !counter.length())
+ return m_counterVector;
+
+ m_counterVector.append(counter.data(), counter.length());
+ return m_counterVector;
+ }
+
+ CryptoAlgorithmAesCtrParams isolatedCopy() const
+ {
+ CryptoAlgorithmAesCtrParams result;
+ result.identifier = identifier;
+ result.m_counterVector = counterVector();
+ result.length = length;
+
+ return result;
+ }
+
+private:
+ mutable Vector<uint8_t> m_counterVector;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(AesCtrParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesGcmParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesGcmParams.h
new file mode 100644
index 000000000..67af03987
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesGcmParams.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BufferSource.h"
+#include "CryptoAlgorithmParameters.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmAesGcmParams final : public CryptoAlgorithmParameters {
+public:
+ BufferSource iv;
+ // Use additionalDataVector() instead of additionalData. The label will be gone once additionalDataVector() is called.
+ mutable std::optional<BufferSource::VariantType> additionalData;
+ mutable std::optional<uint8_t> tagLength;
+
+ Class parametersClass() const final { return Class::AesGcmParams; }
+
+ const Vector<uint8_t>& ivVector() const
+ {
+ if (!m_ivVector.isEmpty() || !iv.length())
+ return m_ivVector;
+
+ m_ivVector.append(iv.data(), iv.length());
+ return m_ivVector;
+ }
+
+ const Vector<uint8_t>& additionalDataVector() const
+ {
+ if (!m_additionalDataVector.isEmpty() || !additionalData)
+ return m_additionalDataVector;
+
+ BufferSource additionalDataBuffer = WTFMove(*additionalData);
+ additionalData = std::nullopt;
+ if (!additionalDataBuffer.length())
+ return m_additionalDataVector;
+
+ m_additionalDataVector.append(additionalDataBuffer.data(), additionalDataBuffer.length());
+ return m_additionalDataVector;
+ }
+
+ CryptoAlgorithmAesGcmParams isolatedCopy() const
+ {
+ CryptoAlgorithmAesGcmParams result;
+ result.identifier = identifier;
+ result.m_ivVector = ivVector();
+ result.m_additionalDataVector = additionalDataVector();
+ result.tagLength = tagLength;
+
+ return result;
+ }
+
+private:
+ mutable Vector<uint8_t> m_ivVector;
+ mutable Vector<uint8_t> m_additionalDataVector;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(AesGcmParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesKeyParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesKeyParams.h
new file mode 100644
index 000000000..c86fdcc7b
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmAesKeyParams.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmParameters.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmAesKeyParams final : public CryptoAlgorithmParameters {
+public:
+ unsigned short length;
+
+ Class parametersClass() const final { return Class::AesKeyParams; }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(AesKeyParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDH.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDH.cpp
new file mode 100644
index 000000000..05be9bb88
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDH.cpp
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmECDH.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmEcKeyParams.h"
+#include "CryptoAlgorithmEcdhKeyDeriveParams.h"
+#include "CryptoKeyEC.h"
+#include "ScriptExecutionContext.h"
+
+namespace WebCore {
+
+Ref<CryptoAlgorithm> CryptoAlgorithmECDH::create()
+{
+ return adoptRef(*new CryptoAlgorithmECDH);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmECDH::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmECDH::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
+{
+ const auto& ecParameters = downcast<CryptoAlgorithmEcKeyParams>(parameters);
+
+ if (usages & (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto result = CryptoKeyEC::generatePair(CryptoAlgorithmIdentifier::ECDH, ecParameters.namedCurve, extractable, usages);
+ if (result.hasException()) {
+ exceptionCallback(result.releaseException().code());
+ return;
+ }
+
+ auto pair = result.releaseReturnValue();
+ pair.publicKey->setUsagesBitmap(0);
+ pair.privateKey->setUsagesBitmap(pair.privateKey->usagesBitmap() & (CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits));
+ callback(WTFMove(pair));
+}
+
+void CryptoAlgorithmECDH::deriveBits(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& baseKey, size_t length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ auto& ecParameters = downcast<CryptoAlgorithmEcdhKeyDeriveParams>(parameters);
+
+ if (baseKey->type() != CryptoKey::Type::Private) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+ ASSERT(ecParameters.publicKey);
+ if (ecParameters.publicKey->type() != CryptoKey::Type::Public) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+ if (baseKey->algorithmIdentifier() != ecParameters.publicKey->algorithmIdentifier()) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+ auto& ecBaseKey = downcast<CryptoKeyEC>(baseKey.get());
+ auto& ecPublicKey = downcast<CryptoKeyEC>(*(ecParameters.publicKey.get()));
+ if (ecBaseKey.namedCurve() != ecPublicKey.namedCurve()) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ auto unifiedCallback = [callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback)](std::optional<Vector<uint8_t>>&& derivedKey, size_t length) mutable {
+ if (!derivedKey) {
+ exceptionCallback(OperationError);
+ return;
+ }
+ if (!length) {
+ callback(WTFMove(*derivedKey));
+ return;
+ }
+ auto lengthInBytes = std::ceil(length / 8.);
+ if (lengthInBytes > (*derivedKey).size()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+ (*derivedKey).shrink(lengthInBytes);
+ callback(WTFMove(*derivedKey));
+ };
+
+ // This is a special case that can't use dispatchOperation() because it bundles
+ // the result validation and callback dispatch into unifiedCallback.
+ workQueue.dispatch(
+ [baseKey = WTFMove(baseKey), publicKey = ecParameters.publicKey, length, unifiedCallback = WTFMove(unifiedCallback), contextIdentifier = context.identifier()]() mutable {
+ auto derivedKey = platformDeriveBits(downcast<CryptoKeyEC>(baseKey.get()), downcast<CryptoKeyEC>(*publicKey));
+ ScriptExecutionContext::postTaskTo(contextIdentifier, [derivedKey = WTFMove(derivedKey), length, unifiedCallback = WTFMove(unifiedCallback)](auto&) mutable {
+ unifiedCallback(WTFMove(derivedKey), length);
+ });
+ });
+}
+
+void CryptoAlgorithmECDH::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ const auto& ecParameters = downcast<CryptoAlgorithmEcKeyParams>(parameters);
+
+ RefPtr<CryptoKeyEC> result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey key = WTFMove(std::get<JsonWebKey>(data));
+
+ bool isUsagesAllowed = false;
+ if (!key.d.isNull()) {
+ isUsagesAllowed = isUsagesAllowed || !(usages ^ CryptoKeyUsageDeriveKey);
+ isUsagesAllowed = isUsagesAllowed || !(usages ^ CryptoKeyUsageDeriveBits);
+ isUsagesAllowed = isUsagesAllowed || !(usages ^ (CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits));
+ }
+ isUsagesAllowed = isUsagesAllowed || !usages;
+ if (!isUsagesAllowed) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ if (usages && !key.use.isNull() && key.use != "enc"_s) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ result = CryptoKeyEC::importJwk(ecParameters.identifier, ecParameters.namedCurve, WTFMove(key), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Raw:
+ if (usages) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ result = CryptoKeyEC::importRaw(ecParameters.identifier, ecParameters.namedCurve, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Spki:
+ if (usages) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ result = CryptoKeyEC::importSpki(ecParameters.identifier, ecParameters.namedCurve, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Pkcs8:
+ if (usages && (usages ^ CryptoKeyUsageDeriveKey) && (usages ^ CryptoKeyUsageDeriveBits) && (usages ^ (CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits))) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ result = CryptoKeyEC::importPkcs8(ecParameters.identifier, ecParameters.namedCurve, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmECDH::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ const auto& ecKey = downcast<CryptoKeyEC>(key.get());
+
+ if (!ecKey.keySizeInBits()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ auto jwk = ecKey.exportJwk();
+ if (jwk.hasException()) {
+ exceptionCallback(jwk.releaseException().code());
+ return;
+ }
+ result = jwk.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Raw: {
+ auto raw = ecKey.exportRaw();
+ if (raw.hasException()) {
+ exceptionCallback(raw.releaseException().code());
+ return;
+ }
+ result = raw.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ auto spki = ecKey.exportSpki();
+ if (spki.hasException()) {
+ exceptionCallback(spki.releaseException().code());
+ return;
+ }
+ result = spki.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ auto pkcs8 = ecKey.exportPkcs8();
+ if (pkcs8.hasException()) {
+ exceptionCallback(pkcs8.releaseException().code());
+ return;
+ }
+ result = pkcs8.releaseReturnValue();
+ break;
+ }
+ }
+
+ callback(format, WTFMove(result));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDH.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDH.h
new file mode 100644
index 000000000..32d55456c
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDH.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKeyEC;
+
+class CryptoAlgorithmECDH final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "ECDH"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::ECDH;
+ static Ref<CryptoAlgorithm> create();
+
+ // Operations can be performed directly.
+ WEBCORE_EXPORT static std::optional<Vector<uint8_t>> platformDeriveBits(const CryptoKeyEC&, const CryptoKeyEC&);
+
+private:
+ CryptoAlgorithmECDH() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void deriveBits(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, size_t length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDHOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDHOpenSSL.cpp
new file mode 100644
index 000000000..fdd07a9e4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDHOpenSSL.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmECDH.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKeyEC.h"
+#include "OpenSSLUtilities.h"
+
+namespace WebCore {
+
+std::optional<Vector<uint8_t>> CryptoAlgorithmECDH::platformDeriveBits(const CryptoKeyEC& baseKey, const CryptoKeyEC& publicKey)
+{
+ auto ctx = EvpPKeyCtxPtr(EVP_PKEY_CTX_new(baseKey.platformKey(), nullptr));
+ if (!ctx)
+ return std::nullopt;
+
+ if (EVP_PKEY_derive_init(ctx.get()) <= 0)
+ return std::nullopt;
+
+ if (EVP_PKEY_derive_set_peer(ctx.get(), publicKey.platformKey()) <= 0)
+ return std::nullopt;
+
+ // Call with a nullptr to get the required buffer size.
+ size_t keyLen;
+ if (EVP_PKEY_derive(ctx.get(), nullptr, &keyLen) <= 0)
+ return std::nullopt;
+
+ Vector<uint8_t> key(keyLen);
+ if (EVP_PKEY_derive(ctx.get(), key.data(), &keyLen) <= 0)
+ return std::nullopt;
+
+ // Shrink the buffer since the new keyLen may differ from the buffer size.
+ key.shrink(keyLen);
+
+ return key;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSA.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSA.cpp
new file mode 100644
index 000000000..dbc000620
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSA.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmECDSA.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmEcKeyParams.h"
+#include "CryptoAlgorithmEcdsaParams.h"
+#include "CryptoKeyEC.h"
+#include <JavaScriptCore/JSCJSValueInlines.h>
+#include <wtf/CrossThreadCopier.h>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmECDSAInternal {
+static constexpr auto ALG256 = "ES256"_s;
+static constexpr auto ALG384 = "ES384"_s;
+static constexpr auto ALG512 = "ES512"_s;
+static constexpr auto P256 = "P-256"_s;
+static constexpr auto P384 = "P-384"_s;
+static constexpr auto P521 = "P-521"_s;
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmECDSA::create()
+{
+ return adoptRef(*new CryptoAlgorithmECDSA);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmECDSA::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmECDSA::sign(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Private) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(downcast<CryptoAlgorithmEcdsaParams>(parameters)), key = WTFMove(key), data = WTFMove(data)] {
+ return platformSign(parameters, downcast<CryptoKeyEC>(key.get()), data);
+ });
+}
+
+void CryptoAlgorithmECDSA::verify(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& signature, Vector<uint8_t>&& data, BoolCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Public) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(downcast<CryptoAlgorithmEcdsaParams>(parameters)), key = WTFMove(key), signature = WTFMove(signature), data = WTFMove(data)] {
+ return platformVerify(parameters, downcast<CryptoKeyEC>(key.get()), signature, data);
+ });
+}
+
+void CryptoAlgorithmECDSA::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
+{
+ const auto& ecParameters = downcast<CryptoAlgorithmEcKeyParams>(parameters);
+
+ if (usages & (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto result = CryptoKeyEC::generatePair(CryptoAlgorithmIdentifier::ECDSA, ecParameters.namedCurve, extractable, usages);
+ if (result.hasException()) {
+ exceptionCallback(result.releaseException().code());
+ return;
+ }
+
+ auto pair = result.releaseReturnValue();
+ pair.publicKey->setUsagesBitmap(pair.publicKey->usagesBitmap() & CryptoKeyUsageVerify);
+ pair.privateKey->setUsagesBitmap(pair.privateKey->usagesBitmap() & CryptoKeyUsageSign);
+ callback(WTFMove(pair));
+}
+
+void CryptoAlgorithmECDSA::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmECDSAInternal;
+ const auto& ecParameters = downcast<CryptoAlgorithmEcKeyParams>(parameters);
+
+ RefPtr<CryptoKeyEC> result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey key = WTFMove(std::get<JsonWebKey>(data));
+
+ if (usages && ((!key.d.isNull() && (usages ^ CryptoKeyUsageSign)) || (key.d.isNull() && (usages ^ CryptoKeyUsageVerify)))) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ if (usages && !key.use.isNull() && key.use != "sig"_s) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ bool isMatched = false;
+ if (key.crv == P256)
+ isMatched = key.alg.isNull() || key.alg == ALG256;
+ if (key.crv == P384)
+ isMatched = key.alg.isNull() || key.alg == ALG384;
+ if (key.crv == P521)
+ isMatched = key.alg.isNull() || key.alg == ALG512;
+ if (!isMatched) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ result = CryptoKeyEC::importJwk(ecParameters.identifier, ecParameters.namedCurve, WTFMove(key), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Raw:
+ if (usages && (usages ^ CryptoKeyUsageVerify)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ result = CryptoKeyEC::importRaw(ecParameters.identifier, ecParameters.namedCurve, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Spki:
+ if (usages && (usages ^ CryptoKeyUsageVerify)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ result = CryptoKeyEC::importSpki(ecParameters.identifier, ecParameters.namedCurve, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Pkcs8:
+ if (usages && (usages ^ CryptoKeyUsageSign)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ result = CryptoKeyEC::importPkcs8(ecParameters.identifier, ecParameters.namedCurve, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmECDSA::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ const auto& ecKey = downcast<CryptoKeyEC>(key.get());
+
+ if (!ecKey.keySizeInBits()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ auto jwk = ecKey.exportJwk();
+ if (jwk.hasException()) {
+ exceptionCallback(jwk.releaseException().code());
+ return;
+ }
+ result = jwk.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Raw: {
+ auto raw = ecKey.exportRaw();
+ if (raw.hasException()) {
+ exceptionCallback(raw.releaseException().code());
+ return;
+ }
+ result = raw.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ auto spki = ecKey.exportSpki();
+ if (spki.hasException()) {
+ exceptionCallback(spki.releaseException().code());
+ return;
+ }
+ result = spki.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ auto pkcs8 = ecKey.exportPkcs8();
+ if (pkcs8.hasException()) {
+ exceptionCallback(pkcs8.releaseException().code());
+ return;
+ }
+ result = pkcs8.releaseReturnValue();
+ break;
+ }
+ }
+
+ callback(format, WTFMove(result));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSA.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSA.h
new file mode 100644
index 000000000..b7c7889f8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSA.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmEcdsaParams;
+class CryptoKeyEC;
+
+class CryptoAlgorithmECDSA final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "ECDSA"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::ECDSA;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmECDSA() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void sign(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void verify(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&& signature, Vector<uint8_t>&&, BoolCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformSign(const CryptoAlgorithmEcdsaParams&, const CryptoKeyEC&, const Vector<uint8_t>&);
+ static ExceptionOr<bool> platformVerify(const CryptoAlgorithmEcdsaParams&, const CryptoKeyEC&, const Vector<uint8_t>&, const Vector<uint8_t>&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSAOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSAOpenSSL.cpp
new file mode 100644
index 000000000..46aec1869
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmECDSAOpenSSL.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmECDSA.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmEcdsaParams.h"
+#include "CryptoKeyEC.h"
+#include "OpenSSLUtilities.h"
+
+namespace WebCore {
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmECDSA::platformSign(const CryptoAlgorithmEcdsaParams& parameters, const CryptoKeyEC& key, const Vector<uint8_t>& data)
+{
+ size_t keySizeInBytes = (key.keySizeInBits() + 7) / 8;
+
+ const EVP_MD* md = digestAlgorithm(parameters.hashIdentifier);
+ if (!md)
+ return Exception { NotSupportedError };
+
+ std::optional<Vector<uint8_t>> digest = calculateDigest(md, data);
+ if (!digest)
+ return Exception { OperationError };
+
+ EC_KEY* ecKey = EVP_PKEY_get0_EC_KEY(key.platformKey());
+ if (!ecKey)
+ return Exception { OperationError };
+
+ // We use ECDSA_do_sign rather than EVP API because the latter handles ECDSA signature in DER format
+ // while this function is supposed to return simply concatinated "r" and "s".
+ auto sig = ECDSASigPtr(ECDSA_do_sign(digest->data(), digest->size(), ecKey));
+ if (!sig)
+ return Exception { OperationError };
+
+ const BIGNUM* r;
+ const BIGNUM* s;
+ ECDSA_SIG_get0(sig.get(), &r, &s);
+
+ // Concatenate r and s, expanding r and s to keySizeInBytes.
+ Vector<uint8_t> signature = convertToBytesExpand(r, keySizeInBytes);
+ signature.appendVector(convertToBytesExpand(s, keySizeInBytes));
+
+ return signature;
+}
+
+ExceptionOr<bool> CryptoAlgorithmECDSA::platformVerify(const CryptoAlgorithmEcdsaParams& parameters, const CryptoKeyEC& key, const Vector<uint8_t>& signature, const Vector<uint8_t>& data)
+{
+ size_t keySizeInBytes = (key.keySizeInBits() + 7) / 8;
+
+ // Bail if the signature size isn't double the key size (i.e. concatenated r and s components).
+ if (signature.size() != keySizeInBytes * 2)
+ return false;
+
+ auto sig = ECDSASigPtr(ECDSA_SIG_new());
+ auto r = BN_bin2bn(signature.data(), keySizeInBytes, nullptr);
+ auto s = BN_bin2bn(signature.data() + keySizeInBytes, keySizeInBytes, nullptr);
+
+ if (!ECDSA_SIG_set0(sig.get(), r, s))
+ return Exception { OperationError };
+
+ const EVP_MD* md = digestAlgorithm(parameters.hashIdentifier);
+ if (!md)
+ return Exception { NotSupportedError };
+
+ std::optional<Vector<uint8_t>> digest = calculateDigest(md, data);
+ if (!digest)
+ return Exception { OperationError };
+
+ EC_KEY* ecKey = EVP_PKEY_get0_EC_KEY(key.platformKey());
+ if (!ecKey)
+ return Exception { OperationError };
+
+ int ret = ECDSA_do_verify(digest->data(), digest->size(), sig.get(), ecKey);
+ return ret == 1;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmEcKeyParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmEcKeyParams.h
new file mode 100644
index 000000000..eb5c459e7
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmEcKeyParams.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmParameters.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmEcKeyParams final : public CryptoAlgorithmParameters {
+public:
+ String namedCurve;
+
+ Class parametersClass() const final { return Class::EcKeyParams; }
+
+ CryptoAlgorithmEcKeyParams isolatedCopy() const
+ {
+ CryptoAlgorithmEcKeyParams result;
+ result.identifier = identifier;
+ result.namedCurve = namedCurve.isolatedCopy();
+
+ return result;
+ }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(EcKeyParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmEcdhKeyDeriveParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmEcdhKeyDeriveParams.h
new file mode 100644
index 000000000..e8149253b
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmEcdhKeyDeriveParams.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmParameters.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKey;
+
+class CryptoAlgorithmEcdhKeyDeriveParams final : public CryptoAlgorithmParameters {
+public:
+ RefPtr<CryptoKey> publicKey;
+
+ Class parametersClass() const final { return Class::EcdhKeyDeriveParams; }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(EcdhKeyDeriveParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmEcdsaParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmEcdsaParams.h
new file mode 100644
index 000000000..e08de2802
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmEcdsaParams.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmParameters.h"
+#include <JavaScriptCore/JSObject.h>
+#include <JavaScriptCore/Strong.h>
+#include <variant>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmEcdsaParams final : public CryptoAlgorithmParameters {
+public:
+ // FIXME: Consider merging hash and hashIdentifier.
+ std::variant<JSC::Strong<JSC::JSObject>, String> hash;
+ CryptoAlgorithmIdentifier hashIdentifier;
+
+ Class parametersClass() const final { return Class::EcdsaParams; }
+
+ CryptoAlgorithmEcdsaParams isolatedCopy() const
+ {
+ CryptoAlgorithmEcdsaParams result;
+ result.identifier = identifier;
+ result.hashIdentifier = hashIdentifier;
+
+ return result;
+ }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(EcdsaParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDF.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDF.cpp
new file mode 100644
index 000000000..5c7a2f4c5
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDF.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmHKDF.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmHkdfParams.h"
+#include "CryptoKeyRaw.h"
+#include <JavaScriptCore/JSCJSValueInlines.h>
+#include <wtf/CrossThreadCopier.h>
+
+namespace WebCore {
+
+Ref<CryptoAlgorithm> CryptoAlgorithmHKDF::create()
+{
+ return adoptRef(*new CryptoAlgorithmHKDF);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmHKDF::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmHKDF::deriveBits(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& baseKey, size_t length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (!length || length % 8) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(downcast<CryptoAlgorithmHkdfParams>(parameters)), baseKey = WTFMove(baseKey), length] {
+ return platformDeriveBits(parameters, downcast<CryptoKeyRaw>(baseKey.get()), length);
+ });
+}
+
+void CryptoAlgorithmHKDF::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ if (format != CryptoKeyFormat::Raw) {
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (usages & (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ if (extractable) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ callback(CryptoKeyRaw::create(parameters.identifier, WTFMove(std::get<Vector<uint8_t>>(data)), usages));
+}
+
+ExceptionOr<size_t> CryptoAlgorithmHKDF::getKeyLength(const CryptoAlgorithmParameters&)
+{
+ return 0;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDF.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDF.h
new file mode 100644
index 000000000..8f3939b19
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDF.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmHkdfParams;
+class CryptoKeyRaw;
+
+class CryptoAlgorithmHKDF final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "HKDF"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::HKDF;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmHKDF() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void deriveBits(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, size_t length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformDeriveBits(const CryptoAlgorithmHkdfParams&, const CryptoKeyRaw&, size_t);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDFOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDFOpenSSL.cpp
new file mode 100644
index 000000000..e3c113f33
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHKDFOpenSSL.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmHKDF.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmHkdfParams.h"
+#include "CryptoKeyRaw.h"
+#include "OpenSSLUtilities.h"
+#include <openssl/hkdf.h>
+
+namespace WebCore {
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmHKDF::platformDeriveBits(const CryptoAlgorithmHkdfParams& parameters, const CryptoKeyRaw& key, size_t length)
+{
+ auto algorithm = digestAlgorithm(parameters.hashIdentifier);
+ if (!algorithm)
+ return Exception { NotSupportedError };
+
+ Vector<uint8_t> output(length / 8);
+ if (HKDF(output.data(), output.size(), algorithm, key.key().data(), key.key().size(), parameters.saltVector().data(), parameters.saltVector().size(), parameters.infoVector().data(), parameters.infoVector().size()) <= 0)
+ return Exception { OperationError };
+
+ return output;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmHMAC.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHMAC.cpp
new file mode 100644
index 000000000..58eaf1b0d
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHMAC.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmHMAC.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmHmacKeyParams.h"
+#include "CryptoKeyHMAC.h"
+#include <variant>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmHMACInternal {
+static constexpr auto ALG1 = "HS1"_s;
+static constexpr auto ALG224 = "HS224"_s;
+static constexpr auto ALG256 = "HS256"_s;
+static constexpr auto ALG384 = "HS384"_s;
+static constexpr auto ALG512 = "HS512"_s;
+}
+
+static inline bool usagesAreInvalidForCryptoAlgorithmHMAC(CryptoKeyUsageBitmap usages)
+{
+ return usages & (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey);
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmHMAC::create()
+{
+ return adoptRef(*new CryptoAlgorithmHMAC);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmHMAC::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmHMAC::sign(const CryptoAlgorithmParameters&, Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [key = WTFMove(key), data = WTFMove(data)] {
+ return platformSign(downcast<CryptoKeyHMAC>(key.get()), data);
+ });
+}
+
+void CryptoAlgorithmHMAC::verify(const CryptoAlgorithmParameters&, Ref<CryptoKey>&& key, Vector<uint8_t>&& signature, Vector<uint8_t>&& data, BoolCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [key = WTFMove(key), signature = WTFMove(signature), data = WTFMove(data)] {
+ return platformVerify(downcast<CryptoKeyHMAC>(key.get()), signature, data);
+ });
+}
+
+void CryptoAlgorithmHMAC::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
+{
+ const auto& hmacParameters = downcast<CryptoAlgorithmHmacKeyParams>(parameters);
+
+ if (usagesAreInvalidForCryptoAlgorithmHMAC(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ if (hmacParameters.length && !hmacParameters.length.value()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ auto result = CryptoKeyHMAC::generate(hmacParameters.length.value_or(0), hmacParameters.hashIdentifier, extractable, usages);
+ if (!result) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ callback(WTFMove(result));
+}
+
+void CryptoAlgorithmHMAC::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmHMACInternal;
+
+ const auto& hmacParameters = downcast<CryptoAlgorithmHmacKeyParams>(parameters);
+
+ if (usagesAreInvalidForCryptoAlgorithmHMAC(usages)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ RefPtr<CryptoKeyHMAC> result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = CryptoKeyHMAC::importRaw(hmacParameters.length.value_or(0), hmacParameters.hashIdentifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ case CryptoKeyFormat::Jwk: {
+ auto checkAlgCallback = [](CryptoAlgorithmIdentifier hash, const String& alg) -> bool {
+ switch (hash) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ return alg.isNull() || alg == ALG1;
+ case CryptoAlgorithmIdentifier::SHA_224:
+ return alg.isNull() || alg == ALG224;
+ case CryptoAlgorithmIdentifier::SHA_256:
+ return alg.isNull() || alg == ALG256;
+ case CryptoAlgorithmIdentifier::SHA_384:
+ return alg.isNull() || alg == ALG384;
+ case CryptoAlgorithmIdentifier::SHA_512:
+ return alg.isNull() || alg == ALG512;
+ default:
+ return false;
+ }
+ return false;
+ };
+ result = CryptoKeyHMAC::importJwk(hmacParameters.length.value_or(0), hmacParameters.hashIdentifier, WTFMove(std::get<JsonWebKey>(data)), extractable, usages, WTFMove(checkAlgCallback));
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmHMAC::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmHMACInternal;
+ const auto& hmacKey = downcast<CryptoKeyHMAC>(key.get());
+
+ if (hmacKey.key().isEmpty()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Raw:
+ result = Vector<uint8_t>(hmacKey.key());
+ break;
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = hmacKey.exportJwk();
+ switch (hmacKey.hashAlgorithmIdentifier()) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ jwk.alg = String(ALG1);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_224:
+ jwk.alg = String(ALG224);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_256:
+ jwk.alg = String(ALG256);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_384:
+ jwk.alg = String(ALG384);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_512:
+ jwk.alg = String(ALG512);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = WTFMove(jwk);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+ExceptionOr<size_t> CryptoAlgorithmHMAC::getKeyLength(const CryptoAlgorithmParameters& parameters)
+{
+ return CryptoKeyHMAC::getKeyLength(parameters);
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmHMAC.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHMAC.h
new file mode 100644
index 000000000..9f1084698
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHMAC.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKeyHMAC;
+
+class CryptoAlgorithmHMAC final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "HMAC"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::HMAC;
+ static Ref<CryptoAlgorithm> create();
+
+ // Operations can be performed directly.
+ static ExceptionOr<Vector<uint8_t>> platformSign(const CryptoKeyHMAC&, const Vector<uint8_t>&);
+ static ExceptionOr<bool> platformVerify(const CryptoKeyHMAC&, const Vector<uint8_t>&, const Vector<uint8_t>&);
+
+private:
+ CryptoAlgorithmHMAC() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void sign(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void verify(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&& signature, Vector<uint8_t>&&, BoolCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+ ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&) final;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmHMACOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHMACOpenSSL.cpp
new file mode 100644
index 000000000..ad35cafe5
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHMACOpenSSL.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmHMAC.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKeyHMAC.h"
+#include "OpenSSLCryptoUniquePtr.h"
+#include "OpenSSLUtilities.h"
+#include <openssl/evp.h>
+#include <wtf/CryptographicUtilities.h>
+
+namespace WebCore {
+
+static std::optional<Vector<uint8_t>> calculateSignature(const EVP_MD* algorithm, const Vector<uint8_t>& key, const uint8_t* data, size_t dataLength)
+{
+ HMACCtxPtr ctx;
+ if (!(ctx = HMACCtxPtr(HMAC_CTX_new())))
+ return std::nullopt;
+
+ if (1 != HMAC_Init_ex(ctx.get(), key.data(), key.size(), algorithm, nullptr))
+ return std::nullopt;
+
+ // Call update with the message
+ if (1 != HMAC_Update(ctx.get(), data, dataLength))
+ return std::nullopt;
+
+ // Finalize the DigestSign operation
+ Vector<uint8_t> cipherText(EVP_MAX_MD_SIZE);
+ unsigned len = 0;
+ if (1 != HMAC_Final(ctx.get(), cipherText.data(), &len))
+ return std::nullopt;
+
+ cipherText.shrink(len);
+ return cipherText;
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmHMAC::platformSign(const CryptoKeyHMAC& key, const Vector<uint8_t>& data)
+{
+ auto algorithm = digestAlgorithm(key.hashAlgorithmIdentifier());
+ if (!algorithm)
+ return Exception { OperationError };
+
+ auto result = calculateSignature(algorithm, key.key(), data.data(), data.size());
+ if (!result)
+ return Exception { OperationError };
+ return WTFMove(*result);
+}
+
+ExceptionOr<bool> CryptoAlgorithmHMAC::platformVerify(const CryptoKeyHMAC& key, const Vector<uint8_t>& signature, const Vector<uint8_t>& data)
+{
+ auto algorithm = digestAlgorithm(key.hashAlgorithmIdentifier());
+ if (!algorithm)
+ return Exception { OperationError };
+
+ auto expectedSignature = calculateSignature(algorithm, key.key(), data.data(), data.size());
+ if (!expectedSignature)
+ return Exception { OperationError };
+ // Using a constant time comparison to prevent timing attacks.
+ return signature.size() == expectedSignature->size() && !constantTimeMemcmp(expectedSignature->data(), signature.data(), expectedSignature->size());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmHkdfParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHkdfParams.h
new file mode 100644
index 000000000..961886391
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHkdfParams.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BufferSource.h"
+#include "CryptoAlgorithmParameters.h"
+#include <JavaScriptCore/JSObject.h>
+#include <JavaScriptCore/Strong.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmHkdfParams final : public CryptoAlgorithmParameters {
+public:
+ // FIXME: Consider merging hash and hashIdentifier.
+ std::variant<JSC::Strong<JSC::JSObject>, String> hash;
+ CryptoAlgorithmIdentifier hashIdentifier;
+ BufferSource salt;
+ BufferSource info;
+
+ const Vector<uint8_t>& saltVector() const
+ {
+ if (!m_saltVector.isEmpty() || !salt.length())
+ return m_saltVector;
+
+ m_saltVector.append(salt.data(), salt.length());
+ return m_saltVector;
+ }
+
+ const Vector<uint8_t>& infoVector() const
+ {
+ if (!m_infoVector.isEmpty() || !info.length())
+ return m_infoVector;
+
+ m_infoVector.append(info.data(), info.length());
+ return m_infoVector;
+ }
+
+ Class parametersClass() const final { return Class::HkdfParams; }
+
+ CryptoAlgorithmHkdfParams isolatedCopy() const
+ {
+ CryptoAlgorithmHkdfParams result;
+ result.identifier = identifier;
+ result.m_saltVector = saltVector();
+ result.m_infoVector = infoVector();
+ result.hashIdentifier = hashIdentifier;
+
+ return result;
+ }
+
+private:
+ mutable Vector<uint8_t> m_saltVector;
+ mutable Vector<uint8_t> m_infoVector;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(HkdfParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmHmacKeyParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHmacKeyParams.h
new file mode 100644
index 000000000..c9b09f90c
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmHmacKeyParams.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmParameters.h"
+#include <JavaScriptCore/JSObject.h>
+#include <JavaScriptCore/Strong.h>
+#include <variant>
+
+namespace WebCore {
+
+class CryptoAlgorithmHmacKeyParams final : public CryptoAlgorithmParameters {
+public:
+ // FIXME: Consider merging hash and hashIdentifier.
+ std::variant<JSC::Strong<JSC::JSObject>, String> hash;
+ CryptoAlgorithmIdentifier hashIdentifier;
+ std::optional<size_t> length;
+
+ Class parametersClass() const final { return Class::HmacKeyParams; }
+
+ CryptoAlgorithmHmacKeyParams isolatedCopy() const
+ {
+ CryptoAlgorithmHmacKeyParams result;
+ result.identifier = identifier;
+ result.hashIdentifier = hashIdentifier;
+ result.length = length;
+
+ return result;
+ }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(HmacKeyParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmIdentifier.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmIdentifier.h
new file mode 100644
index 000000000..657a7aadb
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmIdentifier.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+enum class CryptoAlgorithmIdentifier {
+ RSAES_PKCS1_v1_5 = 1,
+ RSASSA_PKCS1_v1_5,
+ RSA_PSS,
+ RSA_OAEP,
+ ECDSA,
+ ECDH,
+ AES_CTR,
+ AES_CBC,
+ AES_GCM,
+ AES_CFB,
+ AES_KW,
+ HMAC,
+ SHA_1,
+ SHA_224,
+ SHA_256,
+ SHA_384,
+ SHA_512,
+ HKDF,
+ PBKDF2
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2.cpp
new file mode 100644
index 000000000..268c051d9
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmPBKDF2.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmPbkdf2Params.h"
+#include "CryptoKeyRaw.h"
+#include <JavaScriptCore/JSCJSValueInlines.h>
+#include <wtf/CrossThreadCopier.h>
+
+namespace WebCore {
+
+Ref<CryptoAlgorithm> CryptoAlgorithmPBKDF2::create()
+{
+ return adoptRef(*new CryptoAlgorithmPBKDF2);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmPBKDF2::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmPBKDF2::deriveBits(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& baseKey, size_t length, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (!length || length % 8) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(downcast<CryptoAlgorithmPbkdf2Params>(parameters)), baseKey = WTFMove(baseKey), length] {
+ return platformDeriveBits(parameters, downcast<CryptoKeyRaw>(baseKey.get()), length);
+ });
+}
+
+void CryptoAlgorithmPBKDF2::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ if (format != CryptoKeyFormat::Raw) {
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (usages & (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ if (extractable) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ callback(CryptoKeyRaw::create(parameters.identifier, WTFMove(std::get<Vector<uint8_t>>(data)), usages));
+}
+
+ExceptionOr<size_t> CryptoAlgorithmPBKDF2::getKeyLength(const CryptoAlgorithmParameters&)
+{
+ return 0;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2.h
new file mode 100644
index 000000000..34069e51f
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmPbkdf2Params;
+class CryptoKeyRaw;
+
+class CryptoAlgorithmPBKDF2 final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "PBKDF2"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::PBKDF2;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmPBKDF2() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void deriveBits(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, size_t length, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformDeriveBits(const CryptoAlgorithmPbkdf2Params&, const CryptoKeyRaw&, size_t);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2OpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2OpenSSL.cpp
new file mode 100644
index 000000000..124d7e2d1
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmPBKDF2OpenSSL.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmPBKDF2.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmPbkdf2Params.h"
+#include "CryptoKeyRaw.h"
+#include "OpenSSLUtilities.h"
+#include <openssl/evp.h>
+
+namespace WebCore {
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmPBKDF2::platformDeriveBits(const CryptoAlgorithmPbkdf2Params& parameters, const CryptoKeyRaw& key, size_t length)
+{
+ auto algorithm = digestAlgorithm(parameters.hashIdentifier);
+ if (!algorithm)
+ return Exception { NotSupportedError };
+
+ // iterations must not be zero.
+ if (!parameters.iterations)
+ return Exception { OperationError };
+
+ Vector<uint8_t> output(length / 8);
+ if (PKCS5_PBKDF2_HMAC(reinterpret_cast<const char*>(key.key().data()), key.key().size(), parameters.saltVector().data(), parameters.saltVector().size(), parameters.iterations, algorithm, output.size(), output.data()) <= 0)
+ return Exception { OperationError };
+
+ return output;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmParameters.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmParameters.h
new file mode 100644
index 000000000..8398404b8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmParameters.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmIdentifier.h"
+#include <wtf/TypeCasts.h>
+#include <wtf/text/WTFString.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmParameters {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ enum class Class {
+ None,
+ AesCbcCfbParams,
+ AesCtrParams,
+ AesGcmParams,
+ AesKeyParams,
+ EcKeyParams,
+ EcdhKeyDeriveParams,
+ EcdsaParams,
+ HkdfParams,
+ HmacKeyParams,
+ Pbkdf2Params,
+ RsaHashedKeyGenParams,
+ RsaHashedImportParams,
+ RsaKeyGenParams,
+ RsaOaepParams,
+ RsaPssParams,
+ };
+
+ // FIXME: Consider merging name and identifier.
+ String name;
+ CryptoAlgorithmIdentifier identifier;
+
+ virtual ~CryptoAlgorithmParameters() = default;
+
+ virtual Class parametersClass() const { return Class::None; }
+};
+
+} // namespace WebCore
+
+#define SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(ToClassName) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::CryptoAlgorithm##ToClassName) \
+static bool isType(const WebCore::CryptoAlgorithmParameters& parameters) { return parameters.parametersClass() == WebCore::CryptoAlgorithmParameters::Class::ToClassName; } \
+SPECIALIZE_TYPE_TRAITS_END()
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmParameters.idl b/src/bun.js/bindings/webcrypto/CryptoAlgorithmParameters.idl
new file mode 100644
index 000000000..5d6aa9604
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmParameters.idl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+] dictionary CryptoAlgorithmParameters {
+ required DOMString name;
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmPbkdf2Params.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmPbkdf2Params.h
new file mode 100644
index 000000000..2aff182c4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmPbkdf2Params.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BufferSource.h"
+#include "CryptoAlgorithmParameters.h"
+#include <JavaScriptCore/JSObject.h>
+#include <JavaScriptCore/Strong.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmPbkdf2Params final : public CryptoAlgorithmParameters {
+public:
+ BufferSource salt;
+ unsigned long iterations;
+ // FIXME: Consider merging hash and hashIdentifier.
+ std::variant<JSC::Strong<JSC::JSObject>, String> hash;
+ CryptoAlgorithmIdentifier hashIdentifier;
+
+ const Vector<uint8_t>& saltVector() const
+ {
+ if (!m_saltVector.isEmpty() || !salt.length())
+ return m_saltVector;
+
+ m_saltVector.append(salt.data(), salt.length());
+ return m_saltVector;
+ }
+
+ Class parametersClass() const final { return Class::Pbkdf2Params; }
+
+ CryptoAlgorithmPbkdf2Params isolatedCopy() const
+ {
+ CryptoAlgorithmPbkdf2Params result;
+ result.identifier = identifier;
+ result.m_saltVector = saltVector();
+ result.iterations = iterations;
+ result.hashIdentifier = hashIdentifier;
+
+ return result;
+ }
+
+private:
+ mutable Vector<uint8_t> m_saltVector;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(Pbkdf2Params)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp
new file mode 100644
index 000000000..9eace1362
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRSAES_PKCS1_v1_5.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRsaKeyGenParams.h"
+#include "CryptoKeyPair.h"
+#include "CryptoKeyRSA.h"
+#include <variant>
+
+namespace WebCore {
+
+static constexpr auto ALG = "RSA1_5"_s;
+
+Ref<CryptoAlgorithm> CryptoAlgorithmRSAES_PKCS1_v1_5::create()
+{
+ return adoptRef(*new CryptoAlgorithmRSAES_PKCS1_v1_5);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmRSAES_PKCS1_v1_5::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmRSAES_PKCS1_v1_5::encrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&& key, Vector<uint8_t>&& plainText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Public) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [key = WTFMove(key), plainText = WTFMove(plainText)] {
+ return platformEncrypt(downcast<CryptoKeyRSA>(key.get()), plainText);
+ });
+}
+
+void CryptoAlgorithmRSAES_PKCS1_v1_5::decrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&& key, Vector<uint8_t>&& cipherText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Private) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [key = WTFMove(key), cipherText = WTFMove(cipherText)] {
+ return platformDecrypt(downcast<CryptoKeyRSA>(key.get()), cipherText);
+ });
+}
+
+void CryptoAlgorithmRSAES_PKCS1_v1_5::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context)
+{
+ const auto& rsaParameters = downcast<CryptoAlgorithmRsaKeyGenParams>(parameters);
+
+ if (usages & (CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto keyPairCallback = [capturedCallback = WTFMove(callback)](CryptoKeyPair&& pair) {
+ pair.publicKey->setUsagesBitmap(pair.publicKey->usagesBitmap() & CryptoKeyUsageEncrypt);
+ pair.privateKey->setUsagesBitmap(pair.privateKey->usagesBitmap() & CryptoKeyUsageDecrypt);
+ capturedCallback(WTFMove(pair));
+ };
+ auto failureCallback = [capturedCallback = WTFMove(exceptionCallback)]() {
+ capturedCallback(OperationError);
+ };
+ // Notice: CryptoAlgorithmIdentifier::SHA_1 is just a placeholder. It should not have any effect.
+ CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5, CryptoAlgorithmIdentifier::SHA_1, false, rsaParameters.modulusLength, rsaParameters.publicExponentVector(), extractable, usages, WTFMove(keyPairCallback), WTFMove(failureCallback), &context);
+}
+
+void CryptoAlgorithmRSAES_PKCS1_v1_5::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ RefPtr<CryptoKeyRSA> result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey key = WTFMove(std::get<JsonWebKey>(data));
+ if (usages && ((!key.d.isNull() && (usages ^ CryptoKeyUsageDecrypt)) || (key.d.isNull() && (usages ^ CryptoKeyUsageEncrypt)))) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ if (usages && !key.use.isNull() && key.use != "enc"_s) {
+ exceptionCallback(DataError);
+ return;
+ }
+ if (!key.alg.isNull() && key.alg != ALG) {
+ exceptionCallback(DataError);
+ return;
+ }
+ result = CryptoKeyRSA::importJwk(parameters.identifier, std::nullopt, WTFMove(key), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ if (usages && (usages ^ CryptoKeyUsageEncrypt)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ result = CryptoKeyRSA::importSpki(parameters.identifier, std::nullopt, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ if (usages && (usages ^ CryptoKeyUsageDecrypt)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ result = CryptoKeyRSA::importPkcs8(parameters.identifier, std::nullopt, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmRSAES_PKCS1_v1_5::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ const auto& rsaKey = downcast<CryptoKeyRSA>(key.get());
+
+ if (!rsaKey.keySizeInBits()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = rsaKey.exportJwk();
+ jwk.alg = String(ALG);
+ result = WTFMove(jwk);
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ auto spki = rsaKey.exportSpki();
+ if (spki.hasException()) {
+ exceptionCallback(spki.releaseException().code());
+ return;
+ }
+ result = spki.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ auto pkcs8 = rsaKey.exportPkcs8();
+ if (pkcs8.hasException()) {
+ exceptionCallback(pkcs8.releaseException().code());
+ return;
+ }
+ result = pkcs8.releaseReturnValue();
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5.h
new file mode 100644
index 000000000..d21e6c1ee
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKeyRSA;
+
+class CryptoAlgorithmRSAES_PKCS1_v1_5 final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "RSAES-PKCS1-v1_5"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmRSAES_PKCS1_v1_5() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void encrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void decrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformEncrypt(const CryptoKeyRSA&, const Vector<uint8_t>&);
+ static ExceptionOr<Vector<uint8_t>> platformDecrypt(const CryptoKeyRSA&, const Vector<uint8_t>&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5OpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5OpenSSL.cpp
new file mode 100644
index 000000000..63b5b9551
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSAES_PKCS1_v1_5OpenSSL.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2021 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRSAES_PKCS1_v1_5.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKeyRSA.h"
+#include "OpenSSLUtilities.h"
+
+namespace WebCore {
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSAES_PKCS1_v1_5::platformEncrypt(const CryptoKeyRSA& key, const Vector<uint8_t>& plainText)
+{
+ auto ctx = EvpPKeyCtxPtr(EVP_PKEY_CTX_new(key.platformKey(), nullptr));
+ if (!ctx)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) <= 0)
+ return Exception { OperationError };
+
+ size_t cipherTextLen;
+ if (EVP_PKEY_encrypt(ctx.get(), nullptr, &cipherTextLen, plainText.data(), plainText.size()) <= 0)
+ return Exception { OperationError };
+
+ Vector<uint8_t> cipherText(cipherTextLen);
+ if (EVP_PKEY_encrypt(ctx.get(), cipherText.data(), &cipherTextLen, plainText.data(), plainText.size()) <= 0)
+ return Exception { OperationError };
+ cipherText.shrink(cipherTextLen);
+
+ return cipherText;
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSAES_PKCS1_v1_5::platformDecrypt(const CryptoKeyRSA& key, const Vector<uint8_t>& cipherText)
+{
+ auto ctx = EvpPKeyCtxPtr(EVP_PKEY_CTX_new(key.platformKey(), nullptr));
+ if (!ctx)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) <= 0)
+ return Exception { OperationError };
+
+ size_t plainTextLen;
+ if (EVP_PKEY_decrypt(ctx.get(), nullptr, &plainTextLen, cipherText.data(), cipherText.size()) <= 0)
+ return Exception { OperationError };
+
+ Vector<uint8_t> plainText(plainTextLen);
+ if (EVP_PKEY_decrypt(ctx.get(), plainText.data(), &plainTextLen, cipherText.data(), cipherText.size()) <= 0)
+ return Exception { OperationError };
+ plainText.shrink(plainTextLen);
+
+ return plainText;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp
new file mode 100644
index 000000000..156e641f2
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRSASSA_PKCS1_v1_5.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRsaHashedImportParams.h"
+#include "CryptoAlgorithmRsaHashedKeyGenParams.h"
+#include "CryptoKeyPair.h"
+#include "CryptoKeyRSA.h"
+#include <variant>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmRSASSA_PKCS1_v1_5Internal {
+static constexpr auto ALG1 = "RS1"_s;
+static constexpr auto ALG224 = "RS224"_s;
+static constexpr auto ALG256 = "RS256"_s;
+static constexpr auto ALG384 = "RS384"_s;
+static constexpr auto ALG512 = "RS512"_s;
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmRSASSA_PKCS1_v1_5::create()
+{
+ return adoptRef(*new CryptoAlgorithmRSASSA_PKCS1_v1_5);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmRSASSA_PKCS1_v1_5::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmRSASSA_PKCS1_v1_5::sign(const CryptoAlgorithmParameters&, Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Private) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [key = WTFMove(key), data = WTFMove(data)] {
+ return platformSign(downcast<CryptoKeyRSA>(key.get()), data);
+ });
+}
+
+void CryptoAlgorithmRSASSA_PKCS1_v1_5::verify(const CryptoAlgorithmParameters&, Ref<CryptoKey>&& key, Vector<uint8_t>&& signature, Vector<uint8_t>&& data, BoolCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Public) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [key = WTFMove(key), signature = WTFMove(signature), data = WTFMove(data)] {
+ return platformVerify(downcast<CryptoKeyRSA>(key.get()), signature, data);
+ });
+}
+
+void CryptoAlgorithmRSASSA_PKCS1_v1_5::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context)
+{
+ const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedKeyGenParams>(parameters);
+
+ if (usages & (CryptoKeyUsageDecrypt | CryptoKeyUsageEncrypt | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto keyPairCallback = [capturedCallback = WTFMove(callback)](CryptoKeyPair&& pair) {
+ pair.publicKey->setUsagesBitmap(pair.publicKey->usagesBitmap() & CryptoKeyUsageVerify);
+ pair.privateKey->setUsagesBitmap(pair.privateKey->usagesBitmap() & CryptoKeyUsageSign);
+ capturedCallback(WTFMove(pair));
+ };
+ auto failureCallback = [capturedCallback = WTFMove(exceptionCallback)]() {
+ capturedCallback(OperationError);
+ };
+ CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5, rsaParameters.hashIdentifier, true, rsaParameters.modulusLength, rsaParameters.publicExponentVector(), extractable, usages, WTFMove(keyPairCallback), WTFMove(failureCallback), &context);
+}
+
+void CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmRSASSA_PKCS1_v1_5Internal;
+
+ const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedImportParams>(parameters);
+
+ RefPtr<CryptoKeyRSA> result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey key = WTFMove(std::get<JsonWebKey>(data));
+
+ if (usages && ((!key.d.isNull() && (usages ^ CryptoKeyUsageSign)) || (key.d.isNull() && (usages ^ CryptoKeyUsageVerify)))) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ if (usages && !key.use.isNull() && key.use != "sig"_s) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ bool isMatched = false;
+ switch (rsaParameters.hashIdentifier) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ isMatched = key.alg.isNull() || key.alg == ALG1;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_224:
+ isMatched = key.alg.isNull() || key.alg == ALG224;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_256:
+ isMatched = key.alg.isNull() || key.alg == ALG256;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_384:
+ isMatched = key.alg.isNull() || key.alg == ALG384;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_512:
+ isMatched = key.alg.isNull() || key.alg == ALG512;
+ break;
+ default:
+ break;
+ }
+ if (!isMatched) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ result = CryptoKeyRSA::importJwk(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(key), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ if (usages && (usages ^ CryptoKeyUsageVerify)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ // FIXME: <webkit.org/b/165436>
+ result = CryptoKeyRSA::importSpki(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ if (usages && (usages ^ CryptoKeyUsageSign)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ // FIXME: <webkit.org/b/165436>
+ result = CryptoKeyRSA::importPkcs8(parameters.identifier, rsaParameters.hashIdentifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmRSASSA_PKCS1_v1_5::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmRSASSA_PKCS1_v1_5Internal;
+ const auto& rsaKey = downcast<CryptoKeyRSA>(key.get());
+
+ if (!rsaKey.keySizeInBits()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = rsaKey.exportJwk();
+ switch (rsaKey.hashAlgorithmIdentifier()) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ jwk.alg = String(ALG1);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_224:
+ jwk.alg = String(ALG224);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_256:
+ jwk.alg = String(ALG256);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_384:
+ jwk.alg = String(ALG384);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_512:
+ jwk.alg = String(ALG512);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = WTFMove(jwk);
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ auto spki = rsaKey.exportSpki();
+ if (spki.hasException()) {
+ exceptionCallback(spki.releaseException().code());
+ return;
+ }
+ result = spki.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ auto pkcs8 = rsaKey.exportPkcs8();
+ if (pkcs8.hasException()) {
+ exceptionCallback(pkcs8.releaseException().code());
+ return;
+ }
+ result = pkcs8.releaseReturnValue();
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5.h
new file mode 100644
index 000000000..d185d3a4b
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKeyRSA;
+
+class CryptoAlgorithmRSASSA_PKCS1_v1_5 final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "RSASSA-PKCS1-v1_5"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmRSASSA_PKCS1_v1_5() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void sign(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void verify(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&& signature, Vector<uint8_t>&&, BoolCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformSign(const CryptoKeyRSA&, const Vector<uint8_t>&);
+ static ExceptionOr<bool> platformVerify(const CryptoKeyRSA&, const Vector<uint8_t>&, const Vector<uint8_t>&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5OpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5OpenSSL.cpp
new file mode 100644
index 000000000..acfeee790
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSASSA_PKCS1_v1_5OpenSSL.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2021 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRSASSA_PKCS1_v1_5.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKeyRSA.h"
+#include "OpenSSLUtilities.h"
+
+namespace WebCore {
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSASSA_PKCS1_v1_5::platformSign(const CryptoKeyRSA& key, const Vector<uint8_t>& data)
+{
+ const EVP_MD* md = digestAlgorithm(key.hashAlgorithmIdentifier());
+ if (!md)
+ return Exception { NotSupportedError };
+
+ std::optional<Vector<uint8_t>> digest = calculateDigest(md, data);
+ if (!digest)
+ return Exception { OperationError };
+
+ auto ctx = EvpPKeyCtxPtr(EVP_PKEY_CTX_new(key.platformKey(), nullptr));
+ if (!ctx)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_sign_init(ctx.get()) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_signature_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ size_t signatureLen;
+ if (EVP_PKEY_sign(ctx.get(), nullptr, &signatureLen, digest->data(), digest->size()) <= 0)
+ return Exception { OperationError };
+
+ Vector<uint8_t> signature(signatureLen);
+ if (EVP_PKEY_sign(ctx.get(), signature.data(), &signatureLen, digest->data(), digest->size()) <= 0)
+ return Exception { OperationError };
+ signature.shrink(signatureLen);
+
+ return signature;
+}
+
+ExceptionOr<bool> CryptoAlgorithmRSASSA_PKCS1_v1_5::platformVerify(const CryptoKeyRSA& key, const Vector<uint8_t>& signature, const Vector<uint8_t>& data)
+{
+ const EVP_MD* md = digestAlgorithm(key.hashAlgorithmIdentifier());
+ if (!md)
+ return Exception { NotSupportedError };
+
+ std::optional<Vector<uint8_t>> digest = calculateDigest(md, data);
+ if (!digest)
+ return Exception { OperationError };
+
+ auto ctx = EvpPKeyCtxPtr(EVP_PKEY_CTX_new(key.platformKey(), nullptr));
+ if (!ctx)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_verify_init(ctx.get()) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_signature_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ int ret = EVP_PKEY_verify(ctx.get(), signature.data(), signature.size(), digest->data(), digest->size());
+
+ return ret == 1;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEP.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEP.cpp
new file mode 100644
index 000000000..259778276
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEP.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRSA_OAEP.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRsaHashedImportParams.h"
+#include "CryptoAlgorithmRsaHashedKeyGenParams.h"
+#include "CryptoAlgorithmRsaOaepParams.h"
+#include "CryptoKeyPair.h"
+#include "CryptoKeyRSA.h"
+#include <variant>
+#include <wtf/CrossThreadCopier.h>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmRSA_OAEPInternal {
+static constexpr auto ALG1 = "RSA-OAEP"_s;
+static constexpr auto ALG224 = "RSA-OAEP-224"_s;
+static constexpr auto ALG256 = "RSA-OAEP-256"_s;
+static constexpr auto ALG384 = "RSA-OAEP-384"_s;
+static constexpr auto ALG512 = "RSA-OAEP-512"_s;
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmRSA_OAEP::create()
+{
+ return adoptRef(*new CryptoAlgorithmRSA_OAEP);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmRSA_OAEP::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmRSA_OAEP::encrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& plainText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Public) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(downcast<CryptoAlgorithmRsaOaepParams>(parameters)), key = WTFMove(key), plainText = WTFMove(plainText)] {
+ return platformEncrypt(parameters, downcast<CryptoKeyRSA>(key.get()), plainText);
+ });
+}
+
+void CryptoAlgorithmRSA_OAEP::decrypt(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& cipherText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Private) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(downcast<CryptoAlgorithmRsaOaepParams>(parameters)), key = WTFMove(key), cipherText = WTFMove(cipherText)] {
+ return platformDecrypt(parameters, downcast<CryptoKeyRSA>(key.get()), cipherText);
+ });
+}
+
+void CryptoAlgorithmRSA_OAEP::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context)
+{
+ const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedKeyGenParams>(parameters);
+
+ if (usages & (CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto keyPairCallback = [capturedCallback = WTFMove(callback)](CryptoKeyPair&& pair) {
+ pair.publicKey->setUsagesBitmap(pair.publicKey->usagesBitmap() & (CryptoKeyUsageEncrypt | CryptoKeyUsageWrapKey));
+ pair.privateKey->setUsagesBitmap(pair.privateKey->usagesBitmap() & (CryptoKeyUsageDecrypt | CryptoKeyUsageUnwrapKey));
+ capturedCallback(WTFMove(pair));
+ };
+ auto failureCallback = [capturedCallback = WTFMove(exceptionCallback)]() {
+ capturedCallback(OperationError);
+ };
+ CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSA_OAEP, rsaParameters.hashIdentifier, true, rsaParameters.modulusLength, rsaParameters.publicExponentVector(), extractable, usages, WTFMove(keyPairCallback), WTFMove(failureCallback), &context);
+}
+
+void CryptoAlgorithmRSA_OAEP::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmRSA_OAEPInternal;
+
+ const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedImportParams>(parameters);
+
+ RefPtr<CryptoKeyRSA> result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey key = WTFMove(std::get<JsonWebKey>(data));
+
+ bool isUsagesAllowed = false;
+ if (!key.d.isNull()) {
+ isUsagesAllowed = isUsagesAllowed || !(usages ^ CryptoKeyUsageDecrypt);
+ isUsagesAllowed = isUsagesAllowed || !(usages ^ CryptoKeyUsageUnwrapKey);
+ isUsagesAllowed = isUsagesAllowed || !(usages ^ (CryptoKeyUsageDecrypt | CryptoKeyUsageUnwrapKey));
+ } else {
+ isUsagesAllowed = isUsagesAllowed || !(usages ^ CryptoKeyUsageEncrypt);
+ isUsagesAllowed = isUsagesAllowed || !(usages ^ CryptoKeyUsageWrapKey);
+ isUsagesAllowed = isUsagesAllowed || !(usages ^ (CryptoKeyUsageEncrypt | CryptoKeyUsageWrapKey));
+ }
+ isUsagesAllowed = isUsagesAllowed || !usages;
+ if (!isUsagesAllowed) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ if (usages && !key.use.isNull() && key.use != "enc"_s) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ bool isMatched = false;
+ switch (rsaParameters.hashIdentifier) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ isMatched = key.alg.isNull() || key.alg == ALG1;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_224:
+ isMatched = key.alg.isNull() || key.alg == ALG224;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_256:
+ isMatched = key.alg.isNull() || key.alg == ALG256;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_384:
+ isMatched = key.alg.isNull() || key.alg == ALG384;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_512:
+ isMatched = key.alg.isNull() || key.alg == ALG512;
+ break;
+ default:
+ break;
+ }
+ if (!isMatched) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ result = CryptoKeyRSA::importJwk(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(key), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ if (usages && (usages ^ CryptoKeyUsageEncrypt) && (usages ^ CryptoKeyUsageWrapKey) && (usages ^ (CryptoKeyUsageEncrypt | CryptoKeyUsageWrapKey))) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ // FIXME: <webkit.org/b/165436>
+ result = CryptoKeyRSA::importSpki(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ if (usages && (usages ^ CryptoKeyUsageDecrypt) && (usages ^ CryptoKeyUsageUnwrapKey) && (usages ^ (CryptoKeyUsageDecrypt | CryptoKeyUsageUnwrapKey))) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ // FIXME: <webkit.org/b/165436>
+ result = CryptoKeyRSA::importPkcs8(parameters.identifier, rsaParameters.hashIdentifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmRSA_OAEP::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmRSA_OAEPInternal;
+ const auto& rsaKey = downcast<CryptoKeyRSA>(key.get());
+
+ if (!rsaKey.keySizeInBits()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = rsaKey.exportJwk();
+ switch (rsaKey.hashAlgorithmIdentifier()) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ jwk.alg = String(ALG1);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_224:
+ jwk.alg = String(ALG224);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_256:
+ jwk.alg = String(ALG256);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_384:
+ jwk.alg = String(ALG384);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_512:
+ jwk.alg = String(ALG512);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = WTFMove(jwk);
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ // FIXME: <webkit.org/b/165437>
+ auto spki = rsaKey.exportSpki();
+ if (spki.hasException()) {
+ exceptionCallback(spki.releaseException().code());
+ return;
+ }
+ result = spki.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ // FIXME: <webkit.org/b/165437>
+ auto pkcs8 = rsaKey.exportPkcs8();
+ if (pkcs8.hasException()) {
+ exceptionCallback(pkcs8.releaseException().code());
+ return;
+ }
+ result = pkcs8.releaseReturnValue();
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEP.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEP.h
new file mode 100644
index 000000000..dba7ea9d5
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEP.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaOaepParams;
+class CryptoKeyRSA;
+
+class CryptoAlgorithmRSA_OAEP final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "RSA-OAEP"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::RSA_OAEP;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmRSA_OAEP() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void encrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void decrypt(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformEncrypt(const CryptoAlgorithmRsaOaepParams&, const CryptoKeyRSA&, const Vector<uint8_t>&);
+ static ExceptionOr<Vector<uint8_t>> platformDecrypt(const CryptoAlgorithmRsaOaepParams&, const CryptoKeyRSA&, const Vector<uint8_t>&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEPOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEPOpenSSL.cpp
new file mode 100644
index 000000000..4a3dbb6b7
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEPOpenSSL.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2021 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRSA_OAEP.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRsaOaepParams.h"
+#include "CryptoKeyRSA.h"
+#include "OpenSSLUtilities.h"
+
+namespace WebCore {
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSA_OAEP::platformEncrypt(const CryptoAlgorithmRsaOaepParams& parameters, const CryptoKeyRSA& key, const Vector<uint8_t>& plainText)
+{
+#if defined(EVP_PKEY_CTX_set_rsa_oaep_md) && defined(EVP_PKEY_CTX_set_rsa_mgf1_md) && defined(EVP_PKEY_CTX_set0_rsa_oaep_label)
+ const EVP_MD* md = digestAlgorithm(key.hashAlgorithmIdentifier());
+ if (!md)
+ return Exception { NotSupportedError };
+
+ auto ctx = EvpPKeyCtxPtr(EVP_PKEY_CTX_new(key.platformKey(), nullptr));
+ if (!ctx)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_OAEP_PADDING) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ if (!parameters.labelVector().isEmpty()) {
+ size_t labelSize = parameters.labelVector().size();
+ // The library takes ownership of the label so the caller should not free the original memory pointed to by label.
+ auto label = OPENSSL_malloc(labelSize);
+ memcpy(label, parameters.labelVector().data(), labelSize);
+ if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(), label, labelSize) <= 0) {
+ OPENSSL_free(label);
+ return Exception { OperationError };
+ }
+ }
+
+ size_t cipherTextLen;
+ if (EVP_PKEY_encrypt(ctx.get(), nullptr, &cipherTextLen, plainText.data(), plainText.size()) <= 0)
+ return Exception { OperationError };
+
+ Vector<uint8_t> cipherText(cipherTextLen);
+ if (EVP_PKEY_encrypt(ctx.get(), cipherText.data(), &cipherTextLen, plainText.data(), plainText.size()) <= 0)
+ return Exception { OperationError };
+ cipherText.shrink(cipherTextLen);
+
+ return cipherText;
+#else
+ return Exception { NotSupportedError };
+#endif
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSA_OAEP::platformDecrypt(const CryptoAlgorithmRsaOaepParams& parameters, const CryptoKeyRSA& key, const Vector<uint8_t>& cipherText)
+{
+#if defined(EVP_PKEY_CTX_set_rsa_oaep_md) && defined(EVP_PKEY_CTX_set_rsa_mgf1_md) && defined(EVP_PKEY_CTX_set0_rsa_oaep_label)
+ const EVP_MD* md = digestAlgorithm(key.hashAlgorithmIdentifier());
+ if (!md)
+ return Exception { NotSupportedError };
+
+ auto ctx = EvpPKeyCtxPtr(EVP_PKEY_CTX_new(key.platformKey(), nullptr));
+ if (!ctx)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_OAEP_PADDING) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ if (!parameters.labelVector().isEmpty()) {
+ size_t labelSize = parameters.labelVector().size();
+ // The library takes ownership of the label so the caller should not free the original memory pointed to by label.
+ auto label = OPENSSL_malloc(labelSize);
+ memcpy(label, parameters.labelVector().data(), labelSize);
+ if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(), label, labelSize) <= 0) {
+ OPENSSL_free(label);
+ return Exception { OperationError };
+ }
+ }
+
+ size_t plainTextLen;
+ if (EVP_PKEY_decrypt(ctx.get(), nullptr, &plainTextLen, cipherText.data(), cipherText.size()) <= 0)
+ return Exception { OperationError };
+
+ Vector<uint8_t> plainText(plainTextLen);
+ if (EVP_PKEY_decrypt(ctx.get(), plainText.data(), &plainTextLen, cipherText.data(), cipherText.size()) <= 0)
+ return Exception { OperationError };
+ plainText.shrink(plainTextLen);
+
+ return plainText;
+#else
+ return Exception { NotSupportedError };
+#endif
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSS.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSS.cpp
new file mode 100644
index 000000000..2d3f5d931
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSS.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRSA_PSS.h"
+
+#if ENABLE(WEB_CRYPTO) && HAVE(RSA_PSS)
+
+#include "CryptoAlgorithmRsaHashedImportParams.h"
+#include "CryptoAlgorithmRsaHashedKeyGenParams.h"
+#include "CryptoAlgorithmRsaPssParams.h"
+#include "CryptoKeyPair.h"
+#include "CryptoKeyRSA.h"
+#include <variant>
+#include <wtf/CrossThreadCopier.h>
+
+namespace WebCore {
+
+namespace CryptoAlgorithmRSA_PSSInternal {
+static constexpr auto ALG1 = "PS1"_s;
+static constexpr auto ALG224 = "PS224"_s;
+static constexpr auto ALG256 = "PS256"_s;
+static constexpr auto ALG384 = "PS384"_s;
+static constexpr auto ALG512 = "PS512"_s;
+}
+
+Ref<CryptoAlgorithm> CryptoAlgorithmRSA_PSS::create()
+{
+ return adoptRef(*new CryptoAlgorithmRSA_PSS);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmRSA_PSS::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmRSA_PSS::sign(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Private) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(downcast<CryptoAlgorithmRsaPssParams>(parameters)), key = WTFMove(key), data = WTFMove(data)] {
+ return platformSign(parameters, downcast<CryptoKeyRSA>(key.get()), data);
+ });
+}
+
+void CryptoAlgorithmRSA_PSS::verify(const CryptoAlgorithmParameters& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& signature, Vector<uint8_t>&& data, BoolCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ if (key->type() != CryptoKeyType::Public) {
+ exceptionCallback(InvalidAccessError);
+ return;
+ }
+
+ dispatchOperationInWorkQueue(workQueue, context, WTFMove(callback), WTFMove(exceptionCallback),
+ [parameters = crossThreadCopy(downcast<CryptoAlgorithmRsaPssParams>(parameters)), key = WTFMove(key), signature = WTFMove(signature), data = WTFMove(data)] {
+ return platformVerify(parameters, downcast<CryptoKeyRSA>(key.get()), signature, data);
+ });
+}
+
+void CryptoAlgorithmRSA_PSS::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context)
+{
+ const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedKeyGenParams>(parameters);
+
+ if (usages & (CryptoKeyUsageDecrypt | CryptoKeyUsageEncrypt | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+
+ auto keyPairCallback = [capturedCallback = WTFMove(callback)](CryptoKeyPair&& pair) {
+ pair.publicKey->setUsagesBitmap(pair.publicKey->usagesBitmap() & CryptoKeyUsageVerify);
+ pair.privateKey->setUsagesBitmap(pair.privateKey->usagesBitmap() & CryptoKeyUsageSign);
+ capturedCallback(WTFMove(pair));
+ };
+ auto failureCallback = [capturedCallback = WTFMove(exceptionCallback)]() {
+ capturedCallback(OperationError);
+ };
+ CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSA_PSS, rsaParameters.hashIdentifier, true, rsaParameters.modulusLength, rsaParameters.publicExponentVector(), extractable, usages, WTFMove(keyPairCallback), WTFMove(failureCallback), &context);
+}
+
+void CryptoAlgorithmRSA_PSS::importKey(CryptoKeyFormat format, KeyData&& data, const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmRSA_PSSInternal;
+
+ const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedImportParams>(parameters);
+
+ RefPtr<CryptoKeyRSA> result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey key = WTFMove(std::get<JsonWebKey>(data));
+
+ if (usages && ((!key.d.isNull() && (usages ^ CryptoKeyUsageSign)) || (key.d.isNull() && (usages ^ CryptoKeyUsageVerify)))) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ if (usages && !key.use.isNull() && key.use != "sig"_s) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ bool isMatched = false;
+ switch (rsaParameters.hashIdentifier) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ isMatched = key.alg.isNull() || key.alg == ALG1;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_224:
+ isMatched = key.alg.isNull() || key.alg == ALG224;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_256:
+ isMatched = key.alg.isNull() || key.alg == ALG256;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_384:
+ isMatched = key.alg.isNull() || key.alg == ALG384;
+ break;
+ case CryptoAlgorithmIdentifier::SHA_512:
+ isMatched = key.alg.isNull() || key.alg == ALG512;
+ break;
+ default:
+ break;
+ }
+ if (!isMatched) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ result = CryptoKeyRSA::importJwk(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(key), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ if (usages && (usages ^ CryptoKeyUsageVerify)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ // FIXME: <webkit.org/b/165436>
+ result = CryptoKeyRSA::importSpki(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ if (usages && (usages ^ CryptoKeyUsageSign)) {
+ exceptionCallback(SyntaxError);
+ return;
+ }
+ // FIXME: <webkit.org/b/165436>
+ result = CryptoKeyRSA::importPkcs8(parameters.identifier, rsaParameters.hashIdentifier, WTFMove(std::get<Vector<uint8_t>>(data)), extractable, usages);
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+ if (!result) {
+ exceptionCallback(DataError);
+ return;
+ }
+
+ callback(*result);
+}
+
+void CryptoAlgorithmRSA_PSS::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+ using namespace CryptoAlgorithmRSA_PSSInternal;
+ const auto& rsaKey = downcast<CryptoKeyRSA>(key.get());
+
+ if (!rsaKey.keySizeInBits()) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ KeyData result;
+ switch (format) {
+ case CryptoKeyFormat::Jwk: {
+ JsonWebKey jwk = rsaKey.exportJwk();
+ switch (rsaKey.hashAlgorithmIdentifier()) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ jwk.alg = String(ALG1);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_224:
+ jwk.alg = String(ALG224);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_256:
+ jwk.alg = String(ALG256);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_384:
+ jwk.alg = String(ALG384);
+ break;
+ case CryptoAlgorithmIdentifier::SHA_512:
+ jwk.alg = String(ALG512);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = WTFMove(jwk);
+ break;
+ }
+ case CryptoKeyFormat::Spki: {
+ auto spki = rsaKey.exportSpki();
+ if (spki.hasException()) {
+ exceptionCallback(spki.releaseException().code());
+ return;
+ }
+ result = spki.releaseReturnValue();
+ break;
+ }
+ case CryptoKeyFormat::Pkcs8: {
+ auto pkcs8 = rsaKey.exportPkcs8();
+ if (pkcs8.hasException()) {
+ exceptionCallback(pkcs8.releaseException().code());
+ return;
+ }
+ result = pkcs8.releaseReturnValue();
+ break;
+ }
+ default:
+ exceptionCallback(NotSupportedError);
+ return;
+ }
+
+ callback(format, WTFMove(result));
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO) && HAVE(RSA_PSS)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSS.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSS.h
new file mode 100644
index 000000000..b1f7f772c
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSS.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO) && HAVE(RSA_PSS)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaPssParams;
+class CryptoKeyRSA;
+
+class CryptoAlgorithmRSA_PSS final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "RSA-PSS"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::RSA_PSS;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmRSA_PSS() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+
+ void sign(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void verify(const CryptoAlgorithmParameters&, Ref<CryptoKey>&&, Vector<uint8_t>&& signature, Vector<uint8_t>&&, BoolCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+ void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+ void importKey(CryptoKeyFormat, KeyData&&, const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+ void exportKey(CryptoKeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+
+ static ExceptionOr<Vector<uint8_t>> platformSign(const CryptoAlgorithmRsaPssParams&, const CryptoKeyRSA&, const Vector<uint8_t>&);
+ static ExceptionOr<bool> platformVerify(const CryptoAlgorithmRsaPssParams&, const CryptoKeyRSA&, const Vector<uint8_t>&, const Vector<uint8_t>&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO) && HAVE(RSA_PSS)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSSOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSSOpenSSL.cpp
new file mode 100644
index 000000000..62267c581
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSSOpenSSL.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2021 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRSA_PSS.h"
+
+#if ENABLE(WEB_CRYPTO) && HAVE(RSA_PSS)
+
+#include "CryptoAlgorithmRsaPssParams.h"
+#include "CryptoKeyRSA.h"
+#include "OpenSSLUtilities.h"
+
+namespace WebCore {
+
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSA_PSS::platformSign(const CryptoAlgorithmRsaPssParams& parameters, const CryptoKeyRSA& key, const Vector<uint8_t>& data)
+{
+#if defined(EVP_PKEY_CTX_set_rsa_pss_saltlen) && defined(EVP_PKEY_CTX_set_rsa_mgf1_md)
+ const EVP_MD* md = digestAlgorithm(key.hashAlgorithmIdentifier());
+ if (!md)
+ return Exception { NotSupportedError };
+
+ std::optional<Vector<uint8_t>> digest = calculateDigest(md, data);
+ if (!digest)
+ return Exception { OperationError };
+
+ auto ctx = EvpPKeyCtxPtr(EVP_PKEY_CTX_new(key.platformKey(), nullptr));
+ if (!ctx)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_sign_init(ctx.get()) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PSS_PADDING ) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(), parameters.saltLength) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_signature_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ size_t signatureLen;
+ if (EVP_PKEY_sign(ctx.get(), nullptr, &signatureLen, digest->data(), digest->size()) <= 0)
+ return Exception { OperationError };
+
+ Vector<uint8_t> signature(signatureLen);
+ if (EVP_PKEY_sign(ctx.get(), signature.data(), &signatureLen, digest->data(), digest->size()) <= 0)
+ return Exception { OperationError };
+ signature.shrink(signatureLen);
+
+ return signature;
+#else
+ return Exception { NotSupportedError };
+#endif
+}
+
+ExceptionOr<bool> CryptoAlgorithmRSA_PSS::platformVerify(const CryptoAlgorithmRsaPssParams& parameters, const CryptoKeyRSA& key, const Vector<uint8_t>& signature, const Vector<uint8_t>& data)
+{
+#if defined(EVP_PKEY_CTX_set_rsa_pss_saltlen) && defined(EVP_PKEY_CTX_set_rsa_mgf1_md)
+ const EVP_MD* md = digestAlgorithm(key.hashAlgorithmIdentifier());
+ if (!md)
+ return Exception { NotSupportedError };
+
+ std::optional<Vector<uint8_t>> digest = calculateDigest(md, data);
+ if (!digest)
+ return Exception { OperationError };
+
+ auto ctx = EvpPKeyCtxPtr(EVP_PKEY_CTX_new(key.platformKey(), nullptr));
+ if (!ctx)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_verify_init(ctx.get()) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PSS_PADDING ) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(), parameters.saltLength) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_signature_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), md) <= 0)
+ return Exception { OperationError };
+
+ int ret = EVP_PKEY_verify(ctx.get(), signature.data(), signature.size(), digest->data(), digest->size());
+
+ return ret == 1;
+#else
+ return Exception { NotSupportedError };
+#endif
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistry.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistry.cpp
new file mode 100644
index 000000000..92c90fbe4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistry.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRegistry.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithm.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+CryptoAlgorithmRegistry& CryptoAlgorithmRegistry::singleton()
+{
+ static LazyNeverDestroyed<CryptoAlgorithmRegistry> registry;
+ static std::once_flag onceKey;
+ std::call_once(onceKey, [&] {
+ registry.construct();
+ });
+ return registry;
+}
+
+CryptoAlgorithmRegistry::CryptoAlgorithmRegistry()
+{
+ platformRegisterAlgorithms();
+}
+
+std::optional<CryptoAlgorithmIdentifier> CryptoAlgorithmRegistry::identifier(const String& name)
+{
+ if (name.isEmpty())
+ return std::nullopt;
+
+ Locker locker { m_lock };
+
+ // FIXME: How is it helpful to call isolatedCopy on the argument to find?
+ auto identifier = m_identifiers.find(name.isolatedCopy());
+ if (identifier == m_identifiers.end())
+ return std::nullopt;
+
+ return identifier->value;
+}
+
+String CryptoAlgorithmRegistry::name(CryptoAlgorithmIdentifier identifier)
+{
+ Locker locker { m_lock };
+
+ auto contructor = m_constructors.find(static_cast<unsigned>(identifier));
+ if (contructor == m_constructors.end())
+ return { };
+
+ return contructor->value.first.isolatedCopy();
+}
+
+RefPtr<CryptoAlgorithm> CryptoAlgorithmRegistry::create(CryptoAlgorithmIdentifier identifier)
+{
+ Locker locker { m_lock };
+
+ auto contructor = m_constructors.find(static_cast<unsigned>(identifier));
+ if (contructor == m_constructors.end())
+ return nullptr;
+
+ return contructor->value.second();
+}
+
+void CryptoAlgorithmRegistry::registerAlgorithm(const String& name, CryptoAlgorithmIdentifier identifier, CryptoAlgorithmConstructor constructor)
+{
+ Locker locker { m_lock };
+
+ ASSERT(!m_identifiers.contains(name));
+ ASSERT(!m_constructors.contains(static_cast<unsigned>(identifier)));
+
+ m_identifiers.add(name, identifier);
+ m_constructors.add(static_cast<unsigned>(identifier), std::make_pair(name, constructor));
+}
+
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistry.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistry.h
new file mode 100644
index 000000000..49d75b2af
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistry.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmIdentifier.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/text/StringHash.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithm;
+
+class CryptoAlgorithmRegistry {
+ WTF_MAKE_NONCOPYABLE(CryptoAlgorithmRegistry);
+ friend class LazyNeverDestroyed<CryptoAlgorithmRegistry>;
+
+public:
+ static CryptoAlgorithmRegistry& singleton();
+
+ std::optional<CryptoAlgorithmIdentifier> identifier(const String&);
+ String name(CryptoAlgorithmIdentifier);
+
+ RefPtr<CryptoAlgorithm> create(CryptoAlgorithmIdentifier);
+
+private:
+ CryptoAlgorithmRegistry();
+ void platformRegisterAlgorithms();
+
+ using CryptoAlgorithmConstructor = Ref<CryptoAlgorithm> (*)();
+
+ template<typename AlgorithmClass> void registerAlgorithm()
+ {
+ registerAlgorithm(AlgorithmClass::s_name, AlgorithmClass::s_identifier, AlgorithmClass::create);
+ }
+
+ void registerAlgorithm(const String& name, CryptoAlgorithmIdentifier, CryptoAlgorithmConstructor);
+
+ Lock m_lock;
+ HashMap<String, CryptoAlgorithmIdentifier, ASCIICaseInsensitiveHash> m_identifiers WTF_GUARDED_BY_LOCK(m_lock);
+ HashMap<unsigned, std::pair<String, CryptoAlgorithmConstructor>> m_constructors WTF_GUARDED_BY_LOCK(m_lock);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistryOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistryOpenSSL.cpp
new file mode 100644
index 000000000..1976a01a8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRegistryOpenSSL.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmRegistry.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAES_CBC.h"
+#include "CryptoAlgorithmAES_CFB.h"
+#include "CryptoAlgorithmAES_CTR.h"
+#include "CryptoAlgorithmAES_GCM.h"
+#include "CryptoAlgorithmAES_KW.h"
+#include "CryptoAlgorithmECDH.h"
+#include "CryptoAlgorithmECDSA.h"
+#include "CryptoAlgorithmHKDF.h"
+#include "CryptoAlgorithmHMAC.h"
+#include "CryptoAlgorithmPBKDF2.h"
+#include "CryptoAlgorithmRSAES_PKCS1_v1_5.h"
+#include "CryptoAlgorithmRSASSA_PKCS1_v1_5.h"
+#include "CryptoAlgorithmRSA_OAEP.h"
+#include "CryptoAlgorithmRSA_PSS.h"
+#include "CryptoAlgorithmSHA1.h"
+#include "CryptoAlgorithmSHA224.h"
+#include "CryptoAlgorithmSHA256.h"
+#include "CryptoAlgorithmSHA384.h"
+#include "CryptoAlgorithmSHA512.h"
+
+namespace WebCore {
+
+void CryptoAlgorithmRegistry::platformRegisterAlgorithms()
+{
+ registerAlgorithm<CryptoAlgorithmAES_CBC>();
+ registerAlgorithm<CryptoAlgorithmAES_CFB>();
+ registerAlgorithm<CryptoAlgorithmAES_CTR>();
+ registerAlgorithm<CryptoAlgorithmAES_GCM>();
+ registerAlgorithm<CryptoAlgorithmAES_KW>();
+ registerAlgorithm<CryptoAlgorithmECDH>();
+ registerAlgorithm<CryptoAlgorithmECDSA>();
+ registerAlgorithm<CryptoAlgorithmHKDF>();
+ registerAlgorithm<CryptoAlgorithmHMAC>();
+ registerAlgorithm<CryptoAlgorithmPBKDF2>();
+ registerAlgorithm<CryptoAlgorithmRSAES_PKCS1_v1_5>();
+ registerAlgorithm<CryptoAlgorithmRSASSA_PKCS1_v1_5>();
+ registerAlgorithm<CryptoAlgorithmRSA_OAEP>();
+ registerAlgorithm<CryptoAlgorithmRSA_PSS>();
+ registerAlgorithm<CryptoAlgorithmSHA1>();
+ registerAlgorithm<CryptoAlgorithmSHA224>();
+ registerAlgorithm<CryptoAlgorithmSHA256>();
+ registerAlgorithm<CryptoAlgorithmSHA384>();
+ registerAlgorithm<CryptoAlgorithmSHA512>();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaHashedImportParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaHashedImportParams.h
new file mode 100644
index 000000000..4883f7869
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaHashedImportParams.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmParameters.h"
+#include <JavaScriptCore/JSObject.h>
+#include <JavaScriptCore/Strong.h>
+#include <variant>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaHashedImportParams final : public CryptoAlgorithmParameters {
+public:
+ // FIXME: Consider merging hash and hashIdentifier.
+ std::variant<JSC::Strong<JSC::JSObject>, String> hash;
+ CryptoAlgorithmIdentifier hashIdentifier;
+
+ Class parametersClass() const final { return Class::RsaHashedImportParams; }
+
+ CryptoAlgorithmRsaHashedImportParams isolatedCopy() const
+ {
+ CryptoAlgorithmRsaHashedImportParams result;
+ result.identifier = identifier;
+ result.hashIdentifier = hashIdentifier;
+
+ return result;
+ }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(RsaHashedImportParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaHashedKeyGenParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaHashedKeyGenParams.h
new file mode 100644
index 000000000..ea72bde12
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaHashedKeyGenParams.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmRsaKeyGenParams.h"
+#include <JavaScriptCore/JSObject.h>
+#include <JavaScriptCore/Strong.h>
+#include <variant>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaHashedKeyGenParams final : public CryptoAlgorithmRsaKeyGenParams {
+public:
+ // FIXME: Consider merging hash and hashIdentifier.
+ std::variant<JSC::Strong<JSC::JSObject>, String> hash;
+ CryptoAlgorithmIdentifier hashIdentifier;
+
+ Class parametersClass() const final { return Class::RsaHashedKeyGenParams; }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(RsaHashedKeyGenParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaKeyGenParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaKeyGenParams.h
new file mode 100644
index 000000000..af67fd2ad
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaKeyGenParams.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmParameters.h"
+#include <JavaScriptCore/Uint8Array.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaKeyGenParams : public CryptoAlgorithmParameters {
+public:
+ size_t modulusLength;
+ RefPtr<Uint8Array> publicExponent;
+
+ Class parametersClass() const override { return Class::RsaKeyGenParams; }
+
+ const Vector<uint8_t>& publicExponentVector() const
+ {
+ if (!m_publicExponentVector.isEmpty() || !publicExponent->byteLength())
+ return m_publicExponentVector;
+
+ m_publicExponentVector.append(publicExponent->data(), publicExponent->byteLength());
+ return m_publicExponentVector;
+ }
+private:
+ mutable Vector<uint8_t> m_publicExponentVector;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(RsaKeyGenParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaOaepParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaOaepParams.h
new file mode 100644
index 000000000..769f3d9cb
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaOaepParams.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BufferSource.h"
+#include "CryptoAlgorithmParameters.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaOaepParams final : public CryptoAlgorithmParameters {
+public:
+ // Use labelVector() instead of label. The label will be gone once labelVector() is called.
+ mutable std::optional<BufferSource::VariantType> label;
+
+ Class parametersClass() const final { return Class::RsaOaepParams; }
+
+ const Vector<uint8_t>& labelVector() const
+ {
+ if (!m_labelVector.isEmpty() || !label)
+ return m_labelVector;
+
+ BufferSource labelBuffer = WTFMove(*label);
+ label = std::nullopt;
+ if (!labelBuffer.length())
+ return m_labelVector;
+
+ m_labelVector.append(labelBuffer.data(), labelBuffer.length());
+ return m_labelVector;
+ }
+
+ CryptoAlgorithmRsaOaepParams isolatedCopy() const
+ {
+ CryptoAlgorithmRsaOaepParams result;
+ result.identifier = identifier;
+ result.m_labelVector = labelVector();
+
+ return result;
+ }
+
+private:
+ mutable Vector<uint8_t> m_labelVector;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(RsaOaepParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaPssParams.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaPssParams.h
new file mode 100644
index 000000000..412f4ce05
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmRsaPssParams.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmParameters.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaPssParams final : public CryptoAlgorithmParameters {
+public:
+ size_t saltLength;
+
+ Class parametersClass() const final { return Class::RsaPssParams; }
+
+ CryptoAlgorithmRsaPssParams isolatedCopy() const
+ {
+ CryptoAlgorithmRsaPssParams result;
+ result.identifier = identifier;
+ result.saltLength = saltLength;
+
+ return result;
+ }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(RsaPssParams)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA1.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA1.cpp
new file mode 100644
index 000000000..f602467e0
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA1.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmSHA1.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "ScriptExecutionContext.h"
+#include "CryptoDigest.h"
+
+namespace WebCore {
+
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA1::create()
+{
+ return adoptRef(*new CryptoAlgorithmSHA1);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmSHA1::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmSHA1::digest(Vector<uint8_t>&& message, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ auto digest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_1);
+ if (!digest) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
+ digest->addBytes(message.data(), message.size());
+ auto result = digest->computeHash();
+ ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
+ callback(result);
+ });
+ });
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA1.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA1.h
new file mode 100644
index 000000000..1fd775a81
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA1.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmSHA1 final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "SHA-1"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_1;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmSHA1() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+ void digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA224.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA224.cpp
new file mode 100644
index 000000000..dfb8204b5
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA224.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmSHA224.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "ScriptExecutionContext.h"
+#include "CryptoDigest.h"
+
+namespace WebCore {
+
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA224::create()
+{
+ return adoptRef(*new CryptoAlgorithmSHA224);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmSHA224::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmSHA224::digest(Vector<uint8_t>&& message, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ auto digest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_224);
+ if (!digest) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
+ digest->addBytes(message.data(), message.size());
+ auto result = digest->computeHash();
+ ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
+ callback(result);
+ });
+ });
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA224.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA224.h
new file mode 100644
index 000000000..493e162ab
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA224.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmSHA224 final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "SHA-224"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_224;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmSHA224() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+ void digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA256.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA256.cpp
new file mode 100644
index 000000000..216eccb5d
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA256.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmSHA256.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "ScriptExecutionContext.h"
+#include "CryptoDigest.h"
+
+namespace WebCore {
+
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA256::create()
+{
+ return adoptRef(*new CryptoAlgorithmSHA256);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmSHA256::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmSHA256::digest(Vector<uint8_t>&& message, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ auto digest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_256);
+ if (!digest) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
+ digest->addBytes(message.data(), message.size());
+ auto result = digest->computeHash();
+ ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
+ callback(result);
+ });
+ });
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA256.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA256.h
new file mode 100644
index 000000000..f5a8543c8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA256.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmSHA256 final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "SHA-256"_s;
+ static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_256;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmSHA256() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+ void digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA384.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA384.cpp
new file mode 100644
index 000000000..134e89bd8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA384.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmSHA384.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "ScriptExecutionContext.h"
+#include "CryptoDigest.h"
+
+namespace WebCore {
+
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA384::create()
+{
+ return adoptRef(*new CryptoAlgorithmSHA384);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmSHA384::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmSHA384::digest(Vector<uint8_t>&& message, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ auto digest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_384);
+ if (!digest) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
+ digest->addBytes(message.data(), message.size());
+ auto result = digest->computeHash();
+ ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
+ callback(result);
+ });
+ });
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA384.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA384.h
new file mode 100644
index 000000000..e5bf2232a
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA384.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmSHA384 final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "SHA-384"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_384;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmSHA384() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+ void digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA512.cpp b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA512.cpp
new file mode 100644
index 000000000..016a47bf1
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA512.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoAlgorithmSHA512.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "ScriptExecutionContext.h"
+#include "CryptoDigest.h"
+
+namespace WebCore {
+
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA512::create()
+{
+ return adoptRef(*new CryptoAlgorithmSHA512);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmSHA512::identifier() const
+{
+ return s_identifier;
+}
+
+void CryptoAlgorithmSHA512::digest(Vector<uint8_t>&& message, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+ auto digest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_512);
+ if (!digest) {
+ exceptionCallback(OperationError);
+ return;
+ }
+
+ workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
+ digest->addBytes(message.data(), message.size());
+ auto result = digest->computeHash();
+ ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
+ callback(result);
+ });
+ });
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA512.h b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA512.h
new file mode 100644
index 000000000..05f98fc4a
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA512.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmSHA512 final : public CryptoAlgorithm {
+public:
+ static constexpr ASCIILiteral s_name = "SHA-512"_s;
+ static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_512;
+ static Ref<CryptoAlgorithm> create();
+
+private:
+ CryptoAlgorithmSHA512() = default;
+ CryptoAlgorithmIdentifier identifier() const final;
+ void digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoDigest.cpp b/src/bun.js/bindings/webcrypto/CryptoDigest.cpp
new file mode 100644
index 000000000..8704c0c08
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoDigest.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2018 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoDigest.h"
+
+#include <openssl/sha.h>
+
+namespace {
+struct SHA1Functions {
+ static constexpr auto init = SHA1_Init;
+ static constexpr auto update = SHA1_Update;
+ static constexpr auto final = SHA1_Final;
+ static constexpr size_t digestLength = SHA_DIGEST_LENGTH;
+};
+
+struct SHA224Functions {
+ static constexpr auto init = SHA224_Init;
+ static constexpr auto update = SHA224_Update;
+ static constexpr auto final = SHA224_Final;
+ static constexpr size_t digestLength = SHA224_DIGEST_LENGTH;
+};
+
+struct SHA256Functions {
+ static constexpr auto init = SHA256_Init;
+ static constexpr auto update = SHA256_Update;
+ static constexpr auto final = SHA256_Final;
+ static constexpr size_t digestLength = SHA256_DIGEST_LENGTH;
+};
+
+struct SHA384Functions {
+ static constexpr auto init = SHA384_Init;
+ static constexpr auto update = SHA384_Update;
+ static constexpr auto final = SHA384_Final;
+ static constexpr size_t digestLength = SHA384_DIGEST_LENGTH;
+};
+
+struct SHA512Functions {
+ static constexpr auto init = SHA512_Init;
+ static constexpr auto update = SHA512_Update;
+ static constexpr auto final = SHA512_Final;
+ static constexpr size_t digestLength = SHA512_DIGEST_LENGTH;
+};
+}
+
+namespace PAL {
+
+struct CryptoDigestContext {
+ virtual ~CryptoDigestContext() = default;
+ virtual void addBytes(const void* input, size_t length) = 0;
+ virtual Vector<uint8_t> computeHash() = 0;
+};
+
+template<typename SHAContext, typename SHAFunctions>
+struct CryptoDigestContextImpl : public CryptoDigestContext {
+ WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+ static std::unique_ptr<CryptoDigestContext> create()
+ {
+ return makeUnique<CryptoDigestContextImpl>();
+ }
+
+ CryptoDigestContextImpl()
+ {
+ SHAFunctions::init(&m_context);
+ }
+
+ void addBytes(const void* input, size_t length) override
+ {
+ SHAFunctions::update(&m_context, input, length);
+ }
+
+ Vector<uint8_t> computeHash() override
+ {
+ Vector<uint8_t> result(SHAFunctions::digestLength);
+ SHAFunctions::final(result.data(), &m_context);
+ return result;
+ }
+
+private:
+ SHAContext m_context;
+};
+
+CryptoDigest::CryptoDigest()
+{
+}
+
+CryptoDigest::~CryptoDigest()
+{
+}
+
+std::unique_ptr<CryptoDigest> CryptoDigest::create(CryptoDigest::Algorithm algorithm)
+{
+ std::unique_ptr<CryptoDigest> digest(new CryptoDigest);
+
+ switch (algorithm) {
+ case CryptoDigest::Algorithm::SHA_1:
+ digest->m_context = CryptoDigestContextImpl<SHA_CTX, SHA1Functions>::create();
+ return digest;
+ case CryptoDigest::Algorithm::SHA_224:
+ digest->m_context = CryptoDigestContextImpl<SHA256_CTX, SHA224Functions>::create();
+ return digest;
+ case CryptoDigest::Algorithm::SHA_256:
+ digest->m_context = CryptoDigestContextImpl<SHA256_CTX, SHA256Functions>::create();
+ return digest;
+ case CryptoDigest::Algorithm::SHA_384:
+ digest->m_context = CryptoDigestContextImpl<SHA512_CTX, SHA384Functions>::create();
+ return digest;
+ case CryptoDigest::Algorithm::SHA_512:
+ digest->m_context = CryptoDigestContextImpl<SHA512_CTX, SHA512Functions>::create();
+ return digest;
+ }
+
+ return nullptr;
+}
+
+void CryptoDigest::addBytes(const void* input, size_t length)
+{
+ ASSERT(m_context);
+ m_context->addBytes(input, length);
+}
+
+Vector<uint8_t> CryptoDigest::computeHash()
+{
+ ASSERT(m_context);
+ return m_context->computeHash();
+}
+
+} // namespace PAL
diff --git a/src/bun.js/bindings/webcrypto/CryptoDigest.h b/src/bun.js/bindings/webcrypto/CryptoDigest.h
new file mode 100644
index 000000000..5da849a1d
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoDigest.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+#ifndef PAL_EXPORT
+#define PAL_EXPORT
+#endif
+
+namespace PAL {
+
+struct CryptoDigestContext;
+
+class CryptoDigest {
+ WTF_MAKE_NONCOPYABLE(CryptoDigest);
+
+public:
+ enum class Algorithm {
+ SHA_1,
+ SHA_224,
+ SHA_256,
+ SHA_384,
+ SHA_512,
+ };
+ PAL_EXPORT static std::unique_ptr<CryptoDigest> create(Algorithm);
+ PAL_EXPORT ~CryptoDigest();
+
+ PAL_EXPORT void addBytes(const void* input, size_t length);
+ PAL_EXPORT Vector<uint8_t> computeHash();
+ PAL_EXPORT String toHexString();
+
+private:
+ CryptoDigest();
+
+ std::unique_ptr<CryptoDigestContext> m_context;
+};
+
+} // namespace PAL
diff --git a/src/bun.js/bindings/webcrypto/CryptoEcKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/CryptoEcKeyAlgorithm.h
new file mode 100644
index 000000000..dc6e67683
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoEcKeyAlgorithm.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoKeyAlgorithm.h"
+
+namespace WebCore {
+
+struct CryptoEcKeyAlgorithm : CryptoKeyAlgorithm {
+ // The named curve that the key uses
+ String namedCurve;
+};
+
+}
+
diff --git a/src/bun.js/bindings/webcrypto/CryptoEcKeyAlgorithm.idl b/src/bun.js/bindings/webcrypto/CryptoEcKeyAlgorithm.idl
new file mode 100644
index 000000000..1096a3b1b
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoEcKeyAlgorithm.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef DOMString NamedCurve;
+
+[
+ Conditional=WEB_CRYPTO,
+ JSGenerateToJSObject
+] dictionary CryptoEcKeyAlgorithm : CryptoKeyAlgorithm {
+ // The named curve that the key uses
+ required NamedCurve namedCurve;
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoHmacKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/CryptoHmacKeyAlgorithm.h
new file mode 100644
index 000000000..92aa132ba
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoHmacKeyAlgorithm.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoKeyAlgorithm.h"
+
+namespace WebCore {
+
+struct CryptoHmacKeyAlgorithm : CryptoKeyAlgorithm {
+ // The inner hash function to use.
+ CryptoKeyAlgorithm hash;
+ // The length (in bits) of the key.
+ unsigned length;
+};
+
+}
+
+
diff --git a/src/bun.js/bindings/webcrypto/CryptoHmacKeyAlgorithm.idl b/src/bun.js/bindings/webcrypto/CryptoHmacKeyAlgorithm.idl
new file mode 100644
index 000000000..a836f0d25
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoHmacKeyAlgorithm.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ JSGenerateToJSObject
+] dictionary CryptoHmacKeyAlgorithm : CryptoKeyAlgorithm {
+ // The inner hash function to use.
+ required CryptoKeyAlgorithm hash;
+ // The length (in bits) of the key.
+ required unsigned long length;
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoKey.cpp b/src/bun.js/bindings/webcrypto/CryptoKey.cpp
new file mode 100644
index 000000000..4491a11fb
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKey.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoKey.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRegistry.h"
+#include "WebCoreOpaqueRoot.h"
+#include <wtf/CryptographicallyRandomNumber.h>
+#include <openssl/rand.h>
+
+namespace WebCore {
+
+CryptoKey::CryptoKey(CryptoAlgorithmIdentifier algorithmIdentifier, Type type, bool extractable, CryptoKeyUsageBitmap usages)
+ : m_algorithmIdentifier(algorithmIdentifier)
+ , m_type(type)
+ , m_extractable(extractable)
+ , m_usages(usages)
+{
+}
+
+CryptoKey::~CryptoKey() = default;
+
+auto CryptoKey::usages() const -> Vector<CryptoKeyUsage>
+{
+ // The result is ordered alphabetically.
+ Vector<CryptoKeyUsage> result;
+ if (m_usages & CryptoKeyUsageDecrypt)
+ result.append(CryptoKeyUsage::Decrypt);
+ if (m_usages & CryptoKeyUsageDeriveBits)
+ result.append(CryptoKeyUsage::DeriveBits);
+ if (m_usages & CryptoKeyUsageDeriveKey)
+ result.append(CryptoKeyUsage::DeriveKey);
+ if (m_usages & CryptoKeyUsageEncrypt)
+ result.append(CryptoKeyUsage::Encrypt);
+ if (m_usages & CryptoKeyUsageSign)
+ result.append(CryptoKeyUsage::Sign);
+ if (m_usages & CryptoKeyUsageUnwrapKey)
+ result.append(CryptoKeyUsage::UnwrapKey);
+ if (m_usages & CryptoKeyUsageVerify)
+ result.append(CryptoKeyUsage::Verify);
+ if (m_usages & CryptoKeyUsageWrapKey)
+ result.append(CryptoKeyUsage::WrapKey);
+ return result;
+}
+
+WebCoreOpaqueRoot root(CryptoKey* key)
+{
+ return WebCoreOpaqueRoot { key };
+}
+
+
+
+
+Vector<uint8_t> CryptoKey::randomData(size_t size)
+{
+ Vector<uint8_t> result(size);
+ RAND_bytes(result.data(), result.size());
+ return result;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKey.h b/src/bun.js/bindings/webcrypto/CryptoKey.h
new file mode 100644
index 000000000..f91229173
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKey.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAesKeyAlgorithm.h"
+#include "CryptoAlgorithmIdentifier.h"
+#include "CryptoEcKeyAlgorithm.h"
+#include "CryptoHmacKeyAlgorithm.h"
+#include "CryptoKeyAlgorithm.h"
+#include "CryptoKeyType.h"
+#include "CryptoKeyUsage.h"
+#include "CryptoRsaHashedKeyAlgorithm.h"
+#include "CryptoRsaKeyAlgorithm.h"
+#include <variant>
+#include <wtf/Forward.h>
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/TypeCasts.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class WebCoreOpaqueRoot;
+
+enum class CryptoKeyClass {
+ AES,
+ EC,
+ HMAC,
+ RSA,
+ Raw,
+};
+
+class CryptoKey : public ThreadSafeRefCounted<CryptoKey> {
+public:
+ using Type = CryptoKeyType;
+ using KeyAlgorithm = std::variant<CryptoKeyAlgorithm, CryptoAesKeyAlgorithm, CryptoEcKeyAlgorithm, CryptoHmacKeyAlgorithm, CryptoRsaHashedKeyAlgorithm, CryptoRsaKeyAlgorithm>;
+
+ CryptoKey(CryptoAlgorithmIdentifier, Type, bool extractable, CryptoKeyUsageBitmap);
+ virtual ~CryptoKey();
+
+ Type type() const;
+ bool extractable() const { return m_extractable; }
+ Vector<CryptoKeyUsage> usages() const;
+ virtual KeyAlgorithm algorithm() const = 0;
+
+ virtual CryptoKeyClass keyClass() const = 0;
+
+ CryptoAlgorithmIdentifier algorithmIdentifier() const { return m_algorithmIdentifier; }
+ CryptoKeyUsageBitmap usagesBitmap() const { return m_usages; }
+ void setUsagesBitmap(CryptoKeyUsageBitmap usage) { m_usages = usage; };
+ bool allows(CryptoKeyUsageBitmap usage) const { return usage == (m_usages & usage); }
+
+ static Vector<uint8_t> randomData(size_t);
+
+private:
+ CryptoAlgorithmIdentifier m_algorithmIdentifier;
+ Type m_type;
+ bool m_extractable;
+ CryptoKeyUsageBitmap m_usages;
+};
+
+inline auto CryptoKey::type() const -> Type
+{
+ return m_type;
+}
+
+WebCoreOpaqueRoot root(CryptoKey*);
+
+} // namespace WebCore
+
+#define SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(ToClassName, KeyClass) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToClassName) \
+ static bool isType(const WebCore::CryptoKey& key) { return key.keyClass() == WebCore::KeyClass; } \
+SPECIALIZE_TYPE_TRAITS_END()
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKey.idl b/src/bun.js/bindings/webcrypto/CryptoKey.idl
new file mode 100644
index 000000000..31ad11f72
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKey.idl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+enum KeyType {
+ "public",
+ "private",
+ "secret"
+};
+
+typedef (CryptoKeyAlgorithm or CryptoAesKeyAlgorithm or CryptoEcKeyAlgorithm or CryptoHmacKeyAlgorithm or CryptoRsaHashedKeyAlgorithm or CryptoRsaKeyAlgorithm) KeyAlgorithm;
+
+[
+ Conditional=WEB_CRYPTO,
+ Exposed=(Window,Worker),
+ GenerateIsReachable=Impl,
+ SecureContext,
+ SkipVTableValidation
+] interface CryptoKey {
+ readonly attribute KeyType type;
+ readonly attribute boolean extractable;
+ [CachedAttribute] readonly attribute KeyAlgorithm algorithm;
+ [CachedAttribute] readonly attribute sequence<CryptoKeyUsage> usages;
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyAES.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyAES.cpp
new file mode 100644
index 000000000..17cbf48d9
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyAES.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoKeyAES.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAesKeyAlgorithm.h"
+#include "CryptoAlgorithmAesKeyParams.h"
+#include "CryptoAlgorithmRegistry.h"
+#include "ExceptionOr.h"
+#include "JsonWebKey.h"
+#include <wtf/text/Base64.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static inline bool lengthIsValid(size_t length)
+{
+ return (length == CryptoKeyAES::s_length128) || (length == CryptoKeyAES::s_length192) || (length == CryptoKeyAES::s_length256);
+}
+
+CryptoKeyAES::CryptoKeyAES(CryptoAlgorithmIdentifier algorithm, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsageBitmap usage)
+ : CryptoKey(algorithm, CryptoKeyType::Secret, extractable, usage)
+ , m_key(key)
+{
+ ASSERT(isValidAESAlgorithm(algorithm));
+}
+
+CryptoKeyAES::CryptoKeyAES(CryptoAlgorithmIdentifier algorithm, Vector<uint8_t>&& key, bool extractable, CryptoKeyUsageBitmap usage)
+ : CryptoKey(algorithm, CryptoKeyType::Secret, extractable, usage)
+ , m_key(WTFMove(key))
+{
+ ASSERT(isValidAESAlgorithm(algorithm));
+}
+
+CryptoKeyAES::~CryptoKeyAES() = default;
+
+bool CryptoKeyAES::isValidAESAlgorithm(CryptoAlgorithmIdentifier algorithm)
+{
+ return algorithm == CryptoAlgorithmIdentifier::AES_CTR
+ || algorithm == CryptoAlgorithmIdentifier::AES_CBC
+ || algorithm == CryptoAlgorithmIdentifier::AES_GCM
+ || algorithm == CryptoAlgorithmIdentifier::AES_CFB
+ || algorithm == CryptoAlgorithmIdentifier::AES_KW;
+}
+
+RefPtr<CryptoKeyAES> CryptoKeyAES::generate(CryptoAlgorithmIdentifier algorithm, size_t lengthBits, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ if (!lengthIsValid(lengthBits))
+ return nullptr;
+ return adoptRef(new CryptoKeyAES(algorithm, randomData(lengthBits / 8), extractable, usages));
+}
+
+RefPtr<CryptoKeyAES> CryptoKeyAES::importRaw(CryptoAlgorithmIdentifier algorithm, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ if (!lengthIsValid(keyData.size() * 8))
+ return nullptr;
+ return adoptRef(new CryptoKeyAES(algorithm, WTFMove(keyData), extractable, usages));
+}
+
+RefPtr<CryptoKeyAES> CryptoKeyAES::importJwk(CryptoAlgorithmIdentifier algorithm, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages, CheckAlgCallback&& callback)
+{
+ if (keyData.kty != "oct"_s)
+ return nullptr;
+ if (keyData.k.isNull())
+ return nullptr;
+ auto octetSequence = base64URLDecode(keyData.k);
+ if (!octetSequence)
+ return nullptr;
+ if (!callback(octetSequence->size() * 8, keyData.alg))
+ return nullptr;
+ if (usages && !keyData.use.isNull() && keyData.use != "enc"_s)
+ return nullptr;
+ if (keyData.key_ops && ((keyData.usages & usages) != usages))
+ return nullptr;
+ if (keyData.ext && !keyData.ext.value() && extractable)
+ return nullptr;
+
+ return adoptRef(new CryptoKeyAES(algorithm, WTFMove(*octetSequence), extractable, usages));
+}
+
+JsonWebKey CryptoKeyAES::exportJwk() const
+{
+ JsonWebKey result;
+ result.kty = "oct"_s;
+ result.k = base64URLEncodeToString(m_key);
+ result.key_ops = usages();
+ result.ext = extractable();
+ return result;
+}
+
+ExceptionOr<size_t> CryptoKeyAES::getKeyLength(const CryptoAlgorithmParameters& parameters)
+{
+ auto& aesParameters = downcast<CryptoAlgorithmAesKeyParams>(parameters);
+ if (!lengthIsValid(aesParameters.length))
+ return Exception { OperationError };
+ return aesParameters.length;
+}
+
+auto CryptoKeyAES::algorithm() const -> KeyAlgorithm
+{
+ CryptoAesKeyAlgorithm result;
+ result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
+ result.length = m_key.size() * 8;
+ return result;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyAES.h b/src/bun.js/bindings/webcrypto/CryptoKeyAES.h
new file mode 100644
index 000000000..341ca6bc7
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyAES.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmIdentifier.h"
+#include "CryptoKey.h"
+#include "ExceptionOr.h"
+#include <wtf/Function.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmParameters;
+
+struct JsonWebKey;
+
+class CryptoKeyAES final : public CryptoKey {
+public:
+ static const int s_length128 = 128;
+ static const int s_length192 = 192;
+ static const int s_length256 = 256;
+
+ static Ref<CryptoKeyAES> create(CryptoAlgorithmIdentifier algorithm, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsageBitmap usage)
+ {
+ return adoptRef(*new CryptoKeyAES(algorithm, key, extractable, usage));
+ }
+ virtual ~CryptoKeyAES();
+
+ static bool isValidAESAlgorithm(CryptoAlgorithmIdentifier);
+
+ static RefPtr<CryptoKeyAES> generate(CryptoAlgorithmIdentifier, size_t lengthBits, bool extractable, CryptoKeyUsageBitmap);
+ WEBCORE_EXPORT static RefPtr<CryptoKeyAES> importRaw(CryptoAlgorithmIdentifier, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+ using CheckAlgCallback = Function<bool(size_t, const String&)>;
+ static RefPtr<CryptoKeyAES> importJwk(CryptoAlgorithmIdentifier, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap, CheckAlgCallback&&);
+
+ CryptoKeyClass keyClass() const final { return CryptoKeyClass::AES; }
+
+ const Vector<uint8_t>& key() const { return m_key; }
+ JsonWebKey exportJwk() const;
+
+ static ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&);
+
+private:
+ CryptoKeyAES(CryptoAlgorithmIdentifier, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsageBitmap);
+ CryptoKeyAES(CryptoAlgorithmIdentifier, Vector<uint8_t>&& key, bool extractable, CryptoKeyUsageBitmap);
+
+ KeyAlgorithm algorithm() const final;
+
+ Vector<uint8_t> m_key;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyAES, CryptoKeyClass::AES)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/CryptoKeyAlgorithm.h
new file mode 100644
index 000000000..dcfeec9e7
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyAlgorithm.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+struct CryptoKeyAlgorithm {
+ String name;
+};
+
+}
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyAlgorithm.idl b/src/bun.js/bindings/webcrypto/CryptoKeyAlgorithm.idl
new file mode 100644
index 000000000..a7d314786
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyAlgorithm.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ JSGenerateToJSObject
+] dictionary CryptoKeyAlgorithm {
+ required DOMString name;
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyEC.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyEC.cpp
new file mode 100644
index 000000000..d62a38b53
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyEC.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoKeyEC.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRegistry.h"
+#include "JsonWebKey.h"
+#include <wtf/text/Base64.h>
+
+namespace WebCore {
+
+static const ASCIILiteral P256 { "P-256"_s };
+static const ASCIILiteral P384 { "P-384"_s };
+static const ASCIILiteral P521 { "P-521"_s };
+
+static std::optional<CryptoKeyEC::NamedCurve> toNamedCurve(const String& curve)
+{
+ if (curve == P256)
+ return CryptoKeyEC::NamedCurve::P256;
+ if (curve == P384)
+ return CryptoKeyEC::NamedCurve::P384;
+ if (curve == P521)
+ return CryptoKeyEC::NamedCurve::P521;
+
+ return std::nullopt;
+}
+
+CryptoKeyEC::CryptoKeyEC(CryptoAlgorithmIdentifier identifier, NamedCurve curve, CryptoKeyType type, PlatformECKeyContainer&& platformKey, bool extractable, CryptoKeyUsageBitmap usages)
+ : CryptoKey(identifier, type, extractable, usages)
+ , m_platformKey(WTFMove(platformKey))
+ , m_curve(curve)
+{
+ // Only CryptoKeyEC objects for supported curves should be created.
+ ASSERT(platformSupportedCurve(curve));
+}
+
+ExceptionOr<CryptoKeyPair> CryptoKeyEC::generatePair(CryptoAlgorithmIdentifier identifier, const String& curve, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ auto namedCurve = toNamedCurve(curve);
+ if (!namedCurve || !platformSupportedCurve(*namedCurve))
+ return Exception { NotSupportedError };
+
+ auto result = platformGeneratePair(identifier, *namedCurve, extractable, usages);
+ if (!result)
+ return Exception { OperationError };
+
+ return WTFMove(*result);
+}
+
+RefPtr<CryptoKeyEC> CryptoKeyEC::importRaw(CryptoAlgorithmIdentifier identifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ auto namedCurve = toNamedCurve(curve);
+ if (!namedCurve || !platformSupportedCurve(*namedCurve))
+ return nullptr;
+
+ return platformImportRaw(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
+}
+
+RefPtr<CryptoKeyEC> CryptoKeyEC::importJwk(CryptoAlgorithmIdentifier identifier, const String& curve, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ if (keyData.kty != "EC"_s)
+ return nullptr;
+ if (keyData.key_ops && ((keyData.usages & usages) != usages))
+ return nullptr;
+ if (keyData.ext && !keyData.ext.value() && extractable)
+ return nullptr;
+
+ if (keyData.crv.isNull() || curve != keyData.crv)
+ return nullptr;
+ auto namedCurve = toNamedCurve(keyData.crv);
+ if (!namedCurve || !platformSupportedCurve(*namedCurve))
+ return nullptr;
+
+ if (keyData.x.isNull() || keyData.y.isNull())
+ return nullptr;
+ auto x = base64URLDecode(keyData.x);
+ if (!x)
+ return nullptr;
+ auto y = base64URLDecode(keyData.y);
+ if (!y)
+ return nullptr;
+ if (keyData.d.isNull()) {
+ // import public key
+ return platformImportJWKPublic(identifier, *namedCurve, WTFMove(*x), WTFMove(*y), extractable, usages);
+ }
+
+ auto d = base64URLDecode(keyData.d);
+ if (!d)
+ return nullptr;
+ // import private key
+ return platformImportJWKPrivate(identifier, *namedCurve, WTFMove(*x), WTFMove(*y), WTFMove(*d), extractable, usages);
+}
+
+RefPtr<CryptoKeyEC> CryptoKeyEC::importSpki(CryptoAlgorithmIdentifier identifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ auto namedCurve = toNamedCurve(curve);
+ if (!namedCurve || !platformSupportedCurve(*namedCurve))
+ return nullptr;
+
+ return platformImportSpki(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
+}
+
+RefPtr<CryptoKeyEC> CryptoKeyEC::importPkcs8(CryptoAlgorithmIdentifier identifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ auto namedCurve = toNamedCurve(curve);
+ if (!namedCurve || !platformSupportedCurve(*namedCurve))
+ return nullptr;
+
+ return platformImportPkcs8(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoKeyEC::exportRaw() const
+{
+ if (type() != CryptoKey::Type::Public)
+ return Exception { InvalidAccessError };
+
+ auto&& result = platformExportRaw();
+ if (result.isEmpty())
+ return Exception { OperationError };
+ return WTFMove(result);
+}
+
+ExceptionOr<JsonWebKey> CryptoKeyEC::exportJwk() const
+{
+ JsonWebKey result;
+ result.kty = "EC"_s;
+ switch (m_curve) {
+ case NamedCurve::P256:
+ result.crv = P256;
+ break;
+ case NamedCurve::P384:
+ result.crv = P384;
+ break;
+ case NamedCurve::P521:
+ result.crv = P521;
+ break;
+ }
+ result.key_ops = usages();
+ result.ext = extractable();
+ if (!platformAddFieldElements(result))
+ return Exception { OperationError };
+ return result;
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoKeyEC::exportSpki() const
+{
+ if (type() != CryptoKey::Type::Public)
+ return Exception { InvalidAccessError };
+
+ auto&& result = platformExportSpki();
+ if (result.isEmpty())
+ return Exception { OperationError };
+ return WTFMove(result);
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoKeyEC::exportPkcs8() const
+{
+ if (type() != CryptoKey::Type::Private)
+ return Exception { InvalidAccessError };
+
+ auto&& result = platformExportPkcs8();
+ if (result.isEmpty())
+ return Exception { OperationError };
+ return WTFMove(result);
+}
+
+String CryptoKeyEC::namedCurveString() const
+{
+ switch (m_curve) {
+ case NamedCurve::P256:
+ return String(P256);
+ case NamedCurve::P384:
+ return String(P384);
+ case NamedCurve::P521:
+ return String(P521);
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyString();
+}
+
+bool CryptoKeyEC::isValidECAlgorithm(CryptoAlgorithmIdentifier algorithm)
+{
+ return algorithm == CryptoAlgorithmIdentifier::ECDSA || algorithm == CryptoAlgorithmIdentifier::ECDH;
+}
+
+auto CryptoKeyEC::algorithm() const -> KeyAlgorithm
+{
+ CryptoEcKeyAlgorithm result;
+ result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
+
+ switch (m_curve) {
+ case NamedCurve::P256:
+ result.namedCurve = P256;
+ break;
+ case NamedCurve::P384:
+ result.namedCurve = P384;
+ break;
+ case NamedCurve::P521:
+ result.namedCurve = P521;
+ break;
+ }
+
+ return result;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyEC.h b/src/bun.js/bindings/webcrypto/CryptoKeyEC.h
new file mode 100644
index 000000000..f2cf7383f
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyEC.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoKey.h"
+#include "CryptoKeyPair.h"
+#include "ExceptionOr.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#if 0
+#include "CommonCryptoUtilities.h"
+
+typedef CCECCryptorRef PlatformECKey;
+namespace WebCore {
+struct CCECCryptorRefDeleter {
+ void operator()(CCECCryptorRef key) const { CCECCryptorRelease(key); }
+};
+}
+typedef std::unique_ptr<typename std::remove_pointer<CCECCryptorRef>::type, WebCore::CCECCryptorRefDeleter> PlatformECKeyContainer;
+#endif
+
+#if USE(GCRYPT)
+#include <pal/crypto/gcrypt/Handle.h>
+
+typedef gcry_sexp_t PlatformECKey;
+typedef std::unique_ptr<typename std::remove_pointer<gcry_sexp_t>::type, PAL::GCrypt::HandleDeleter<gcry_sexp_t>> PlatformECKeyContainer;
+#endif
+
+#if USE(OPENSSL)
+#include "OpenSSLCryptoUniquePtr.h"
+typedef EVP_PKEY* PlatformECKey;
+typedef WebCore::EvpPKeyPtr PlatformECKeyContainer;
+#endif
+
+namespace WebCore {
+
+struct JsonWebKey;
+
+class CryptoKeyEC final : public CryptoKey {
+public:
+ enum class NamedCurve {
+ P256,
+ P384,
+ P521,
+ };
+
+ static Ref<CryptoKeyEC> create(CryptoAlgorithmIdentifier identifier, NamedCurve curve, CryptoKeyType type, PlatformECKeyContainer&& platformKey, bool extractable, CryptoKeyUsageBitmap usages)
+ {
+ return adoptRef(*new CryptoKeyEC(identifier, curve, type, WTFMove(platformKey), extractable, usages));
+ }
+ virtual ~CryptoKeyEC() = default;
+
+ WEBCORE_EXPORT static ExceptionOr<CryptoKeyPair> generatePair(CryptoAlgorithmIdentifier, const String& curve, bool extractable, CryptoKeyUsageBitmap);
+ WEBCORE_EXPORT static RefPtr<CryptoKeyEC> importRaw(CryptoAlgorithmIdentifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyEC> importJwk(CryptoAlgorithmIdentifier, const String& curve, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyEC> importSpki(CryptoAlgorithmIdentifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyEC> importPkcs8(CryptoAlgorithmIdentifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+
+ WEBCORE_EXPORT ExceptionOr<Vector<uint8_t>> exportRaw() const;
+ ExceptionOr<JsonWebKey> exportJwk() const;
+ ExceptionOr<Vector<uint8_t>> exportSpki() const;
+ ExceptionOr<Vector<uint8_t>> exportPkcs8() const;
+
+ size_t keySizeInBits() const;
+ size_t keySizeInBytes() const { return std::ceil(keySizeInBits() / 8.); }
+ NamedCurve namedCurve() const { return m_curve; }
+ String namedCurveString() const;
+ PlatformECKey platformKey() const { return m_platformKey.get(); }
+ static bool isValidECAlgorithm(CryptoAlgorithmIdentifier);
+
+private:
+ CryptoKeyEC(CryptoAlgorithmIdentifier, NamedCurve, CryptoKeyType, PlatformECKeyContainer&&, bool extractable, CryptoKeyUsageBitmap);
+
+ CryptoKeyClass keyClass() const final { return CryptoKeyClass::EC; }
+
+ KeyAlgorithm algorithm() const final;
+
+ static bool platformSupportedCurve(NamedCurve);
+ static std::optional<CryptoKeyPair> platformGeneratePair(CryptoAlgorithmIdentifier, NamedCurve, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyEC> platformImportRaw(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyEC> platformImportJWKPublic(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyEC> platformImportJWKPrivate(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, Vector<uint8_t>&& d, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyEC> platformImportSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyEC> platformImportPkcs8(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+ Vector<uint8_t> platformExportRaw() const;
+ bool platformAddFieldElements(JsonWebKey&) const;
+ Vector<uint8_t> platformExportSpki() const;
+ Vector<uint8_t> platformExportPkcs8() const;
+
+ PlatformECKeyContainer m_platformKey;
+ NamedCurve m_curve;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyEC, CryptoKeyClass::EC)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyECOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyECOpenSSL.cpp
new file mode 100644
index 000000000..bb5dc5e62
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyECOpenSSL.cpp
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoKeyEC.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JsonWebKey.h"
+#include "OpenSSLUtilities.h"
+#include <wtf/text/Base64.h>
+
+namespace WebCore {
+
+static int curveIdentifier(CryptoKeyEC::NamedCurve curve)
+{
+ switch (curve) {
+ case CryptoKeyEC::NamedCurve::P256:
+ return NID_X9_62_prime256v1;
+ case CryptoKeyEC::NamedCurve::P384:
+ return NID_secp384r1;
+ case CryptoKeyEC::NamedCurve::P521:
+ return NID_secp521r1;
+ }
+
+ ASSERT_NOT_REACHED();
+ return NID_undef;
+}
+
+static size_t curveSize(CryptoKeyEC::NamedCurve curve)
+{
+ switch (curve) {
+ case CryptoKeyEC::NamedCurve::P256:
+ return 256;
+ case CryptoKeyEC::NamedCurve::P384:
+ return 384;
+ case CryptoKeyEC::NamedCurve::P521:
+ return 521;
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+static ECKeyPtr createECKey(CryptoKeyEC::NamedCurve curve)
+{
+ auto key = ECKeyPtr(EC_KEY_new_by_curve_name(curveIdentifier(curve)));
+ if (key) {
+ // OPENSSL_EC_NAMED_CURVE needs to be set to export the key with the curve name, not with the curve parameters.
+ EC_KEY_set_asn1_flag(key.get(), OPENSSL_EC_NAMED_CURVE);
+ }
+ return key;
+}
+
+// This function verifies that the group represents the named curve.
+static bool verifyCurve(const EC_GROUP* group, CryptoKeyEC::NamedCurve curve)
+{
+ if (!group)
+ return false;
+
+ auto key = createECKey(curve);
+ if (!key)
+ return false;
+
+ return !EC_GROUP_cmp(group, EC_KEY_get0_group(key.get()), nullptr);
+}
+
+size_t CryptoKeyEC::keySizeInBits() const
+{
+ // EVP_PKEY_size() returns the size of DER-encoded key and cannot be used for this function's purpose.
+ // Instead we resolve the key size by CryptoKeyEC::NamedCurve.
+ size_t size = curveSize(m_curve);
+ return size;
+}
+
+bool CryptoKeyEC::platformSupportedCurve(NamedCurve curve)
+{
+ return curve == NamedCurve::P256 || curve == NamedCurve::P384 || curve == NamedCurve::P521;
+}
+
+std::optional<CryptoKeyPair> CryptoKeyEC::platformGeneratePair(CryptoAlgorithmIdentifier identifier, NamedCurve curve, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ // To generate a key pair, we generate a private key and extract the public key from the private key.
+ auto privateECKey = createECKey(curve);
+ if (!privateECKey)
+ return std::nullopt;
+
+ if (EC_KEY_generate_key(privateECKey.get()) <= 0)
+ return std::nullopt;
+
+ auto point = ECPointPtr(EC_POINT_dup(EC_KEY_get0_public_key(privateECKey.get()), EC_KEY_get0_group(privateECKey.get())));
+ if (!point)
+ return std::nullopt;
+
+ auto publicECKey = createECKey(curve);
+ if (!publicECKey)
+ return std::nullopt;
+
+ if (EC_KEY_set_public_key(publicECKey.get(), point.get()) <= 0)
+ return std::nullopt;
+
+ auto privatePKey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_EC_KEY(privatePKey.get(), privateECKey.get()) <= 0)
+ return std::nullopt;
+
+ auto publicPKey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_EC_KEY(publicPKey.get(), publicECKey.get()) <= 0)
+ return std::nullopt;
+
+ auto publicKey = CryptoKeyEC::create(identifier, curve, CryptoKeyType::Public, WTFMove(publicPKey), true, usages);
+ auto privateKey = CryptoKeyEC::create(identifier, curve, CryptoKeyType::Private, WTFMove(privatePKey), extractable, usages);
+ return CryptoKeyPair { WTFMove(publicKey), WTFMove(privateKey) };
+}
+
+RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportRaw(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ auto key = createECKey(curve);
+ if (!key)
+ return nullptr;
+
+ auto group = EC_KEY_get0_group(key.get());
+ auto point = ECPointPtr(EC_POINT_new(group));
+ // Load an EC point from the keyData. This point is used as a public key.
+ if (EC_POINT_oct2point(group, point.get(), keyData.data(), keyData.size(), nullptr) <= 0)
+ return nullptr;
+
+ if (EC_KEY_set_public_key(key.get(), point.get()) <= 0)
+ return nullptr;
+
+ if (EC_KEY_check_key(key.get()) <= 0)
+ return nullptr;
+
+ auto pkey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_EC_KEY(pkey.get(), key.get()) <= 0)
+ return nullptr;
+
+ return create(identifier, curve, CryptoKeyType::Public, WTFMove(pkey), extractable, usages);
+}
+
+RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportJWKPublic(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ auto key = createECKey(curve);
+ if (!key)
+ return nullptr;
+
+ auto group = EC_KEY_get0_group(key.get());
+ auto point = ECPointPtr(EC_POINT_new(group));
+
+ // Currently we only support elliptic curves over GF(p).
+ if (EC_POINT_set_affine_coordinates_GFp(group, point.get(), convertToBigNumber(x).get(), convertToBigNumber(y).get(), nullptr) <= 0)
+ return nullptr;
+
+ if (EC_KEY_set_public_key(key.get(), point.get()) <= 0)
+ return nullptr;
+
+ if (EC_KEY_check_key(key.get()) <= 0)
+ return nullptr;
+
+ auto pkey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_EC_KEY(pkey.get(), key.get()) <= 0)
+ return nullptr;
+
+ return create(identifier, curve, CryptoKeyType::Public, WTFMove(pkey), extractable, usages);
+}
+
+RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportJWKPrivate(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, Vector<uint8_t>&& d, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ auto key = createECKey(curve);
+ if (!key)
+ return nullptr;
+
+ auto group = EC_KEY_get0_group(key.get());
+ auto point = ECPointPtr(EC_POINT_new(group));
+
+ // Currently we only support elliptic curves over GF(p).
+ if (EC_POINT_set_affine_coordinates_GFp(group, point.get(), convertToBigNumber(x).get(), convertToBigNumber(y).get(), nullptr) <= 0)
+ return nullptr;
+
+ if (EC_KEY_set_public_key(key.get(), point.get()) <= 0)
+ return nullptr;
+
+ if (EC_KEY_set_private_key(key.get(), convertToBigNumber(d).get()) <= 0)
+ return nullptr;
+
+ if (EC_KEY_check_key(key.get()) <= 0)
+ return nullptr;
+
+ auto pkey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_EC_KEY(pkey.get(), key.get()) <= 0)
+ return nullptr;
+
+ return create(identifier, curve, CryptoKeyType::Private, WTFMove(pkey), extractable, usages);
+}
+
+static const ASN1_OBJECT* ecPublicKeyIdentifier()
+{
+ static ASN1_OBJECT* oid = OBJ_txt2obj("1.2.840.10045.2.1", 1);
+ return oid;
+}
+
+static const ASN1_OBJECT* ecDHIdentifier()
+{
+ static ASN1_OBJECT* oid = OBJ_txt2obj("1.3.132.1.12", 1);
+ return oid;
+}
+
+static bool supportedAlgorithmIdentifier(CryptoAlgorithmIdentifier identifier, const ASN1_OBJECT* oid)
+{
+ switch (identifier) {
+ case CryptoAlgorithmIdentifier::ECDSA:
+ // ECDSA only supports id-ecPublicKey algorithms for imported keys.
+ if (!OBJ_cmp(oid, ecPublicKeyIdentifier()))
+ return true;
+ return false;
+ case CryptoAlgorithmIdentifier::ECDH:
+ // ECDH supports both id-ecPublicKey and id-ecDH algorithms for imported keys.
+ if (!OBJ_cmp(oid, ecPublicKeyIdentifier()))
+ return true;
+ if (!OBJ_cmp(oid, ecDHIdentifier()))
+ return true;
+ return false;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+}
+
+RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ // In this function we extract the subjectPublicKey after verifying that the algorithm in the SPKI data
+ // match the given identifier and curve. Then construct an EC key with the named curve and set the public key.
+
+ // SubjectPublicKeyInfo ::= SEQUENCE {
+ // algorithm AlgorithmIdentifier,
+ // subjectPublicKey BIT STRING
+ // }
+
+ const uint8_t* ptr = keyData.data();
+ auto subjectPublicKeyInfo = ASN1SequencePtr(d2i_ASN1_SEQUENCE_ANY(nullptr, &ptr, keyData.size()));
+ if (!subjectPublicKeyInfo)
+ return nullptr;
+ if (ptr - keyData.data() != (ptrdiff_t)keyData.size())
+ return nullptr;
+
+ if (sk_ASN1_TYPE_num(subjectPublicKeyInfo.get()) != 2)
+ return nullptr;
+
+ ASN1_TYPE* value = sk_ASN1_TYPE_value(subjectPublicKeyInfo.get(), 0);
+ if (value->type != V_ASN1_SEQUENCE)
+ return nullptr;
+
+ // AlgorithmIdentifier ::= SEQUENCE {
+ // algorithm OBJECT IDENTIFIER,
+ // parameters ANY DEFINED BY algorithm OPTIONAL
+ // }
+
+ ptr = value->value.sequence->data;
+ auto algorithm = ASN1SequencePtr(d2i_ASN1_SEQUENCE_ANY(nullptr, &ptr, value->value.sequence->length));
+ if (!algorithm)
+ return nullptr;
+
+ if (sk_ASN1_TYPE_num(algorithm.get()) != 2)
+ return nullptr;
+
+ value = sk_ASN1_TYPE_value(algorithm.get(), 0);
+ if (value->type != V_ASN1_OBJECT)
+ return nullptr;
+
+ if (!supportedAlgorithmIdentifier(identifier, value->value.object))
+ return nullptr;
+
+ // ECParameters ::= CHOICE {
+ // namedCurve OBJECT IDENTIFIER
+ // -- implicitCurve null
+ // -- specifiedCurve SpecifiedECDomain
+ // }
+ //
+ // Only "namedCurve" is supported.
+ value = sk_ASN1_TYPE_value(algorithm.get(), 1);
+ if (value->type != V_ASN1_OBJECT)
+ return nullptr;
+
+ int curveNID = OBJ_obj2nid(value->value.object);
+ if (curveNID != curveIdentifier(curve))
+ return nullptr;
+
+ // subjectPublicKey must be a BIT STRING.
+ value = sk_ASN1_TYPE_value(subjectPublicKeyInfo.get(), 1);
+ if (value->type != V_ASN1_BIT_STRING)
+ return nullptr;
+
+ ASN1_BIT_STRING* bitString = value->value.bit_string;
+
+ // The SPKI data has been verified at this point. We prepare platform data next.
+ auto key = createECKey(curve);
+ if (!key)
+ return nullptr;
+
+ auto group = EC_KEY_get0_group(key.get());
+ if (!group)
+ return nullptr;
+
+ auto point = ECPointPtr(EC_POINT_new(group));
+ if (!point)
+ return nullptr;
+
+ if (EC_POINT_oct2point(group, point.get(), bitString->data, bitString->length, 0) <= 0)
+ return nullptr;
+
+ if (EC_KEY_set_public_key(key.get(), point.get()) <= 0)
+ return nullptr;
+
+ if (EC_KEY_check_key(key.get()) <= 0)
+ return nullptr;
+
+ EC_KEY_set_asn1_flag(key.get(), OPENSSL_EC_NAMED_CURVE);
+
+ auto pkey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_EC_KEY(pkey.get(), key.get()) <= 0)
+ return nullptr;
+
+ return adoptRef(new CryptoKeyEC(identifier, curve, CryptoKeyType::Public, WTFMove(pkey), extractable, usages));
+}
+
+RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportPkcs8(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ // We need a local pointer variable to pass to d2i (DER to internal) functions().
+ const uint8_t* ptr = keyData.data();
+
+ // We use d2i_PKCS8_PRIV_KEY_INFO() to import a private key.
+ auto p8inf = PKCS8PrivKeyInfoPtr(d2i_PKCS8_PRIV_KEY_INFO(nullptr, &ptr, keyData.size()));
+ if (!p8inf)
+ return nullptr;
+ if (ptr - keyData.data() != (ptrdiff_t)keyData.size())
+ return nullptr;
+
+ auto pkey = EvpPKeyPtr(EVP_PKCS82PKEY(p8inf.get()));
+ if (!pkey || EVP_PKEY_base_id(pkey.get()) != EVP_PKEY_EC)
+ return nullptr;
+
+ auto ecKey = EVP_PKEY_get0_EC_KEY(pkey.get());
+ if (!ecKey)
+ return nullptr;
+
+ if (EC_KEY_check_key(ecKey) <= 0)
+ return nullptr;
+
+ if (!verifyCurve(EC_KEY_get0_group(ecKey), curve))
+ return nullptr;
+
+ EC_KEY_set_asn1_flag(ecKey, OPENSSL_EC_NAMED_CURVE);
+
+ return adoptRef(new CryptoKeyEC(identifier, curve, CryptoKeyType::Private, WTFMove(pkey), extractable, usages));
+}
+
+Vector<uint8_t> CryptoKeyEC::platformExportRaw() const
+{
+ EC_KEY* key = EVP_PKEY_get0_EC_KEY(platformKey());
+ if (!key)
+ return { };
+
+ const EC_POINT* point = EC_KEY_get0_public_key(key);
+ const EC_GROUP* group = EC_KEY_get0_group(key);
+ size_t keyDataSize = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, nullptr);
+ if (!keyDataSize)
+ return { };
+
+ Vector<uint8_t> keyData(keyDataSize);
+ if (EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, keyData.data(), keyData.size(), nullptr) != keyDataSize)
+ return { };
+
+ return keyData;
+}
+
+bool CryptoKeyEC::platformAddFieldElements(JsonWebKey& jwk) const
+{
+ size_t keySizeInBytes = (keySizeInBits() + 7) / 8;
+
+ EC_KEY* key = EVP_PKEY_get0_EC_KEY(platformKey());
+ if (!key)
+ return false;
+
+ const EC_POINT* publicKey = EC_KEY_get0_public_key(key);
+ if (publicKey) {
+ auto ctx = BNCtxPtr(BN_CTX_new());
+ auto x = BIGNUMPtr(BN_new());
+ auto y = BIGNUMPtr(BN_new());
+ if (1 == EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key), publicKey, x.get(), y.get(), ctx.get())) {
+ jwk.x = base64URLEncodeToString(convertToBytesExpand(x.get(), keySizeInBytes));
+ jwk.y = base64URLEncodeToString(convertToBytesExpand(y.get(), keySizeInBytes));
+ }
+ }
+
+ if (type() == Type::Private) {
+ const BIGNUM* privateKey = EC_KEY_get0_private_key(key);
+ if (privateKey)
+ jwk.d = base64URLEncodeToString(convertToBytes(privateKey));
+ }
+ return true;
+}
+
+Vector<uint8_t> CryptoKeyEC::platformExportSpki() const
+{
+ if (type() != CryptoKeyType::Public)
+ return { };
+
+ int len = i2d_PUBKEY(platformKey(), nullptr);
+ if (len < 0)
+ return { };
+
+ Vector<uint8_t> keyData(len);
+ auto ptr = keyData.data();
+ if (i2d_PUBKEY(platformKey(), &ptr) < 0)
+ return { };
+
+ return keyData;
+}
+
+Vector<uint8_t> CryptoKeyEC::platformExportPkcs8() const
+{
+ if (type() != CryptoKeyType::Private)
+ return { };
+
+ auto p8inf = PKCS8PrivKeyInfoPtr(EVP_PKEY2PKCS8(platformKey()));
+ if (!p8inf)
+ return { };
+
+ int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf.get(), nullptr);
+ if (len < 0)
+ return { };
+
+ Vector<uint8_t> keyData(len);
+ auto ptr = keyData.data();
+ if (i2d_PKCS8_PRIV_KEY_INFO(p8inf.get(), &ptr) < 0)
+ return { };
+
+ return keyData;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyFormat.h b/src/bun.js/bindings/webcrypto/CryptoKeyFormat.h
new file mode 100644
index 000000000..2bf7faeff
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyFormat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+enum class CryptoKeyFormat {
+ Raw,
+ Spki,
+ Pkcs8,
+ Jwk
+};
+
+}
+
+#endif
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.cpp
new file mode 100644
index 000000000..aafb3b2fe
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoKeyHMAC.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmHmacKeyParams.h"
+#include "CryptoAlgorithmRegistry.h"
+#include "ExceptionOr.h"
+#include "JsonWebKey.h"
+#include <wtf/text/Base64.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static size_t getKeyLengthFromHash(CryptoAlgorithmIdentifier hash)
+{
+ switch (hash) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ case CryptoAlgorithmIdentifier::SHA_224:
+ case CryptoAlgorithmIdentifier::SHA_256:
+ return 512;
+ case CryptoAlgorithmIdentifier::SHA_384:
+ case CryptoAlgorithmIdentifier::SHA_512:
+ return 1024;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
+
+CryptoKeyHMAC::CryptoKeyHMAC(const Vector<uint8_t>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usage)
+ : CryptoKey(CryptoAlgorithmIdentifier::HMAC, CryptoKeyType::Secret, extractable, usage)
+ , m_hash(hash)
+ , m_key(key)
+{
+}
+
+CryptoKeyHMAC::CryptoKeyHMAC(Vector<uint8_t>&& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usage)
+ : CryptoKey(CryptoAlgorithmIdentifier::HMAC, CryptoKeyType::Secret, extractable, usage)
+ , m_hash(hash)
+ , m_key(WTFMove(key))
+{
+}
+
+CryptoKeyHMAC::~CryptoKeyHMAC() = default;
+
+RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::generate(size_t lengthBits, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ if (!lengthBits) {
+ lengthBits = getKeyLengthFromHash(hash);
+ if (!lengthBits)
+ return nullptr;
+ }
+ // CommonHMAC only supports key length that is a multiple of 8. Therefore, here we are a little bit different
+ // from the spec as of 11 December 2014: https://www.w3.org/TR/WebCryptoAPI/#hmac-operations
+ if (lengthBits % 8)
+ return nullptr;
+
+ return adoptRef(new CryptoKeyHMAC(randomData(lengthBits / 8), hash, extractable, usages));
+}
+
+RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::importRaw(size_t lengthBits, CryptoAlgorithmIdentifier hash, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ size_t length = keyData.size() * 8;
+ if (!length)
+ return nullptr;
+ // CommonHMAC only supports key length that is a multiple of 8. Therefore, here we are a little bit different
+ // from the spec as of 11 December 2014: https://www.w3.org/TR/WebCryptoAPI/#hmac-operations
+ if (lengthBits && lengthBits != length)
+ return nullptr;
+
+ return adoptRef(new CryptoKeyHMAC(WTFMove(keyData), hash, extractable, usages));
+}
+
+RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::importJwk(size_t lengthBits, CryptoAlgorithmIdentifier hash, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages, CheckAlgCallback&& callback)
+{
+ if (keyData.kty != "oct"_s)
+ return nullptr;
+ if (keyData.k.isNull())
+ return nullptr;
+ auto octetSequence = base64URLDecode(keyData.k);
+ if (!octetSequence)
+ return nullptr;
+ if (!callback(hash, keyData.alg))
+ return nullptr;
+ if (usages && !keyData.use.isNull() && keyData.use != "sig"_s)
+ return nullptr;
+ if (keyData.key_ops && ((keyData.usages & usages) != usages))
+ return nullptr;
+ if (keyData.ext && !keyData.ext.value() && extractable)
+ return nullptr;
+
+ return CryptoKeyHMAC::importRaw(lengthBits, hash, WTFMove(*octetSequence), extractable, usages);
+}
+
+JsonWebKey CryptoKeyHMAC::exportJwk() const
+{
+ JsonWebKey result;
+ result.kty = "oct"_s;
+ result.k = base64URLEncodeToString(m_key);
+ result.key_ops = usages();
+ result.ext = extractable();
+ return result;
+}
+
+ExceptionOr<size_t> CryptoKeyHMAC::getKeyLength(const CryptoAlgorithmParameters& parameters)
+{
+ auto& aesParameters = downcast<CryptoAlgorithmHmacKeyParams>(parameters);
+
+ size_t result = aesParameters.length ? *(aesParameters.length) : getKeyLengthFromHash(aesParameters.hashIdentifier);
+ if (result)
+ return result;
+
+ return Exception { TypeError };
+}
+
+auto CryptoKeyHMAC::algorithm() const -> KeyAlgorithm
+{
+ CryptoHmacKeyAlgorithm result;
+ result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
+ result.hash.name = CryptoAlgorithmRegistry::singleton().name(m_hash);
+ result.length = m_key.size() * 8;
+ return result;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.h b/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.h
new file mode 100644
index 000000000..0c7ba38cb
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyHMAC.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKey.h"
+#include "ExceptionOr.h"
+#include <wtf/Function.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class CryptoAlgorithmParameters;
+struct JsonWebKey;
+
+class CryptoKeyHMAC final : public CryptoKey {
+public:
+ static Ref<CryptoKeyHMAC> create(const Vector<uint8_t>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usage)
+ {
+ return adoptRef(*new CryptoKeyHMAC(key, hash, extractable, usage));
+ }
+ virtual ~CryptoKeyHMAC();
+
+ static RefPtr<CryptoKeyHMAC> generate(size_t lengthBits, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyHMAC> importRaw(size_t lengthBits, CryptoAlgorithmIdentifier hash, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
+ using CheckAlgCallback = Function<bool(CryptoAlgorithmIdentifier, const String&)>;
+ static RefPtr<CryptoKeyHMAC> importJwk(size_t lengthBits, CryptoAlgorithmIdentifier hash, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap, CheckAlgCallback&&);
+
+ CryptoKeyClass keyClass() const final { return CryptoKeyClass::HMAC; }
+
+ const Vector<uint8_t>& key() const { return m_key; }
+ JsonWebKey exportJwk() const;
+
+ CryptoAlgorithmIdentifier hashAlgorithmIdentifier() const { return m_hash; }
+
+ static ExceptionOr<size_t> getKeyLength(const CryptoAlgorithmParameters&);
+
+private:
+ CryptoKeyHMAC(const Vector<uint8_t>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap);
+ CryptoKeyHMAC(Vector<uint8_t>&& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap);
+
+ KeyAlgorithm algorithm() const final;
+
+ CryptoAlgorithmIdentifier m_hash;
+ Vector<uint8_t> m_key;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyHMAC, CryptoKeyClass::HMAC)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyPair.h b/src/bun.js/bindings/webcrypto/CryptoKeyPair.h
new file mode 100644
index 000000000..29630ca0c
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyPair.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/RefPtr.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKey;
+
+struct CryptoKeyPair {
+ RefPtr<CryptoKey> publicKey;
+ RefPtr<CryptoKey> privateKey;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyPair.idl b/src/bun.js/bindings/webcrypto/CryptoKeyPair.idl
new file mode 100644
index 000000000..bf3e48839
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyPair.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ JSGenerateToJSObject
+] dictionary CryptoKeyPair {
+ CryptoKey publicKey;
+ CryptoKey privateKey;
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyRSA.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyRSA.cpp
new file mode 100644
index 000000000..273218721
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyRSA.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoKeyRSA.h"
+
+#include "CryptoKeyRSAComponents.h"
+#include "JsonWebKey.h"
+#include <wtf/text/Base64.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+RefPtr<CryptoKeyRSA> CryptoKeyRSA::importJwk(CryptoAlgorithmIdentifier algorithm, std::optional<CryptoAlgorithmIdentifier> hash, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ if (keyData.kty != "RSA"_s)
+ return nullptr;
+ if (keyData.key_ops && ((keyData.usages & usages) != usages))
+ return nullptr;
+ if (keyData.ext && !keyData.ext.value() && extractable)
+ return nullptr;
+
+ if (keyData.n.isNull() || keyData.e.isNull())
+ return nullptr;
+ auto modulus = base64URLDecode(keyData.n);
+ if (!modulus)
+ return nullptr;
+ // Per RFC 7518 Section 6.3.1.1: https://tools.ietf.org/html/rfc7518#section-6.3.1.1
+ if (!modulus->isEmpty() && !modulus->at(0))
+ modulus->remove(0);
+ auto exponent = base64URLDecode(keyData.e);
+ if (!exponent)
+ return nullptr;
+ if (keyData.d.isNull()) {
+ // import public key
+ auto publicKeyComponents = CryptoKeyRSAComponents::createPublic(WTFMove(*modulus), WTFMove(*exponent));
+ // Notice: CryptoAlgorithmIdentifier::SHA_1 is just a placeholder. It should not have any effect if hash is std::nullopt.
+ return CryptoKeyRSA::create(algorithm, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, *publicKeyComponents, extractable, usages);
+ }
+
+ // import private key
+ auto privateExponent = base64URLDecode(keyData.d);
+ if (!privateExponent)
+ return nullptr;
+ if (keyData.p.isNull() && keyData.q.isNull() && keyData.dp.isNull() && keyData.dp.isNull() && keyData.qi.isNull()) {
+ auto privateKeyComponents = CryptoKeyRSAComponents::createPrivate(WTFMove(*modulus), WTFMove(*exponent), WTFMove(*privateExponent));
+ // Notice: CryptoAlgorithmIdentifier::SHA_1 is just a placeholder. It should not have any effect if hash is std::nullopt.
+ return CryptoKeyRSA::create(algorithm, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, *privateKeyComponents, extractable, usages);
+ }
+
+ if (keyData.p.isNull() || keyData.q.isNull() || keyData.dp.isNull() || keyData.dq.isNull() || keyData.qi.isNull())
+ return nullptr;
+
+ auto firstPrimeFactor = base64URLDecode(keyData.p);
+ if (!firstPrimeFactor)
+ return nullptr;
+ auto firstFactorCRTExponent = base64URLDecode(keyData.dp);
+ if (!firstFactorCRTExponent)
+ return nullptr;
+ auto secondPrimeFactor = base64URLDecode(keyData.q);
+ if (!secondPrimeFactor)
+ return nullptr;
+ auto secondFactorCRTExponent = base64URLDecode(keyData.dq);
+ if (!secondFactorCRTExponent)
+ return nullptr;
+ auto secondFactorCRTCoefficient = base64URLDecode(keyData.qi);
+ if (!secondFactorCRTCoefficient)
+ return nullptr;
+
+ CryptoKeyRSAComponents::PrimeInfo firstPrimeInfo;
+ firstPrimeInfo.primeFactor = WTFMove(*firstPrimeFactor);
+ firstPrimeInfo.factorCRTExponent = WTFMove(*firstFactorCRTExponent);
+
+ CryptoKeyRSAComponents::PrimeInfo secondPrimeInfo;
+ secondPrimeInfo.primeFactor = WTFMove(*secondPrimeFactor);
+ secondPrimeInfo.factorCRTExponent = WTFMove(*secondFactorCRTExponent);
+ secondPrimeInfo.factorCRTCoefficient = WTFMove(*secondFactorCRTCoefficient);
+
+ if (!keyData.oth) {
+ auto privateKeyComponents = CryptoKeyRSAComponents::createPrivateWithAdditionalData(WTFMove(*modulus), WTFMove(*exponent), WTFMove(*privateExponent), WTFMove(firstPrimeInfo), WTFMove(secondPrimeInfo), { });
+ // Notice: CryptoAlgorithmIdentifier::SHA_1 is just a placeholder. It should not have any effect if hash is std::nullopt.
+ return CryptoKeyRSA::create(algorithm, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, *privateKeyComponents, extractable, usages);
+ }
+
+ Vector<CryptoKeyRSAComponents::PrimeInfo> otherPrimeInfos;
+ for (const auto& value : keyData.oth.value()) {
+ auto primeFactor = base64URLDecode(value.r);
+ if (!primeFactor)
+ return nullptr;
+ auto factorCRTExponent = base64URLDecode(value.d);
+ if (!factorCRTExponent)
+ return nullptr;
+ auto factorCRTCoefficient = base64URLDecode(value.t);
+ if (!factorCRTCoefficient)
+ return nullptr;
+
+ CryptoKeyRSAComponents::PrimeInfo info;
+ info.primeFactor = WTFMove(*primeFactor);
+ info.factorCRTExponent = WTFMove(*factorCRTExponent);
+ info.factorCRTCoefficient = WTFMove(*factorCRTCoefficient);
+
+ otherPrimeInfos.append(WTFMove(info));
+ }
+
+ auto privateKeyComponents = CryptoKeyRSAComponents::createPrivateWithAdditionalData(WTFMove(*modulus), WTFMove(*exponent), WTFMove(*privateExponent), WTFMove(firstPrimeInfo), WTFMove(secondPrimeInfo), WTFMove(otherPrimeInfos));
+ // Notice: CryptoAlgorithmIdentifier::SHA_1 is just a placeholder. It should not have any effect if hash is std::nullopt.
+ return CryptoKeyRSA::create(algorithm, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, *privateKeyComponents, extractable, usages);
+}
+
+JsonWebKey CryptoKeyRSA::exportJwk() const
+{
+ JsonWebKey result;
+ result.kty = "RSA"_s;
+ result.key_ops = usages();
+ result.ext = extractable();
+
+ auto rsaComponents = exportData();
+
+ if (!rsaComponents)
+ return result;
+
+ // public key
+ result.n = base64URLEncodeToString(rsaComponents->modulus());
+ result.e = base64URLEncodeToString(rsaComponents->exponent());
+ if (rsaComponents->type() == CryptoKeyRSAComponents::Type::Public)
+ return result;
+
+ // private key
+ result.d = base64URLEncodeToString(rsaComponents->privateExponent());
+ if (!rsaComponents->hasAdditionalPrivateKeyParameters())
+ return result;
+
+ result.p = base64URLEncodeToString(rsaComponents->firstPrimeInfo().primeFactor);
+ result.q = base64URLEncodeToString(rsaComponents->secondPrimeInfo().primeFactor);
+ result.dp = base64URLEncodeToString(rsaComponents->firstPrimeInfo().factorCRTExponent);
+ result.dq = base64URLEncodeToString(rsaComponents->secondPrimeInfo().factorCRTExponent);
+ result.qi = base64URLEncodeToString(rsaComponents->secondPrimeInfo().factorCRTCoefficient);
+ if (rsaComponents->otherPrimeInfos().isEmpty())
+ return result;
+
+ Vector<RsaOtherPrimesInfo> oth;
+ for (const auto& info : rsaComponents->otherPrimeInfos()) {
+ RsaOtherPrimesInfo otherInfo;
+ otherInfo.r = base64URLEncodeToString(info.primeFactor);
+ otherInfo.d = base64URLEncodeToString(info.factorCRTExponent);
+ otherInfo.t = base64URLEncodeToString(info.factorCRTCoefficient);
+ oth.append(WTFMove(otherInfo));
+ }
+ result.oth = WTFMove(oth);
+ return result;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyRSA.h b/src/bun.js/bindings/webcrypto/CryptoKeyRSA.h
new file mode 100644
index 000000000..70f9cf648
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyRSA.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoKey.h"
+#include "ExceptionOr.h"
+#include <wtf/Function.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+#if 0
+#include "CommonCryptoUtilities.h"
+
+typedef CCRSACryptorRef PlatformRSAKey;
+namespace WebCore {
+struct CCRSACryptorRefDeleter {
+ void operator()(CCRSACryptorRef key) const { CCRSACryptorRelease(key); }
+};
+}
+typedef std::unique_ptr<typename std::remove_pointer<CCRSACryptorRef>::type, WebCore::CCRSACryptorRefDeleter> PlatformRSAKeyContainer;
+#endif
+
+#if USE(GCRYPT)
+#include <pal/crypto/gcrypt/Handle.h>
+
+typedef gcry_sexp_t PlatformRSAKey;
+typedef std::unique_ptr<typename std::remove_pointer<gcry_sexp_t>::type, PAL::GCrypt::HandleDeleter<gcry_sexp_t>> PlatformRSAKeyContainer;
+#endif
+
+#if USE(OPENSSL)
+#include "OpenSSLCryptoUniquePtr.h"
+typedef EVP_PKEY* PlatformRSAKey;
+typedef WebCore::EvpPKeyPtr PlatformRSAKeyContainer;
+#endif
+
+namespace WebCore {
+
+class CryptoKeyRSAComponents;
+class PromiseWrapper;
+class ScriptExecutionContext;
+
+struct CryptoKeyPair;
+struct JsonWebKey;
+
+class CryptoKeyRSA final : public CryptoKey {
+public:
+ static Ref<CryptoKeyRSA> create(CryptoAlgorithmIdentifier identifier, CryptoAlgorithmIdentifier hash, bool hasHash, CryptoKeyType type, PlatformRSAKeyContainer&& platformKey, bool extractable, CryptoKeyUsageBitmap usage)
+ {
+ return adoptRef(*new CryptoKeyRSA(identifier, hash, hasHash, type, WTFMove(platformKey), extractable, usage));
+ }
+ static RefPtr<CryptoKeyRSA> create(CryptoAlgorithmIdentifier, CryptoAlgorithmIdentifier hash, bool hasHash, const CryptoKeyRSAComponents&, bool extractable, CryptoKeyUsageBitmap);
+ virtual ~CryptoKeyRSA() = default;
+
+ bool isRestrictedToHash(CryptoAlgorithmIdentifier&) const;
+
+ size_t keySizeInBits() const;
+
+ using KeyPairCallback = Function<void(CryptoKeyPair&&)>;
+ using VoidCallback = Function<void()>;
+ static void generatePair(CryptoAlgorithmIdentifier, CryptoAlgorithmIdentifier hash, bool hasHash, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsageBitmap, KeyPairCallback&&, VoidCallback&& failureCallback, ScriptExecutionContext*);
+ static RefPtr<CryptoKeyRSA> importJwk(CryptoAlgorithmIdentifier, std::optional<CryptoAlgorithmIdentifier> hash, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyRSA> importSpki(CryptoAlgorithmIdentifier, std::optional<CryptoAlgorithmIdentifier> hash, Vector<uint8_t>&&, bool extractable, CryptoKeyUsageBitmap);
+ static RefPtr<CryptoKeyRSA> importPkcs8(CryptoAlgorithmIdentifier, std::optional<CryptoAlgorithmIdentifier> hash, Vector<uint8_t>&&, bool extractable, CryptoKeyUsageBitmap);
+
+ PlatformRSAKey platformKey() const { return m_platformKey.get(); }
+ JsonWebKey exportJwk() const;
+ ExceptionOr<Vector<uint8_t>> exportSpki() const;
+ ExceptionOr<Vector<uint8_t>> exportPkcs8() const;
+
+ std::unique_ptr<CryptoKeyRSAComponents> exportData() const;
+
+ CryptoAlgorithmIdentifier hashAlgorithmIdentifier() const { return m_hash; }
+
+private:
+ CryptoKeyRSA(CryptoAlgorithmIdentifier, CryptoAlgorithmIdentifier hash, bool hasHash, CryptoKeyType, PlatformRSAKeyContainer&&, bool extractable, CryptoKeyUsageBitmap);
+
+ CryptoKeyClass keyClass() const final { return CryptoKeyClass::RSA; }
+
+ KeyAlgorithm algorithm() const final;
+
+ PlatformRSAKeyContainer m_platformKey;
+
+ bool m_restrictedToSpecificHash;
+ CryptoAlgorithmIdentifier m_hash;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyRSA, CryptoKeyClass::RSA)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyRSAComponents.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyRSAComponents.cpp
new file mode 100644
index 000000000..f9b6052cd
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyRSAComponents.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoKeyRSAComponents.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+CryptoKeyRSAComponents::CryptoKeyRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent)
+ : m_type(Type::Public)
+ , m_modulus(modulus)
+ , m_exponent(exponent)
+{
+}
+
+CryptoKeyRSAComponents::CryptoKeyRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent)
+ : m_type(Type::Public)
+ , m_modulus(WTFMove(modulus))
+ , m_exponent(WTFMove(exponent))
+{
+}
+
+CryptoKeyRSAComponents::CryptoKeyRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent)
+ : m_type(Type::Private)
+ , m_modulus(modulus)
+ , m_exponent(exponent)
+ , m_privateExponent(privateExponent)
+ , m_hasAdditionalPrivateKeyParameters(false)
+{
+}
+
+CryptoKeyRSAComponents::CryptoKeyRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent)
+ : m_type(Type::Private)
+ , m_modulus(WTFMove(modulus))
+ , m_exponent(WTFMove(exponent))
+ , m_privateExponent(WTFMove(privateExponent))
+ , m_hasAdditionalPrivateKeyParameters(false)
+{
+}
+
+CryptoKeyRSAComponents::CryptoKeyRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent, const PrimeInfo& firstPrimeInfo, const PrimeInfo& secondPrimeInfo, const Vector<PrimeInfo>& otherPrimeInfos)
+ : m_type(Type::Private)
+ , m_modulus(modulus)
+ , m_exponent(exponent)
+ , m_privateExponent(privateExponent)
+ , m_hasAdditionalPrivateKeyParameters(true)
+ , m_firstPrimeInfo(firstPrimeInfo)
+ , m_secondPrimeInfo(secondPrimeInfo)
+ , m_otherPrimeInfos(otherPrimeInfos)
+{
+}
+
+CryptoKeyRSAComponents::CryptoKeyRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent, PrimeInfo&& firstPrimeInfo, PrimeInfo&& secondPrimeInfo, Vector<PrimeInfo>&& otherPrimeInfos)
+ : m_type(Type::Private)
+ , m_modulus(WTFMove(modulus))
+ , m_exponent(WTFMove(exponent))
+ , m_privateExponent(WTFMove(privateExponent))
+ , m_hasAdditionalPrivateKeyParameters(true)
+ , m_firstPrimeInfo(WTFMove(firstPrimeInfo))
+ , m_secondPrimeInfo(WTFMove(secondPrimeInfo))
+ , m_otherPrimeInfos(WTFMove(otherPrimeInfos))
+{
+}
+
+CryptoKeyRSAComponents::~CryptoKeyRSAComponents() = default;
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyRSAComponents.h b/src/bun.js/bindings/webcrypto/CryptoKeyRSAComponents.h
new file mode 100644
index 000000000..26ed55c4e
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyRSAComponents.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKeyRSAComponents {
+public:
+ enum class Type {
+ Public,
+ Private
+ };
+
+ struct PrimeInfo {
+ Vector<uint8_t> primeFactor;
+ Vector<uint8_t> factorCRTExponent;
+ Vector<uint8_t> factorCRTCoefficient;
+ };
+
+ static std::unique_ptr<CryptoKeyRSAComponents> createPublic(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent)
+ {
+ return std::unique_ptr<CryptoKeyRSAComponents>(new CryptoKeyRSAComponents(modulus, exponent));
+ }
+ static std::unique_ptr<CryptoKeyRSAComponents> createPublic(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent)
+ {
+ return std::unique_ptr<CryptoKeyRSAComponents>(new CryptoKeyRSAComponents(WTFMove(modulus), WTFMove(exponent)));
+ }
+
+ static std::unique_ptr<CryptoKeyRSAComponents> createPrivate(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent)
+ {
+ return std::unique_ptr<CryptoKeyRSAComponents>(new CryptoKeyRSAComponents(modulus, exponent, privateExponent));
+ }
+ static std::unique_ptr<CryptoKeyRSAComponents> createPrivate(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent)
+ {
+ return std::unique_ptr<CryptoKeyRSAComponents>(new CryptoKeyRSAComponents(WTFMove(modulus), WTFMove(exponent), WTFMove(privateExponent)));
+ }
+
+ static std::unique_ptr<CryptoKeyRSAComponents> createPrivateWithAdditionalData(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent, const PrimeInfo& firstPrimeInfo, const PrimeInfo& secondPrimeInfo, const Vector<PrimeInfo>& otherPrimeInfos)
+ {
+ return std::unique_ptr<CryptoKeyRSAComponents>(new CryptoKeyRSAComponents(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos));
+ }
+ static std::unique_ptr<CryptoKeyRSAComponents> createPrivateWithAdditionalData(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent, PrimeInfo&& firstPrimeInfo, PrimeInfo&& secondPrimeInfo, Vector<PrimeInfo>&& otherPrimeInfos)
+ {
+ return std::unique_ptr<CryptoKeyRSAComponents>(new CryptoKeyRSAComponents(WTFMove(modulus), WTFMove(exponent), WTFMove(privateExponent), WTFMove(firstPrimeInfo), WTFMove(secondPrimeInfo), WTFMove(otherPrimeInfos)));
+ }
+
+ virtual ~CryptoKeyRSAComponents();
+
+ Type type() const { return m_type; }
+
+ // Private and public keys.
+ const Vector<uint8_t>& modulus() const { return m_modulus; }
+ const Vector<uint8_t>& exponent() const { return m_exponent; }
+
+ // Only private keys.
+ const Vector<uint8_t>& privateExponent() const { return m_privateExponent; }
+ bool hasAdditionalPrivateKeyParameters() const { return m_hasAdditionalPrivateKeyParameters; }
+ const PrimeInfo& firstPrimeInfo() const { return m_firstPrimeInfo; }
+ const PrimeInfo& secondPrimeInfo() const { return m_secondPrimeInfo; }
+ const Vector<PrimeInfo>& otherPrimeInfos() const { return m_otherPrimeInfos; }
+
+private:
+ CryptoKeyRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent);
+ CryptoKeyRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent);
+
+ CryptoKeyRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent);
+ CryptoKeyRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent);
+
+ CryptoKeyRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent, const PrimeInfo& firstPrimeInfo, const PrimeInfo& secondPrimeInfo, const Vector<PrimeInfo>& otherPrimeInfos);
+ CryptoKeyRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent, PrimeInfo&& firstPrimeInfo, PrimeInfo&& secondPrimeInfo, Vector<PrimeInfo>&& otherPrimeInfos);
+
+ Type m_type;
+
+ // Private and public keys.
+ Vector<uint8_t> m_modulus;
+ Vector<uint8_t> m_exponent;
+
+ // Only private keys.
+ Vector<uint8_t> m_privateExponent;
+ bool m_hasAdditionalPrivateKeyParameters;
+ PrimeInfo m_firstPrimeInfo;
+ PrimeInfo m_secondPrimeInfo;
+ Vector<PrimeInfo> m_otherPrimeInfos; // When three or more primes have been used, the number of array elements is be the number of primes used minus two.
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyRSAOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyRSAOpenSSL.cpp
new file mode 100644
index 000000000..ef4794e36
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyRSAOpenSSL.cpp
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2021 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoKeyRSA.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRegistry.h"
+#include "CryptoKeyPair.h"
+#include "CryptoKeyRSAComponents.h"
+#include "OpenSSLUtilities.h"
+#include <JavaScriptCore/TypedArrayInlines.h>
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+
+namespace WebCore {
+
+static size_t getRSAModulusLength(RSA* rsa)
+{
+ if (!rsa)
+ return 0;
+ return RSA_size(rsa) * 8;
+}
+
+RefPtr<CryptoKeyRSA> CryptoKeyRSA::create(CryptoAlgorithmIdentifier identifier, CryptoAlgorithmIdentifier hash, bool hasHash, const CryptoKeyRSAComponents& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ CryptoKeyType keyType;
+ switch (keyData.type()) {
+ case CryptoKeyRSAComponents::Type::Public:
+ keyType = CryptoKeyType::Public;
+ break;
+ case CryptoKeyRSAComponents::Type::Private:
+ keyType = CryptoKeyType::Private;
+ break;
+ default:
+ return nullptr;
+ }
+
+ // When creating a private key, we require the p and q prime information.
+ if (keyType == CryptoKeyType::Private && !keyData.hasAdditionalPrivateKeyParameters())
+ return nullptr;
+
+ // But we don't currently support creating keys with any additional prime information.
+ if (!keyData.otherPrimeInfos().isEmpty())
+ return nullptr;
+
+ // For both public and private keys, we need the public modulus and exponent.
+ if (keyData.modulus().isEmpty() || keyData.exponent().isEmpty())
+ return nullptr;
+
+ // For private keys, we require the private exponent, as well as p and q prime information.
+ if (keyType == CryptoKeyType::Private) {
+ if (keyData.privateExponent().isEmpty() || keyData.firstPrimeInfo().primeFactor.isEmpty() || keyData.secondPrimeInfo().primeFactor.isEmpty())
+ return nullptr;
+ }
+
+ auto rsa = RSAPtr(RSA_new());
+ if (!rsa)
+ return nullptr;
+
+ auto n = convertToBigNumber(keyData.modulus());
+ auto e = convertToBigNumber(keyData.exponent());
+ if (!n || !e)
+ return nullptr;
+
+ // Calling with d null is fine as long as n and e are not null
+ if (!RSA_set0_key(rsa.get(), n.get(), e.get(), nullptr))
+ return nullptr;
+
+ // Ownership transferred to OpenSSL
+ n.release();
+ e.release();
+
+ if (keyType == CryptoKeyType::Private) {
+ auto d = convertToBigNumber(keyData.privateExponent());
+ if (!d)
+ return nullptr;
+
+ // Calling with n and e null is fine as long as they were set prior
+ if (!RSA_set0_key(rsa.get(), nullptr, nullptr, d.get()))
+ return nullptr;
+
+ // Ownership transferred to OpenSSL
+ d.release();
+
+ auto p = convertToBigNumber(keyData.firstPrimeInfo().primeFactor);
+ auto q = convertToBigNumber(keyData.secondPrimeInfo().primeFactor);
+ if (!p || !q)
+ return nullptr;
+
+ if (!RSA_set0_factors(rsa.get(), p.get(), q.get()))
+ return nullptr;
+
+ // Ownership transferred to OpenSSL
+ p.release();
+ q.release();
+
+ // We set dmp1, dmpq1, and iqmp member of the RSA struct if the keyData has corresponding data.
+
+ // dmp1 -- d mod (p - 1)
+ auto dmp1 = (!keyData.firstPrimeInfo().factorCRTExponent.isEmpty()) ? convertToBigNumber(keyData.firstPrimeInfo().factorCRTExponent) : nullptr;
+ // dmq1 -- d mod (q - 1)
+ auto dmq1 = (!keyData.secondPrimeInfo().factorCRTExponent.isEmpty()) ? convertToBigNumber(keyData.secondPrimeInfo().factorCRTExponent) : nullptr;
+ // iqmp -- q^(-1) mod p
+ auto iqmp = (!keyData.secondPrimeInfo().factorCRTCoefficient.isEmpty()) ? convertToBigNumber(keyData.secondPrimeInfo().factorCRTCoefficient) : nullptr;
+
+ if (!RSA_set0_crt_params(rsa.get(), dmp1.get(), dmq1.get(), iqmp.get()))
+ return nullptr;
+
+ // Ownership transferred to OpenSSL
+ dmp1.release();
+ dmq1.release();
+ iqmp.release();
+ }
+
+ auto pkey = EvpPKeyPtr(EVP_PKEY_new());
+ if (!pkey)
+ return nullptr;
+
+ if (EVP_PKEY_set1_RSA(pkey.get(), rsa.get()) != 1)
+ return nullptr;
+
+ return adoptRef(new CryptoKeyRSA(identifier, hash, hasHash, keyType, WTFMove(pkey), extractable, usages));
+}
+
+CryptoKeyRSA::CryptoKeyRSA(CryptoAlgorithmIdentifier identifier, CryptoAlgorithmIdentifier hash, bool hasHash, CryptoKeyType type, PlatformRSAKeyContainer&& platformKey, bool extractable, CryptoKeyUsageBitmap usages)
+ : CryptoKey(identifier, type, extractable, usages)
+ , m_platformKey(WTFMove(platformKey))
+ , m_restrictedToSpecificHash(hasHash)
+ , m_hash(hash)
+{
+}
+
+bool CryptoKeyRSA::isRestrictedToHash(CryptoAlgorithmIdentifier& identifier) const
+{
+ if (!m_restrictedToSpecificHash)
+ return false;
+
+ identifier = m_hash;
+ return true;
+}
+
+size_t CryptoKeyRSA::keySizeInBits() const
+{
+ RSA* rsa = EVP_PKEY_get0_RSA(m_platformKey.get());
+ if (!rsa)
+ return 0;
+
+ return getRSAModulusLength(rsa);
+}
+
+// Convert the exponent vector to a 32-bit value, if possible.
+static std::optional<uint32_t> exponentVectorToUInt32(const Vector<uint8_t>& exponent)
+{
+ if (exponent.size() > 4) {
+ if (std::any_of(exponent.begin(), exponent.end() - 4, [](uint8_t element) { return !!element; }))
+ return std::nullopt;
+ }
+
+ uint32_t result = 0;
+ for (size_t size = exponent.size(), i = std::min<size_t>(4, size); i > 0; --i) {
+ result <<= 8;
+ result += exponent[size - i];
+ }
+
+ return result;
+}
+
+void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, CryptoAlgorithmIdentifier hash, bool hasHash, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsageBitmap usages, KeyPairCallback&& callback, VoidCallback&& failureCallback, ScriptExecutionContext*)
+{
+ // OpenSSL doesn't report an error if the exponent is smaller than three or even.
+ auto e = exponentVectorToUInt32(publicExponent);
+ if (!e || *e < 3 || !(*e & 0x1)) {
+ failureCallback();
+ return;
+ }
+
+ auto exponent = convertToBigNumber(publicExponent);
+ auto privateRSA = RSAPtr(RSA_new());
+ if (!exponent || RSA_generate_key_ex(privateRSA.get(), modulusLength, exponent.get(), nullptr) <= 0) {
+ failureCallback();
+ return;
+ }
+
+ auto publicRSA = RSAPtr(RSAPublicKey_dup(privateRSA.get()));
+ if (!publicRSA) {
+ failureCallback();
+ return;
+ }
+
+ auto privatePKey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_RSA(privatePKey.get(), privateRSA.get()) <= 0) {
+ failureCallback();
+ return;
+ }
+
+ auto publicPKey = EvpPKeyPtr(EVP_PKEY_new());
+ if (EVP_PKEY_set1_RSA(publicPKey.get(), publicRSA.get()) <= 0) {
+ failureCallback();
+ return;
+ }
+
+ auto publicKey = CryptoKeyRSA::create(algorithm, hash, hasHash, CryptoKeyType::Public, WTFMove(publicPKey), true, usages);
+ auto privateKey = CryptoKeyRSA::create(algorithm, hash, hasHash, CryptoKeyType::Private, WTFMove(privatePKey), extractable, usages);
+ callback(CryptoKeyPair { WTFMove(publicKey), WTFMove(privateKey) });
+}
+
+RefPtr<CryptoKeyRSA> CryptoKeyRSA::importSpki(CryptoAlgorithmIdentifier identifier, std::optional<CryptoAlgorithmIdentifier> hash, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ // We need a local pointer variable to pass to d2i (DER to internal) functions().
+ const uint8_t* ptr = keyData.data();
+
+ // We use d2i_PUBKEY() to import a public key.
+ auto pkey = EvpPKeyPtr(d2i_PUBKEY(nullptr, &ptr, keyData.size()));
+ if (!pkey || EVP_PKEY_id(pkey.get()) != EVP_PKEY_RSA)
+ return nullptr;
+
+ return adoptRef(new CryptoKeyRSA(identifier, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, CryptoKeyType::Public, WTFMove(pkey), extractable, usages));
+}
+
+RefPtr<CryptoKeyRSA> CryptoKeyRSA::importPkcs8(CryptoAlgorithmIdentifier identifier, std::optional<CryptoAlgorithmIdentifier> hash, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
+{
+ // We need a local pointer variable to pass to d2i (DER to internal) functions().
+ const uint8_t* ptr = keyData.data();
+
+ // We use d2i_PKCS8_PRIV_KEY_INFO() to import a private key.
+ auto p8inf = PKCS8PrivKeyInfoPtr(d2i_PKCS8_PRIV_KEY_INFO(nullptr, &ptr, keyData.size()));
+ if (!p8inf)
+ return nullptr;
+
+ auto pkey = EvpPKeyPtr(EVP_PKCS82PKEY(p8inf.get()));
+ if (!pkey || EVP_PKEY_id(pkey.get()) != EVP_PKEY_RSA)
+ return nullptr;
+
+ return adoptRef(new CryptoKeyRSA(identifier, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, CryptoKeyType::Private, WTFMove(pkey), extractable, usages));
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoKeyRSA::exportSpki() const
+{
+ if (type() != CryptoKeyType::Public)
+ return Exception { InvalidAccessError };
+
+ int len = i2d_PUBKEY(platformKey(), nullptr);
+ if (len < 0)
+ return Exception { OperationError };
+
+ Vector<uint8_t> keyData(len);
+ auto ptr = keyData.data();
+ if (i2d_PUBKEY(platformKey(), &ptr) < 0)
+ return Exception { OperationError };
+
+ return keyData;
+}
+
+ExceptionOr<Vector<uint8_t>> CryptoKeyRSA::exportPkcs8() const
+{
+ if (type() != CryptoKeyType::Private)
+ return Exception { InvalidAccessError };
+
+ auto p8inf = PKCS8PrivKeyInfoPtr(EVP_PKEY2PKCS8(platformKey()));
+ if (!p8inf)
+ return Exception { OperationError };
+
+ int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf.get(), nullptr);
+ if (len < 0)
+ return Exception { OperationError };
+
+ Vector<uint8_t> keyData(len);
+ auto ptr = keyData.data();
+ if (i2d_PKCS8_PRIV_KEY_INFO(p8inf.get(), &ptr) < 0)
+ return Exception { OperationError };
+
+ return keyData;
+}
+
+auto CryptoKeyRSA::algorithm() const -> KeyAlgorithm
+{
+ RSA* rsa = EVP_PKEY_get0_RSA(platformKey());
+
+ auto modulusLength = getRSAModulusLength(rsa);
+ Vector<uint8_t> publicExponent;
+
+ if (rsa) {
+ const BIGNUM* e;
+ RSA_get0_key(rsa, nullptr, &e, nullptr);
+ publicExponent = convertToBytes(e);
+ }
+
+ if (m_restrictedToSpecificHash) {
+ CryptoRsaHashedKeyAlgorithm result;
+ result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
+ result.modulusLength = modulusLength;
+ result.publicExponent = Uint8Array::tryCreate(publicExponent.data(), publicExponent.size());
+ result.hash.name = CryptoAlgorithmRegistry::singleton().name(m_hash);
+ return result;
+ }
+
+ CryptoRsaKeyAlgorithm result;
+ result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
+ result.modulusLength = modulusLength;
+ result.publicExponent = Uint8Array::tryCreate(publicExponent.data(), publicExponent.size());
+ return result;
+}
+
+std::unique_ptr<CryptoKeyRSAComponents> CryptoKeyRSA::exportData() const
+{
+ RSA* rsa = EVP_PKEY_get0_RSA(platformKey());
+ if (!rsa)
+ return nullptr;
+
+ const BIGNUM* n;
+ const BIGNUM* e;
+ const BIGNUM* d;
+ RSA_get0_key(rsa, &n, &e, &d);
+
+ switch (type()) {
+ case CryptoKeyType::Public:
+ // We need the public modulus and exponent for the public key.
+ if (!n || !e)
+ return nullptr;
+ return CryptoKeyRSAComponents::createPublic(convertToBytes(n), convertToBytes(e));
+ case CryptoKeyType::Private: {
+ // We need the public modulus, exponent, and private exponent, as well as p and q prime information.
+ const BIGNUM* p;
+ const BIGNUM* q;
+ RSA_get0_factors(rsa, &p, &q);
+
+ if (!n || !e || !d || !p || !q)
+ return nullptr;
+
+ CryptoKeyRSAComponents::PrimeInfo firstPrimeInfo;
+ firstPrimeInfo.primeFactor = convertToBytes(p);
+
+ CryptoKeyRSAComponents::PrimeInfo secondPrimeInfo;
+ secondPrimeInfo.primeFactor = convertToBytes(q);
+
+ auto context = BNCtxPtr(BN_CTX_new());
+
+ const BIGNUM* dmp1;
+ const BIGNUM* dmq1;
+ const BIGNUM* iqmp;
+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+
+ // dmp1 -- d mod (p - 1)
+ if (dmp1)
+ firstPrimeInfo.factorCRTExponent = convertToBytes(dmp1);
+ else {
+ auto dmp1New = BIGNUMPtr(BN_new());
+ auto pm1 = BIGNUMPtr(BN_dup(p));
+ if (BN_sub_word(pm1.get(), 1) == 1 && BN_mod(dmp1New.get(), d, pm1.get(), context.get()) == 1)
+ firstPrimeInfo.factorCRTExponent = convertToBytes(dmp1New.get());
+ }
+
+ // dmq1 -- d mod (q - 1)
+ if (dmq1)
+ secondPrimeInfo.factorCRTExponent = convertToBytes(dmq1);
+ else {
+ auto dmq1New = BIGNUMPtr(BN_new());
+ auto qm1 = BIGNUMPtr(BN_dup(q));
+ if (BN_sub_word(qm1.get(), 1) == 1 && BN_mod(dmq1New.get(), d, qm1.get(), context.get()) == 1)
+ secondPrimeInfo.factorCRTExponent = convertToBytes(dmq1New.get());
+ }
+
+ // iqmp -- q^(-1) mod p
+ if (iqmp)
+ secondPrimeInfo.factorCRTCoefficient = convertToBytes(iqmp);
+ else {
+ auto iqmpNew = BIGNUMPtr(BN_mod_inverse(nullptr, q, p, context.get()));
+ if (iqmpNew)
+ secondPrimeInfo.factorCRTCoefficient = convertToBytes(iqmpNew.get());
+ }
+
+ return CryptoKeyRSAComponents::createPrivateWithAdditionalData(
+ convertToBytes(n), convertToBytes(e), convertToBytes(d),
+ WTFMove(firstPrimeInfo), WTFMove(secondPrimeInfo), Vector<CryptoKeyRSAComponents::PrimeInfo> { });
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyRaw.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyRaw.cpp
new file mode 100644
index 000000000..c75684189
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyRaw.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoKeyRaw.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRegistry.h"
+
+namespace WebCore {
+
+CryptoKeyRaw::CryptoKeyRaw(CryptoAlgorithmIdentifier identifier, Vector<uint8_t>&& keyData, CryptoKeyUsageBitmap usages)
+ : CryptoKey(identifier, CryptoKeyType::Secret, false, usages)
+ , m_key(WTFMove(keyData))
+{
+}
+
+auto CryptoKeyRaw::algorithm() const -> KeyAlgorithm
+{
+ CryptoKeyAlgorithm result;
+ result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
+ return result;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyRaw.h b/src/bun.js/bindings/webcrypto/CryptoKeyRaw.h
new file mode 100644
index 000000000..df5b6b831
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyRaw.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoKey.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKeyRaw final : public CryptoKey {
+public:
+ static Ref<CryptoKeyRaw> create(CryptoAlgorithmIdentifier identifier, Vector<uint8_t>&& keyData, CryptoKeyUsageBitmap usages)
+ {
+ return adoptRef(*new CryptoKeyRaw(identifier, WTFMove(keyData), usages));
+ }
+
+ const Vector<uint8_t>& key() const { return m_key; }
+
+private:
+ CryptoKeyRaw(CryptoAlgorithmIdentifier, Vector<uint8_t>&& keyData, CryptoKeyUsageBitmap);
+
+ CryptoKeyClass keyClass() const final { return CryptoKeyClass::Raw; }
+
+ KeyAlgorithm algorithm() const final;
+
+ Vector<uint8_t> m_key;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyRaw, CryptoKeyClass::Raw)
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyType.h b/src/bun.js/bindings/webcrypto/CryptoKeyType.h
new file mode 100644
index 000000000..f090806db
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyType.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+enum class CryptoKeyType {
+ Public,
+ Private,
+ Secret
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyUsage.h b/src/bun.js/bindings/webcrypto/CryptoKeyUsage.h
new file mode 100644
index 000000000..cfd186f75
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyUsage.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+enum {
+ CryptoKeyUsageEncrypt = 1 << 0,
+ CryptoKeyUsageDecrypt = 1 << 1,
+ CryptoKeyUsageSign = 1 << 2,
+ CryptoKeyUsageVerify = 1 << 3,
+ CryptoKeyUsageDeriveKey = 1 << 4,
+ CryptoKeyUsageDeriveBits = 1 << 5,
+ CryptoKeyUsageWrapKey = 1 << 6,
+ CryptoKeyUsageUnwrapKey = 1 << 7
+};
+
+typedef int CryptoKeyUsageBitmap;
+
+// Only for binding purpose.
+enum class CryptoKeyUsage {
+ Encrypt,
+ Decrypt,
+ Sign,
+ Verify,
+ DeriveKey,
+ DeriveBits,
+ WrapKey,
+ UnwrapKey
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyUsage.idl b/src/bun.js/bindings/webcrypto/CryptoKeyUsage.idl
new file mode 100644
index 000000000..a42262deb
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoKeyUsage.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+] enum CryptoKeyUsage {
+ "encrypt",
+ "decrypt",
+ "sign",
+ "verify",
+ "deriveKey",
+ "deriveBits",
+ "wrapKey",
+ "unwrapKey"
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoRsaHashedKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/CryptoRsaHashedKeyAlgorithm.h
new file mode 100644
index 000000000..30109aa90
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoRsaHashedKeyAlgorithm.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoRsaKeyAlgorithm.h"
+
+namespace WebCore {
+
+struct CryptoRsaHashedKeyAlgorithm : CryptoRsaKeyAlgorithm {
+ // The hash algorithm that is used with this key
+ CryptoKeyAlgorithm hash;
+};
+
+}
+
diff --git a/src/bun.js/bindings/webcrypto/CryptoRsaHashedKeyAlgorithm.idl b/src/bun.js/bindings/webcrypto/CryptoRsaHashedKeyAlgorithm.idl
new file mode 100644
index 000000000..7541718ec
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoRsaHashedKeyAlgorithm.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ JSGenerateToJSObject
+] dictionary CryptoRsaHashedKeyAlgorithm : CryptoRsaKeyAlgorithm {
+ // The hash algorithm that is used with this key
+ required CryptoKeyAlgorithm hash;
+};
diff --git a/src/bun.js/bindings/webcrypto/CryptoRsaKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/CryptoRsaKeyAlgorithm.h
new file mode 100644
index 000000000..7723d09f4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoRsaKeyAlgorithm.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoKeyAlgorithm.h"
+#include <JavaScriptCore/Uint8Array.h>
+
+namespace WebCore {
+
+struct CryptoRsaKeyAlgorithm : CryptoKeyAlgorithm {
+ // The length, in bits, of the RSA modulus
+ unsigned modulusLength;
+ // The RSA public exponent
+ RefPtr<Uint8Array> publicExponent;
+};
+
+}
+
diff --git a/src/bun.js/bindings/webcrypto/CryptoRsaKeyAlgorithm.idl b/src/bun.js/bindings/webcrypto/CryptoRsaKeyAlgorithm.idl
new file mode 100644
index 000000000..207315358
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/CryptoRsaKeyAlgorithm.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef Uint8Array BigInteger;
+
+[
+ Conditional=WEB_CRYPTO,
+ JSGenerateToJSObject
+] dictionary CryptoRsaKeyAlgorithm : CryptoKeyAlgorithm {
+ // The length, in bits, of the RSA modulus
+ required unsigned long modulusLength;
+ // The RSA public exponent
+ required BigInteger publicExponent;
+};
diff --git a/src/bun.js/bindings/webcrypto/EcKeyParams.idl b/src/bun.js/bindings/webcrypto/EcKeyParams.idl
new file mode 100644
index 000000000..97ea4b7a2
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/EcKeyParams.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This is a unified dictionary for EcKeyImportParams and EcKeyGenParams.
+// https://www.w3.org/TR/WebCryptoAPI/#EcKeyImportParams-dictionary, and
+// https://www.w3.org/TR/WebCryptoAPI/#EcKeyGenParams-dictionary
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmEcKeyParams
+] dictionary EcKeyParams : CryptoAlgorithmParameters {
+ required DOMString namedCurve;
+};
diff --git a/src/bun.js/bindings/webcrypto/EcdhKeyDeriveParams.idl b/src/bun.js/bindings/webcrypto/EcdhKeyDeriveParams.idl
new file mode 100644
index 000000000..568f190cc
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/EcdhKeyDeriveParams.idl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmEcdhKeyDeriveParams,
+] dictionary EcdhKeyDeriveParams : CryptoAlgorithmParameters {
+ // We should rename this to public once https://bugs.webkit.org/show_bug.cgi?id=169333 is fixed.
+ // The peer's EC public key.
+ required CryptoKey publicKey;
+};
diff --git a/src/bun.js/bindings/webcrypto/EcdsaParams.idl b/src/bun.js/bindings/webcrypto/EcdsaParams.idl
new file mode 100644
index 000000000..5323fccd1
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/EcdsaParams.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef (object or DOMString) HashAlgorithmIdentifier;
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmEcdsaParams
+] dictionary EcdsaParams : CryptoAlgorithmParameters {
+ // The hash algorithm to use
+ required HashAlgorithmIdentifier hash;
+};
diff --git a/src/bun.js/bindings/webcrypto/HkdfParams.idl b/src/bun.js/bindings/webcrypto/HkdfParams.idl
new file mode 100644
index 000000000..651634505
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/HkdfParams.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef (object or DOMString) HashAlgorithmIdentifier;
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmHkdfParams,
+] dictionary HkdfParams : CryptoAlgorithmParameters {
+ // The algorithm to use with HMAC (e.g.: SHA-256)
+ required HashAlgorithmIdentifier hash;
+ // A bit string that corresponds to the salt used in the extract step.
+ required BufferSource salt;
+ // A bit string that corresponds to the context and application specific context for the derived keying material.
+ required BufferSource info;
+};
diff --git a/src/bun.js/bindings/webcrypto/HmacKeyParams.idl b/src/bun.js/bindings/webcrypto/HmacKeyParams.idl
new file mode 100644
index 000000000..d751b9411
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/HmacKeyParams.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef (object or DOMString) HashAlgorithmIdentifier;
+
+// This is a unified dictionary for HmacImportParams and HmacKeyGenParams.
+// https://www.w3.org/TR/WebCryptoAPI/#hmac-importparams, and
+// https://www.w3.org/TR/WebCryptoAPI/#hmac-keygen-params
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmHmacKeyParams
+] dictionary HmacKeyParams : CryptoAlgorithmParameters {
+ // The inner hash function to use.
+ required HashAlgorithmIdentifier hash;
+ // The length (in bits) of the key to generate. If unspecified, the
+ // recommended length will be used, which is the size of the associated hash function's block
+ // size.
+ [EnforceRange] unsigned long length;
+};
diff --git a/src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.cpp b/src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.cpp
new file mode 100644
index 000000000..af0ddfda7
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.cpp
@@ -0,0 +1,85 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSAesCbcCfbParams.h"
+
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmAesCbcCfbParams convertDictionary<CryptoAlgorithmAesCbcCfbParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmAesCbcCfbParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "AesCbcCfbParams", "DOMString");
+ return { };
+ }
+ JSValue ivValue;
+ if (isNullOrUndefined)
+ ivValue = jsUndefined();
+ else {
+ ivValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "iv"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!ivValue.isUndefined()) {
+ result.iv = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(lexicalGlobalObject, ivValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "iv", "AesCbcCfbParams", "(ArrayBufferView or ArrayBuffer)");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.dep b/src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.dep
new file mode 100644
index 000000000..e8fe070b8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmAesCbcCfbParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.h b/src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.h
new file mode 100644
index 000000000..81a61fc13
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesCbcCfbParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesCbcCfbParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmAesCbcCfbParams convertDictionary<CryptoAlgorithmAesCbcCfbParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSAesCtrParams.cpp b/src/bun.js/bindings/webcrypto/JSAesCtrParams.cpp
new file mode 100644
index 000000000..97ce6322e
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesCtrParams.cpp
@@ -0,0 +1,100 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSAesCtrParams.h"
+
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmAesCtrParams convertDictionary<CryptoAlgorithmAesCtrParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmAesCtrParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "AesCtrParams", "DOMString");
+ return { };
+ }
+ JSValue counterValue;
+ if (isNullOrUndefined)
+ counterValue = jsUndefined();
+ else {
+ counterValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "counter"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!counterValue.isUndefined()) {
+ result.counter = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(lexicalGlobalObject, counterValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "counter", "AesCtrParams", "(ArrayBufferView or ArrayBuffer)");
+ return { };
+ }
+ JSValue lengthValue;
+ if (isNullOrUndefined)
+ lengthValue = jsUndefined();
+ else {
+ lengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "length"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!lengthValue.isUndefined()) {
+ result.length = convert<IDLEnforceRangeAdaptor<IDLOctet>>(lexicalGlobalObject, lengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "length", "AesCtrParams", "octet");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSAesCtrParams.dep b/src/bun.js/bindings/webcrypto/JSAesCtrParams.dep
new file mode 100644
index 000000000..75e3da1b8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesCtrParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmAesCtrParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSAesCtrParams.h b/src/bun.js/bindings/webcrypto/JSAesCtrParams.h
new file mode 100644
index 000000000..2e8a66c8e
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesCtrParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesCtrParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmAesCtrParams convertDictionary<CryptoAlgorithmAesCtrParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSAesGcmParams.cpp b/src/bun.js/bindings/webcrypto/JSAesGcmParams.cpp
new file mode 100644
index 000000000..7e13f82e9
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesGcmParams.cpp
@@ -0,0 +1,108 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSAesGcmParams.h"
+
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmAesGcmParams convertDictionary<CryptoAlgorithmAesGcmParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmAesGcmParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "AesGcmParams", "DOMString");
+ return { };
+ }
+ JSValue additionalDataValue;
+ if (isNullOrUndefined)
+ additionalDataValue = jsUndefined();
+ else {
+ additionalDataValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "additionalData"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!additionalDataValue.isUndefined()) {
+ result.additionalData = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(lexicalGlobalObject, additionalDataValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue ivValue;
+ if (isNullOrUndefined)
+ ivValue = jsUndefined();
+ else {
+ ivValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "iv"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!ivValue.isUndefined()) {
+ result.iv = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(lexicalGlobalObject, ivValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "iv", "AesGcmParams", "(ArrayBufferView or ArrayBuffer)");
+ return { };
+ }
+ JSValue tagLengthValue;
+ if (isNullOrUndefined)
+ tagLengthValue = jsUndefined();
+ else {
+ tagLengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "tagLength"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!tagLengthValue.isUndefined()) {
+ result.tagLength = convert<IDLEnforceRangeAdaptor<IDLOctet>>(lexicalGlobalObject, tagLengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSAesGcmParams.dep b/src/bun.js/bindings/webcrypto/JSAesGcmParams.dep
new file mode 100644
index 000000000..7ea1a9ef3
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesGcmParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmAesGcmParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSAesGcmParams.h b/src/bun.js/bindings/webcrypto/JSAesGcmParams.h
new file mode 100644
index 000000000..56308053a
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesGcmParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesGcmParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmAesGcmParams convertDictionary<CryptoAlgorithmAesGcmParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSAesKeyParams.cpp b/src/bun.js/bindings/webcrypto/JSAesKeyParams.cpp
new file mode 100644
index 000000000..2437d14ea
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesKeyParams.cpp
@@ -0,0 +1,83 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSAesKeyParams.h"
+
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include <JavaScriptCore/JSCInlines.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmAesKeyParams convertDictionary<CryptoAlgorithmAesKeyParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmAesKeyParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "AesKeyParams", "DOMString");
+ return { };
+ }
+ JSValue lengthValue;
+ if (isNullOrUndefined)
+ lengthValue = jsUndefined();
+ else {
+ lengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "length"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!lengthValue.isUndefined()) {
+ result.length = convert<IDLEnforceRangeAdaptor<IDLUnsignedShort>>(lexicalGlobalObject, lengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "length", "AesKeyParams", "unsigned short");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSAesKeyParams.dep b/src/bun.js/bindings/webcrypto/JSAesKeyParams.dep
new file mode 100644
index 000000000..a23ff45ae
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesKeyParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmAesKeyParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSAesKeyParams.h b/src/bun.js/bindings/webcrypto/JSAesKeyParams.h
new file mode 100644
index 000000000..0dd7782af
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSAesKeyParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmAesKeyParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmAesKeyParams convertDictionary<CryptoAlgorithmAesKeyParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.cpp b/src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.cpp
new file mode 100644
index 000000000..3f7568947
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.cpp
@@ -0,0 +1,101 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoAesKeyAlgorithm.h"
+
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMGlobalObject.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAesKeyAlgorithm convertDictionary<CryptoAesKeyAlgorithm>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAesKeyAlgorithm result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "CryptoAesKeyAlgorithm", "DOMString");
+ return { };
+ }
+ JSValue lengthValue;
+ if (isNullOrUndefined)
+ lengthValue = jsUndefined();
+ else {
+ lengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "length"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!lengthValue.isUndefined()) {
+ result.length = convert<IDLUnsignedShort>(lexicalGlobalObject, lengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "length", "CryptoAesKeyAlgorithm", "unsigned short");
+ return { };
+ }
+ return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const CryptoAesKeyAlgorithm& dictionary)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
+
+ auto nameValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.name);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "name"_s), nameValue);
+ auto lengthValue = toJS<IDLUnsignedShort>(lexicalGlobalObject, throwScope, dictionary.length);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "length"_s), lengthValue);
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.dep b/src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.dep
new file mode 100644
index 000000000..aaea407df
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.dep
@@ -0,0 +1,2 @@
+CryptoAesKeyAlgorithm.h : CryptoKeyAlgorithm.idl
+CryptoKeyAlgorithm.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.h
new file mode 100644
index 000000000..5297bbaf8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoAesKeyAlgorithm.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAesKeyAlgorithm.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAesKeyAlgorithm convertDictionary<CryptoAesKeyAlgorithm>(JSC::JSGlobalObject&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const CryptoAesKeyAlgorithm&);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.cpp b/src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.cpp
new file mode 100644
index 000000000..298e6afe4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.cpp
@@ -0,0 +1,68 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoAlgorithmParameters.h"
+
+#include "JSDOMConvertStrings.h"
+#include <JavaScriptCore/JSCInlines.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmParameters convertDictionary<CryptoAlgorithmParameters>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmParameters result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "CryptoAlgorithmParameters", "DOMString");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.dep b/src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.dep
new file mode 100644
index 000000000..e638f59cb
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.dep
@@ -0,0 +1 @@
+CryptoAlgorithmParameters.h :
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.h b/src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.h
new file mode 100644
index 000000000..3c0ea58db
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoAlgorithmParameters.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmParameters.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmParameters convertDictionary<CryptoAlgorithmParameters>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.cpp b/src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.cpp
new file mode 100644
index 000000000..e63283c97
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.cpp
@@ -0,0 +1,100 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoEcKeyAlgorithm.h"
+
+#include "JSDOMConvertStrings.h"
+#include "JSDOMGlobalObject.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoEcKeyAlgorithm convertDictionary<CryptoEcKeyAlgorithm>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoEcKeyAlgorithm result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "CryptoEcKeyAlgorithm", "DOMString");
+ return { };
+ }
+ JSValue namedCurveValue;
+ if (isNullOrUndefined)
+ namedCurveValue = jsUndefined();
+ else {
+ namedCurveValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "namedCurve"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!namedCurveValue.isUndefined()) {
+ result.namedCurve = convert<IDLDOMString>(lexicalGlobalObject, namedCurveValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "namedCurve", "CryptoEcKeyAlgorithm", "DOMString");
+ return { };
+ }
+ return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const CryptoEcKeyAlgorithm& dictionary)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
+
+ auto nameValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.name);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "name"_s), nameValue);
+ auto namedCurveValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.namedCurve);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "namedCurve"_s), namedCurveValue);
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.dep b/src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.dep
new file mode 100644
index 000000000..789ae54a0
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.dep
@@ -0,0 +1,2 @@
+CryptoEcKeyAlgorithm.h : CryptoKeyAlgorithm.idl
+CryptoKeyAlgorithm.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.h
new file mode 100644
index 000000000..c48a18536
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoEcKeyAlgorithm.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoEcKeyAlgorithm.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoEcKeyAlgorithm convertDictionary<CryptoEcKeyAlgorithm>(JSC::JSGlobalObject&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const CryptoEcKeyAlgorithm&);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.cpp b/src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.cpp
new file mode 100644
index 000000000..850eeb2aa
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.cpp
@@ -0,0 +1,119 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoHmacKeyAlgorithm.h"
+
+#include "JSCryptoKeyAlgorithm.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMGlobalObject.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoHmacKeyAlgorithm convertDictionary<CryptoHmacKeyAlgorithm>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoHmacKeyAlgorithm result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "CryptoHmacKeyAlgorithm", "DOMString");
+ return { };
+ }
+ JSValue hashValue;
+ if (isNullOrUndefined)
+ hashValue = jsUndefined();
+ else {
+ hashValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hash"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!hashValue.isUndefined()) {
+ result.hash = convert<IDLDictionary<CryptoKeyAlgorithm>>(lexicalGlobalObject, hashValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "hash", "CryptoHmacKeyAlgorithm", "CryptoKeyAlgorithm");
+ return { };
+ }
+ JSValue lengthValue;
+ if (isNullOrUndefined)
+ lengthValue = jsUndefined();
+ else {
+ lengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "length"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!lengthValue.isUndefined()) {
+ result.length = convert<IDLUnsignedLong>(lexicalGlobalObject, lengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "length", "CryptoHmacKeyAlgorithm", "unsigned long");
+ return { };
+ }
+ return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const CryptoHmacKeyAlgorithm& dictionary)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
+
+ auto nameValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.name);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "name"_s), nameValue);
+ auto hashValue = toJS<IDLDictionary<CryptoKeyAlgorithm>>(lexicalGlobalObject, globalObject, throwScope, dictionary.hash);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "hash"_s), hashValue);
+ auto lengthValue = toJS<IDLUnsignedLong>(lexicalGlobalObject, throwScope, dictionary.length);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "length"_s), lengthValue);
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.dep b/src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.dep
new file mode 100644
index 000000000..6d506eae2
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.dep
@@ -0,0 +1,2 @@
+CryptoHmacKeyAlgorithm.h : CryptoKeyAlgorithm.idl
+CryptoKeyAlgorithm.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.h
new file mode 100644
index 000000000..8d273991d
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoHmacKeyAlgorithm.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoHmacKeyAlgorithm.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoHmacKeyAlgorithm convertDictionary<CryptoHmacKeyAlgorithm>(JSC::JSGlobalObject&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const CryptoHmacKeyAlgorithm&);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKey.cpp b/src/bun.js/bindings/webcrypto/JSCryptoKey.cpp
new file mode 100644
index 000000000..dea8e3ff7
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKey.cpp
@@ -0,0 +1,361 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoKey.h"
+
+#include "ActiveDOMObject.h"
+#include "ExtendedDOMClientIsoSubspaces.h"
+#include "ExtendedDOMIsoSubspaces.h"
+#include "JSCryptoAesKeyAlgorithm.h"
+#include "JSCryptoEcKeyAlgorithm.h"
+#include "JSCryptoHmacKeyAlgorithm.h"
+#include "JSCryptoKeyAlgorithm.h"
+#include "JSCryptoKeyUsage.h"
+#include "JSCryptoRsaHashedKeyAlgorithm.h"
+#include "JSCryptoRsaKeyAlgorithm.h"
+#include "JSDOMAttribute.h"
+#include "JSDOMBinding.h"
+#include "JSDOMConstructorNotConstructable.h"
+#include "JSDOMConvertBoolean.h"
+#include "JSDOMConvertDictionary.h"
+#include "JSDOMConvertSequences.h"
+#include "JSDOMConvertUnion.h"
+#include "JSDOMExceptionHandling.h"
+#include "JSDOMGlobalObject.h"
+#include "JSDOMGlobalObjectInlines.h"
+#include "JSDOMWrapperCache.h"
+#include "ScriptExecutionContext.h"
+#include "WebCoreJSClientData.h"
+#include "WebCoreOpaqueRoot.h"
+#include <JavaScriptCore/FunctionPrototype.h>
+#include <JavaScriptCore/HeapAnalyzer.h>
+#include <JavaScriptCore/JSArray.h>
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
+#include <JavaScriptCore/JSString.h>
+#include <JavaScriptCore/SlotVisitorMacros.h>
+#include <JavaScriptCore/SubspaceInlines.h>
+#include <variant>
+#include <wtf/GetPtr.h>
+#include <wtf/PointerPreparations.h>
+#include <wtf/SortedArrayMap.h>
+#include <wtf/URL.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+String convertEnumerationToString(CryptoKey::Type enumerationValue)
+{
+ static const NeverDestroyed<String> values[] = {
+ MAKE_STATIC_STRING_IMPL("public"),
+ MAKE_STATIC_STRING_IMPL("private"),
+ MAKE_STATIC_STRING_IMPL("secret"),
+ };
+ static_assert(static_cast<size_t>(CryptoKey::Type::Public) == 0, "CryptoKey::Type::Public is not 0 as expected");
+ static_assert(static_cast<size_t>(CryptoKey::Type::Private) == 1, "CryptoKey::Type::Private is not 1 as expected");
+ static_assert(static_cast<size_t>(CryptoKey::Type::Secret) == 2, "CryptoKey::Type::Secret is not 2 as expected");
+ ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
+ return values[static_cast<size_t>(enumerationValue)];
+}
+
+template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject, CryptoKey::Type enumerationValue)
+{
+ return jsStringWithCache(lexicalGlobalObject.vm(), convertEnumerationToString(enumerationValue));
+}
+
+template<> std::optional<CryptoKey::Type> parseEnumeration<CryptoKey::Type>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ auto stringValue = value.toWTFString(&lexicalGlobalObject);
+ static constexpr std::pair<ComparableASCIILiteral, CryptoKey::Type> mappings[] = {
+ { "private", CryptoKey::Type::Private },
+ { "public", CryptoKey::Type::Public },
+ { "secret", CryptoKey::Type::Secret },
+ };
+ static constexpr SortedArrayMap enumerationMapping { mappings };
+ if (auto* enumerationValue = enumerationMapping.tryGet(stringValue); LIKELY(enumerationValue))
+ return *enumerationValue;
+ return std::nullopt;
+}
+
+template<> const char* expectedEnumerationValues<CryptoKey::Type>()
+{
+ return "\"public\", \"private\", \"secret\"";
+}
+
+// Attributes
+
+static JSC_DECLARE_CUSTOM_GETTER(jsCryptoKeyConstructor);
+static JSC_DECLARE_CUSTOM_GETTER(jsCryptoKey_type);
+static JSC_DECLARE_CUSTOM_GETTER(jsCryptoKey_extractable);
+static JSC_DECLARE_CUSTOM_GETTER(jsCryptoKey_algorithm);
+static JSC_DECLARE_CUSTOM_GETTER(jsCryptoKey_usages);
+
+class JSCryptoKeyPrototype final : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+ static JSCryptoKeyPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ JSCryptoKeyPrototype* ptr = new (NotNull, JSC::allocateCell<JSCryptoKeyPrototype>(vm)) JSCryptoKeyPrototype(vm, globalObject, structure);
+ ptr->finishCreation(vm);
+ return ptr;
+ }
+
+ DECLARE_INFO;
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCryptoKeyPrototype, Base);
+ return &vm.plainObjectSpace();
+ }
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+private:
+ JSCryptoKeyPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+ : JSC::JSNonFinalObject(vm, structure)
+ {
+ }
+
+ void finishCreation(JSC::VM&);
+};
+STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCryptoKeyPrototype, JSCryptoKeyPrototype::Base);
+
+using JSCryptoKeyDOMConstructor = JSDOMConstructorNotConstructable<JSCryptoKey>;
+
+template<> const ClassInfo JSCryptoKeyDOMConstructor::s_info = { "CryptoKey"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCryptoKeyDOMConstructor) };
+
+template<> JSValue JSCryptoKeyDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
+{
+ UNUSED_PARAM(vm);
+ return globalObject.functionPrototype();
+}
+
+template<> void JSCryptoKeyDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+ JSString* nameString = jsNontrivialString(vm, "CryptoKey"_s);
+ m_originalName.set(vm, this, nameString);
+ putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+ putDirect(vm, vm.propertyNames->prototype, JSCryptoKey::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
+}
+
+/* Hash table for prototype */
+
+static const HashTableValue JSCryptoKeyPrototypeTableValues[] =
+{
+ { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsCryptoKeyConstructor, 0 } },
+ { "type"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, jsCryptoKey_type, 0 } },
+ { "extractable"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, jsCryptoKey_extractable, 0 } },
+ { "algorithm"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, jsCryptoKey_algorithm, 0 } },
+ { "usages"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, jsCryptoKey_usages, 0 } },
+};
+
+const ClassInfo JSCryptoKeyPrototype::s_info = { "CryptoKey"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCryptoKeyPrototype) };
+
+void JSCryptoKeyPrototype::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ reifyStaticProperties(vm, JSCryptoKey::info(), JSCryptoKeyPrototypeTableValues, *this);
+ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+}
+
+const ClassInfo JSCryptoKey::s_info = { "CryptoKey"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCryptoKey) };
+
+JSCryptoKey::JSCryptoKey(Structure* structure, JSDOMGlobalObject& globalObject, Ref<CryptoKey>&& impl)
+ : JSDOMWrapper<CryptoKey>(structure, globalObject, WTFMove(impl))
+{
+}
+
+void JSCryptoKey::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+
+ // static_assert(!std::is_base_of<ActiveDOMObject, CryptoKey>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
+
+}
+
+JSObject* JSCryptoKey::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return JSCryptoKeyPrototype::create(vm, &globalObject, JSCryptoKeyPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+JSObject* JSCryptoKey::prototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return getDOMPrototype<JSCryptoKey>(vm, globalObject);
+}
+
+JSValue JSCryptoKey::getConstructor(VM& vm, const JSGlobalObject* globalObject)
+{
+ return getDOMConstructor<JSCryptoKeyDOMConstructor, DOMConstructorID::CryptoKey>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
+}
+
+void JSCryptoKey::destroy(JSC::JSCell* cell)
+{
+ JSCryptoKey* thisObject = static_cast<JSCryptoKey*>(cell);
+ thisObject->JSCryptoKey::~JSCryptoKey();
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsCryptoKeyConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
+{
+ VM& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto* prototype = jsDynamicCast<JSCryptoKeyPrototype*>(JSValue::decode(thisValue));
+ if (UNLIKELY(!prototype))
+ return throwVMTypeError(lexicalGlobalObject, throwScope);
+ return JSValue::encode(JSCryptoKey::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
+}
+
+static inline JSValue jsCryptoKey_typeGetter(JSGlobalObject& lexicalGlobalObject, JSCryptoKey& thisObject)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto& impl = thisObject.wrapped();
+ RELEASE_AND_RETURN(throwScope, (toJS<IDLEnumeration<CryptoKey::Type>>(lexicalGlobalObject, throwScope, impl.type())));
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsCryptoKey_type, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ return IDLAttribute<JSCryptoKey>::get<jsCryptoKey_typeGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
+}
+
+static inline JSValue jsCryptoKey_extractableGetter(JSGlobalObject& lexicalGlobalObject, JSCryptoKey& thisObject)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto& impl = thisObject.wrapped();
+ RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.extractable())));
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsCryptoKey_extractable, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ return IDLAttribute<JSCryptoKey>::get<jsCryptoKey_extractableGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
+}
+
+static inline JSValue jsCryptoKey_algorithmGetter(JSGlobalObject& lexicalGlobalObject, JSCryptoKey& thisObject)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ if (JSValue cachedValue = thisObject.m_algorithm.get())
+ return cachedValue;
+ auto& impl = thisObject.wrapped();
+ JSValue result = toJS<IDLUnion<IDLDictionary<CryptoKeyAlgorithm>, IDLDictionary<CryptoAesKeyAlgorithm>, IDLDictionary<CryptoEcKeyAlgorithm>, IDLDictionary<CryptoHmacKeyAlgorithm>, IDLDictionary<CryptoRsaHashedKeyAlgorithm>, IDLDictionary<CryptoRsaKeyAlgorithm>>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.algorithm());
+ RETURN_IF_EXCEPTION(throwScope, { });
+ thisObject.m_algorithm.set(JSC::getVM(&lexicalGlobalObject), &thisObject, result);
+ return result;
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsCryptoKey_algorithm, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ return IDLAttribute<JSCryptoKey>::get<jsCryptoKey_algorithmGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
+}
+
+static inline JSValue jsCryptoKey_usagesGetter(JSGlobalObject& lexicalGlobalObject, JSCryptoKey& thisObject)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ if (JSValue cachedValue = thisObject.m_usages.get())
+ return cachedValue;
+ auto& impl = thisObject.wrapped();
+ JSValue result = toJS<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.usages());
+ RETURN_IF_EXCEPTION(throwScope, { });
+ thisObject.m_usages.set(JSC::getVM(&lexicalGlobalObject), &thisObject, result);
+ return result;
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsCryptoKey_usages, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+{
+ return IDLAttribute<JSCryptoKey>::get<jsCryptoKey_usagesGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
+}
+
+JSC::GCClient::IsoSubspace* JSCryptoKey::subspaceForImpl(JSC::VM& vm)
+{
+ return WebCore::subspaceForImpl<JSCryptoKey, UseCustomHeapCellType::No>(vm,
+ [] (auto& spaces) { return spaces.m_clientSubspaceForCryptoKey.get(); },
+ [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForCryptoKey = WTFMove(space); },
+ [] (auto& spaces) { return spaces.m_subspaceForCryptoKey.get(); },
+ [] (auto& spaces, auto&& space) { spaces.m_subspaceForCryptoKey = WTFMove(space); }
+ );
+}
+
+template<typename Visitor>
+void JSCryptoKey::visitChildrenImpl(JSCell* cell, Visitor& visitor)
+{
+ auto* thisObject = jsCast<JSCryptoKey*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+ visitor.append(thisObject->m_algorithm);
+ visitor.append(thisObject->m_usages);
+}
+
+DEFINE_VISIT_CHILDREN(JSCryptoKey);
+
+void JSCryptoKey::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
+{
+ auto* thisObject = jsCast<JSCryptoKey*>(cell);
+ analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
+ if (thisObject->scriptExecutionContext())
+ analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
+ Base::analyzeHeap(cell, analyzer);
+}
+
+bool JSCryptoKeyOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void* context, AbstractSlotVisitor& visitor, const char** reason)
+{
+ auto* jsCryptoKey = jsCast<JSCryptoKey*>(handle.slot()->asCell());
+ CryptoKey* owner = &jsCryptoKey->wrapped();
+ if (UNLIKELY(reason))
+ *reason = "Reachable from CryptoKey";
+ return visitor.containsOpaqueRoot(context);
+}
+
+void JSCryptoKeyOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
+{
+ auto* jsCryptoKey = static_cast<JSCryptoKey*>(handle.slot()->asCell());
+ auto& world = *static_cast<DOMWrapperWorld*>(context);
+ uncacheWrapper(world, &jsCryptoKey->wrapped(), jsCryptoKey);
+}
+
+JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<CryptoKey>&& impl)
+{
+ return createWrapper<CryptoKey>(globalObject, WTFMove(impl));
+}
+
+JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, CryptoKey& impl)
+{
+ return wrap(lexicalGlobalObject, globalObject, impl);
+}
+
+CryptoKey* JSCryptoKey::toWrapped(JSC::VM&, JSC::JSValue value)
+{
+ if (auto* wrapper = jsDynamicCast<JSCryptoKey*>(value))
+ return &wrapper->wrapped();
+ return nullptr;
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKey.dep b/src/bun.js/bindings/webcrypto/JSCryptoKey.dep
new file mode 100644
index 000000000..b1bf0ac9d
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKey.dep
@@ -0,0 +1 @@
+JSCryptoKey.h :
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKey.h b/src/bun.js/bindings/webcrypto/JSCryptoKey.h
new file mode 100644
index 000000000..57a6dbbfb
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKey.h
@@ -0,0 +1,108 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKey.h"
+#include "JSDOMConvertEnumeration.h"
+#include "JSDOMWrapper.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+class JSCryptoKey : public JSDOMWrapper<CryptoKey> {
+public:
+ using Base = JSDOMWrapper<CryptoKey>;
+ static JSCryptoKey* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<CryptoKey>&& impl)
+ {
+ JSCryptoKey* ptr = new (NotNull, JSC::allocateCell<JSCryptoKey>(globalObject->vm())) JSCryptoKey(structure, *globalObject, WTFMove(impl));
+ ptr->finishCreation(globalObject->vm());
+ return ptr;
+ }
+
+ static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
+ static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
+ static CryptoKey* toWrapped(JSC::VM&, JSC::JSValue);
+ static void destroy(JSC::JSCell*);
+
+ DECLARE_INFO;
+
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray);
+ }
+
+ static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
+ mutable JSC::WriteBarrier<JSC::Unknown> m_algorithm;
+ mutable JSC::WriteBarrier<JSC::Unknown> m_usages;
+ template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return subspaceForImpl(vm);
+ }
+ static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
+ DECLARE_VISIT_CHILDREN;
+
+ static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
+protected:
+ JSCryptoKey(JSC::Structure*, JSDOMGlobalObject&, Ref<CryptoKey>&&);
+
+ void finishCreation(JSC::VM&);
+};
+
+class JSCryptoKeyOwner final : public JSC::WeakHandleOwner {
+public:
+ bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final;
+ void finalize(JSC::Handle<JSC::Unknown>, void* context) final;
+};
+
+inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, CryptoKey*)
+{
+ static NeverDestroyed<JSCryptoKeyOwner> owner;
+ return &owner.get();
+}
+
+inline void* wrapperKey(CryptoKey* wrappableObject)
+{
+ return wrappableObject;
+}
+
+JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, CryptoKey&);
+inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, CryptoKey* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<CryptoKey>&&);
+inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<CryptoKey>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
+
+template<> struct JSDOMWrapperConverterTraits<CryptoKey> {
+ using WrapperClass = JSCryptoKey;
+ using ToWrappedReturnType = CryptoKey*;
+};
+String convertEnumerationToString(CryptoKey::Type);
+template<> JSC::JSString* convertEnumerationToJS(JSC::JSGlobalObject&, CryptoKey::Type);
+
+template<> std::optional<CryptoKey::Type> parseEnumeration<CryptoKey::Type>(JSC::JSGlobalObject&, JSC::JSValue);
+template<> const char* expectedEnumerationValues<CryptoKey::Type>();
+
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.cpp b/src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.cpp
new file mode 100644
index 000000000..c7009a16d
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.cpp
@@ -0,0 +1,83 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoKeyAlgorithm.h"
+
+#include "JSDOMConvertStrings.h"
+#include "JSDOMGlobalObject.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoKeyAlgorithm convertDictionary<CryptoKeyAlgorithm>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoKeyAlgorithm result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "CryptoKeyAlgorithm", "DOMString");
+ return { };
+ }
+ return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const CryptoKeyAlgorithm& dictionary)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
+
+ auto nameValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.name);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "name"_s), nameValue);
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.dep b/src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.dep
new file mode 100644
index 000000000..b0b711d25
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.dep
@@ -0,0 +1 @@
+CryptoKeyAlgorithm.h :
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.h
new file mode 100644
index 000000000..979c0e0a4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKeyAlgorithm.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKeyAlgorithm.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoKeyAlgorithm convertDictionary<CryptoKeyAlgorithm>(JSC::JSGlobalObject&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const CryptoKeyAlgorithm&);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKeyPair.cpp b/src/bun.js/bindings/webcrypto/JSCryptoKeyPair.cpp
new file mode 100644
index 000000000..82947e907
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKeyPair.cpp
@@ -0,0 +1,99 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoKeyPair.h"
+
+#include "JSCryptoKey.h"
+#include "JSDOMConvertInterface.h"
+#include "JSDOMGlobalObject.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoKeyPair convertDictionary<CryptoKeyPair>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoKeyPair result;
+ JSValue privateKeyValue;
+ if (isNullOrUndefined)
+ privateKeyValue = jsUndefined();
+ else {
+ privateKeyValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "privateKey"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!privateKeyValue.isUndefined()) {
+ result.privateKey = convert<IDLInterface<CryptoKey>>(lexicalGlobalObject, privateKeyValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue publicKeyValue;
+ if (isNullOrUndefined)
+ publicKeyValue = jsUndefined();
+ else {
+ publicKeyValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "publicKey"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!publicKeyValue.isUndefined()) {
+ result.publicKey = convert<IDLInterface<CryptoKey>>(lexicalGlobalObject, publicKeyValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const CryptoKeyPair& dictionary)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
+
+ if (!IDLInterface<CryptoKey>::isNullValue(dictionary.privateKey)) {
+ auto privateKeyValue = toJS<IDLInterface<CryptoKey>>(lexicalGlobalObject, globalObject, throwScope, IDLInterface<CryptoKey>::extractValueFromNullable(dictionary.privateKey));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "privateKey"_s), privateKeyValue);
+ }
+ if (!IDLInterface<CryptoKey>::isNullValue(dictionary.publicKey)) {
+ auto publicKeyValue = toJS<IDLInterface<CryptoKey>>(lexicalGlobalObject, globalObject, throwScope, IDLInterface<CryptoKey>::extractValueFromNullable(dictionary.publicKey));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "publicKey"_s), publicKeyValue);
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKeyPair.dep b/src/bun.js/bindings/webcrypto/JSCryptoKeyPair.dep
new file mode 100644
index 000000000..904d979ee
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKeyPair.dep
@@ -0,0 +1 @@
+CryptoKeyPair.h :
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKeyPair.h b/src/bun.js/bindings/webcrypto/JSCryptoKeyPair.h
new file mode 100644
index 000000000..1284c368e
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKeyPair.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKeyPair.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoKeyPair convertDictionary<CryptoKeyPair>(JSC::JSGlobalObject&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const CryptoKeyPair&);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKeyUsage.cpp b/src/bun.js/bindings/webcrypto/JSCryptoKeyUsage.cpp
new file mode 100644
index 000000000..09d4b348b
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKeyUsage.cpp
@@ -0,0 +1,91 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoKeyUsage.h"
+
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/JSString.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/SortedArrayMap.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+String convertEnumerationToString(CryptoKeyUsage enumerationValue)
+{
+ static const NeverDestroyed<String> values[] = {
+ MAKE_STATIC_STRING_IMPL("encrypt"),
+ MAKE_STATIC_STRING_IMPL("decrypt"),
+ MAKE_STATIC_STRING_IMPL("sign"),
+ MAKE_STATIC_STRING_IMPL("verify"),
+ MAKE_STATIC_STRING_IMPL("deriveKey"),
+ MAKE_STATIC_STRING_IMPL("deriveBits"),
+ MAKE_STATIC_STRING_IMPL("wrapKey"),
+ MAKE_STATIC_STRING_IMPL("unwrapKey"),
+ };
+ static_assert(static_cast<size_t>(CryptoKeyUsage::Encrypt) == 0, "CryptoKeyUsage::Encrypt is not 0 as expected");
+ static_assert(static_cast<size_t>(CryptoKeyUsage::Decrypt) == 1, "CryptoKeyUsage::Decrypt is not 1 as expected");
+ static_assert(static_cast<size_t>(CryptoKeyUsage::Sign) == 2, "CryptoKeyUsage::Sign is not 2 as expected");
+ static_assert(static_cast<size_t>(CryptoKeyUsage::Verify) == 3, "CryptoKeyUsage::Verify is not 3 as expected");
+ static_assert(static_cast<size_t>(CryptoKeyUsage::DeriveKey) == 4, "CryptoKeyUsage::DeriveKey is not 4 as expected");
+ static_assert(static_cast<size_t>(CryptoKeyUsage::DeriveBits) == 5, "CryptoKeyUsage::DeriveBits is not 5 as expected");
+ static_assert(static_cast<size_t>(CryptoKeyUsage::WrapKey) == 6, "CryptoKeyUsage::WrapKey is not 6 as expected");
+ static_assert(static_cast<size_t>(CryptoKeyUsage::UnwrapKey) == 7, "CryptoKeyUsage::UnwrapKey is not 7 as expected");
+ ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
+ return values[static_cast<size_t>(enumerationValue)];
+}
+
+template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject, CryptoKeyUsage enumerationValue)
+{
+ return jsStringWithCache(lexicalGlobalObject.vm(), convertEnumerationToString(enumerationValue));
+}
+
+template<> std::optional<CryptoKeyUsage> parseEnumeration<CryptoKeyUsage>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ auto stringValue = value.toWTFString(&lexicalGlobalObject);
+ static constexpr std::pair<ComparableASCIILiteral, CryptoKeyUsage> mappings[] = {
+ { "decrypt", CryptoKeyUsage::Decrypt },
+ { "deriveBits", CryptoKeyUsage::DeriveBits },
+ { "deriveKey", CryptoKeyUsage::DeriveKey },
+ { "encrypt", CryptoKeyUsage::Encrypt },
+ { "sign", CryptoKeyUsage::Sign },
+ { "unwrapKey", CryptoKeyUsage::UnwrapKey },
+ { "verify", CryptoKeyUsage::Verify },
+ { "wrapKey", CryptoKeyUsage::WrapKey },
+ };
+ static constexpr SortedArrayMap enumerationMapping { mappings };
+ if (auto* enumerationValue = enumerationMapping.tryGet(stringValue); LIKELY(enumerationValue))
+ return *enumerationValue;
+ return std::nullopt;
+}
+
+template<> const char* expectedEnumerationValues<CryptoKeyUsage>()
+{
+ return "\"encrypt\", \"decrypt\", \"sign\", \"verify\", \"deriveKey\", \"deriveBits\", \"wrapKey\", \"unwrapKey\"";
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoKeyUsage.h b/src/bun.js/bindings/webcrypto/JSCryptoKeyUsage.h
new file mode 100644
index 000000000..7119cf1d1
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoKeyUsage.h
@@ -0,0 +1,38 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoKeyUsage.h"
+#include "JSDOMConvertEnumeration.h"
+
+namespace WebCore {
+
+String convertEnumerationToString(CryptoKeyUsage);
+template<> JSC::JSString* convertEnumerationToJS(JSC::JSGlobalObject&, CryptoKeyUsage);
+
+template<> std::optional<CryptoKeyUsage> parseEnumeration<CryptoKeyUsage>(JSC::JSGlobalObject&, JSC::JSValue);
+template<> const char* expectedEnumerationValues<CryptoKeyUsage>();
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.cpp b/src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.cpp
new file mode 100644
index 000000000..2a2cdb8a2
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.cpp
@@ -0,0 +1,137 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoRsaHashedKeyAlgorithm.h"
+
+#include "JSCryptoKeyAlgorithm.h"
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMGlobalObject.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoRsaHashedKeyAlgorithm convertDictionary<CryptoRsaHashedKeyAlgorithm>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoRsaHashedKeyAlgorithm result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "CryptoRsaHashedKeyAlgorithm", "DOMString");
+ return { };
+ }
+ JSValue modulusLengthValue;
+ if (isNullOrUndefined)
+ modulusLengthValue = jsUndefined();
+ else {
+ modulusLengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "modulusLength"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!modulusLengthValue.isUndefined()) {
+ result.modulusLength = convert<IDLUnsignedLong>(lexicalGlobalObject, modulusLengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "modulusLength", "CryptoRsaHashedKeyAlgorithm", "unsigned long");
+ return { };
+ }
+ JSValue publicExponentValue;
+ if (isNullOrUndefined)
+ publicExponentValue = jsUndefined();
+ else {
+ publicExponentValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "publicExponent"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!publicExponentValue.isUndefined()) {
+ result.publicExponent = convert<IDLUint8Array>(lexicalGlobalObject, publicExponentValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "publicExponent", "CryptoRsaHashedKeyAlgorithm", "Uint8Array");
+ return { };
+ }
+ JSValue hashValue;
+ if (isNullOrUndefined)
+ hashValue = jsUndefined();
+ else {
+ hashValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hash"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!hashValue.isUndefined()) {
+ result.hash = convert<IDLDictionary<CryptoKeyAlgorithm>>(lexicalGlobalObject, hashValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "hash", "CryptoRsaHashedKeyAlgorithm", "CryptoKeyAlgorithm");
+ return { };
+ }
+ return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const CryptoRsaHashedKeyAlgorithm& dictionary)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
+
+ auto nameValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.name);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "name"_s), nameValue);
+ auto modulusLengthValue = toJS<IDLUnsignedLong>(lexicalGlobalObject, throwScope, dictionary.modulusLength);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "modulusLength"_s), modulusLengthValue);
+ auto publicExponentValue = toJS<IDLUint8Array>(lexicalGlobalObject, globalObject, throwScope, dictionary.publicExponent);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "publicExponent"_s), publicExponentValue);
+ auto hashValue = toJS<IDLDictionary<CryptoKeyAlgorithm>>(lexicalGlobalObject, globalObject, throwScope, dictionary.hash);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "hash"_s), hashValue);
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.dep b/src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.dep
new file mode 100644
index 000000000..360e6c612
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.dep
@@ -0,0 +1,3 @@
+CryptoRsaHashedKeyAlgorithm.h : CryptoRsaKeyAlgorithm.idl CryptoKeyAlgorithm.idl
+CryptoRsaKeyAlgorithm.idl :
+CryptoKeyAlgorithm.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.h
new file mode 100644
index 000000000..ef51231f4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoRsaHashedKeyAlgorithm.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoRsaHashedKeyAlgorithm.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoRsaHashedKeyAlgorithm convertDictionary<CryptoRsaHashedKeyAlgorithm>(JSC::JSGlobalObject&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const CryptoRsaHashedKeyAlgorithm&);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.cpp b/src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.cpp
new file mode 100644
index 000000000..79407e27f
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.cpp
@@ -0,0 +1,119 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSCryptoRsaKeyAlgorithm.h"
+
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMGlobalObject.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoRsaKeyAlgorithm convertDictionary<CryptoRsaKeyAlgorithm>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoRsaKeyAlgorithm result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "CryptoRsaKeyAlgorithm", "DOMString");
+ return { };
+ }
+ JSValue modulusLengthValue;
+ if (isNullOrUndefined)
+ modulusLengthValue = jsUndefined();
+ else {
+ modulusLengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "modulusLength"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!modulusLengthValue.isUndefined()) {
+ result.modulusLength = convert<IDLUnsignedLong>(lexicalGlobalObject, modulusLengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "modulusLength", "CryptoRsaKeyAlgorithm", "unsigned long");
+ return { };
+ }
+ JSValue publicExponentValue;
+ if (isNullOrUndefined)
+ publicExponentValue = jsUndefined();
+ else {
+ publicExponentValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "publicExponent"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!publicExponentValue.isUndefined()) {
+ result.publicExponent = convert<IDLUint8Array>(lexicalGlobalObject, publicExponentValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "publicExponent", "CryptoRsaKeyAlgorithm", "Uint8Array");
+ return { };
+ }
+ return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const CryptoRsaKeyAlgorithm& dictionary)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
+
+ auto nameValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.name);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "name"_s), nameValue);
+ auto modulusLengthValue = toJS<IDLUnsignedLong>(lexicalGlobalObject, throwScope, dictionary.modulusLength);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "modulusLength"_s), modulusLengthValue);
+ auto publicExponentValue = toJS<IDLUint8Array>(lexicalGlobalObject, globalObject, throwScope, dictionary.publicExponent);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "publicExponent"_s), publicExponentValue);
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.dep b/src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.dep
new file mode 100644
index 000000000..e907cd5f8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.dep
@@ -0,0 +1,2 @@
+CryptoRsaKeyAlgorithm.h : CryptoKeyAlgorithm.idl
+CryptoKeyAlgorithm.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.h b/src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.h
new file mode 100644
index 000000000..3adcf0132
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSCryptoRsaKeyAlgorithm.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoRsaKeyAlgorithm.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoRsaKeyAlgorithm convertDictionary<CryptoRsaKeyAlgorithm>(JSC::JSGlobalObject&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const CryptoRsaKeyAlgorithm&);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSEcKeyParams.cpp b/src/bun.js/bindings/webcrypto/JSEcKeyParams.cpp
new file mode 100644
index 000000000..51fcfb966
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSEcKeyParams.cpp
@@ -0,0 +1,82 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSEcKeyParams.h"
+
+#include "JSDOMConvertStrings.h"
+#include <JavaScriptCore/JSCInlines.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmEcKeyParams convertDictionary<CryptoAlgorithmEcKeyParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmEcKeyParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "EcKeyParams", "DOMString");
+ return { };
+ }
+ JSValue namedCurveValue;
+ if (isNullOrUndefined)
+ namedCurveValue = jsUndefined();
+ else {
+ namedCurveValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "namedCurve"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!namedCurveValue.isUndefined()) {
+ result.namedCurve = convert<IDLDOMString>(lexicalGlobalObject, namedCurveValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "namedCurve", "EcKeyParams", "DOMString");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSEcKeyParams.dep b/src/bun.js/bindings/webcrypto/JSEcKeyParams.dep
new file mode 100644
index 000000000..4735dd21b
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSEcKeyParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmEcKeyParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSEcKeyParams.h b/src/bun.js/bindings/webcrypto/JSEcKeyParams.h
new file mode 100644
index 000000000..b4e39fcea
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSEcKeyParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmEcKeyParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmEcKeyParams convertDictionary<CryptoAlgorithmEcKeyParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.cpp b/src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.cpp
new file mode 100644
index 000000000..9005a34ff
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.cpp
@@ -0,0 +1,84 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSEcdhKeyDeriveParams.h"
+
+#include "JSCryptoKey.h"
+#include "JSDOMConvertInterface.h"
+#include "JSDOMConvertStrings.h"
+#include <JavaScriptCore/JSCInlines.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmEcdhKeyDeriveParams convertDictionary<CryptoAlgorithmEcdhKeyDeriveParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmEcdhKeyDeriveParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "EcdhKeyDeriveParams", "DOMString");
+ return { };
+ }
+ JSValue publicKeyValue;
+ if (isNullOrUndefined)
+ publicKeyValue = jsUndefined();
+ else {
+ publicKeyValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "publicKey"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!publicKeyValue.isUndefined()) {
+ result.publicKey = convert<IDLInterface<CryptoKey>>(lexicalGlobalObject, publicKeyValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "publicKey", "EcdhKeyDeriveParams", "CryptoKey");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.dep b/src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.dep
new file mode 100644
index 000000000..5681b50bf
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmEcdhKeyDeriveParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.h b/src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.h
new file mode 100644
index 000000000..657b1ee31
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSEcdhKeyDeriveParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmEcdhKeyDeriveParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmEcdhKeyDeriveParams convertDictionary<CryptoAlgorithmEcdhKeyDeriveParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSEcdsaParams.cpp b/src/bun.js/bindings/webcrypto/JSEcdsaParams.cpp
new file mode 100644
index 000000000..700b30e6e
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSEcdsaParams.cpp
@@ -0,0 +1,85 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSEcdsaParams.h"
+
+#include "JSDOMConvertObject.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmEcdsaParams convertDictionary<CryptoAlgorithmEcdsaParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmEcdsaParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "EcdsaParams", "DOMString");
+ return { };
+ }
+ JSValue hashValue;
+ if (isNullOrUndefined)
+ hashValue = jsUndefined();
+ else {
+ hashValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hash"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!hashValue.isUndefined()) {
+ result.hash = convert<IDLUnion<IDLObject, IDLDOMString>>(lexicalGlobalObject, hashValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "hash", "EcdsaParams", "(object or DOMString)");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSEcdsaParams.dep b/src/bun.js/bindings/webcrypto/JSEcdsaParams.dep
new file mode 100644
index 000000000..294efafe8
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSEcdsaParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmEcdsaParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSEcdsaParams.h b/src/bun.js/bindings/webcrypto/JSEcdsaParams.h
new file mode 100644
index 000000000..b17bf046f
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSEcdsaParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmEcdsaParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmEcdsaParams convertDictionary<CryptoAlgorithmEcdsaParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSHkdfParams.cpp b/src/bun.js/bindings/webcrypto/JSHkdfParams.cpp
new file mode 100644
index 000000000..3b68fa3de
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSHkdfParams.cpp
@@ -0,0 +1,114 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSHkdfParams.h"
+
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertObject.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmHkdfParams convertDictionary<CryptoAlgorithmHkdfParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmHkdfParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "HkdfParams", "DOMString");
+ return { };
+ }
+ JSValue hashValue;
+ if (isNullOrUndefined)
+ hashValue = jsUndefined();
+ else {
+ hashValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hash"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!hashValue.isUndefined()) {
+ result.hash = convert<IDLUnion<IDLObject, IDLDOMString>>(lexicalGlobalObject, hashValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "hash", "HkdfParams", "(object or DOMString)");
+ return { };
+ }
+ JSValue infoValue;
+ if (isNullOrUndefined)
+ infoValue = jsUndefined();
+ else {
+ infoValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "info"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!infoValue.isUndefined()) {
+ result.info = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(lexicalGlobalObject, infoValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "info", "HkdfParams", "(ArrayBufferView or ArrayBuffer)");
+ return { };
+ }
+ JSValue saltValue;
+ if (isNullOrUndefined)
+ saltValue = jsUndefined();
+ else {
+ saltValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "salt"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!saltValue.isUndefined()) {
+ result.salt = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(lexicalGlobalObject, saltValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "salt", "HkdfParams", "(ArrayBufferView or ArrayBuffer)");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSHkdfParams.dep b/src/bun.js/bindings/webcrypto/JSHkdfParams.dep
new file mode 100644
index 000000000..bf1ae962f
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSHkdfParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmHkdfParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSHkdfParams.h b/src/bun.js/bindings/webcrypto/JSHkdfParams.h
new file mode 100644
index 000000000..76251ef07
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSHkdfParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmHkdfParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmHkdfParams convertDictionary<CryptoAlgorithmHkdfParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSHmacKeyParams.cpp b/src/bun.js/bindings/webcrypto/JSHmacKeyParams.cpp
new file mode 100644
index 000000000..2debe2409
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSHmacKeyParams.cpp
@@ -0,0 +1,97 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSHmacKeyParams.h"
+
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertObject.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmHmacKeyParams convertDictionary<CryptoAlgorithmHmacKeyParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmHmacKeyParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "HmacKeyParams", "DOMString");
+ return { };
+ }
+ JSValue hashValue;
+ if (isNullOrUndefined)
+ hashValue = jsUndefined();
+ else {
+ hashValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hash"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!hashValue.isUndefined()) {
+ result.hash = convert<IDLUnion<IDLObject, IDLDOMString>>(lexicalGlobalObject, hashValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "hash", "HmacKeyParams", "(object or DOMString)");
+ return { };
+ }
+ JSValue lengthValue;
+ if (isNullOrUndefined)
+ lengthValue = jsUndefined();
+ else {
+ lengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "length"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!lengthValue.isUndefined()) {
+ result.length = convert<IDLEnforceRangeAdaptor<IDLUnsignedLong>>(lexicalGlobalObject, lengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSHmacKeyParams.dep b/src/bun.js/bindings/webcrypto/JSHmacKeyParams.dep
new file mode 100644
index 000000000..fbf7eea2f
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSHmacKeyParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmHmacKeyParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSHmacKeyParams.h b/src/bun.js/bindings/webcrypto/JSHmacKeyParams.h
new file mode 100644
index 000000000..2d1c61f44
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSHmacKeyParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmHmacKeyParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmHmacKeyParams convertDictionary<CryptoAlgorithmHmacKeyParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSJsonWebKey.cpp b/src/bun.js/bindings/webcrypto/JSJsonWebKey.cpp
new file mode 100644
index 000000000..39ed1ff31
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSJsonWebKey.cpp
@@ -0,0 +1,361 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSJsonWebKey.h"
+
+#include "JSCryptoKeyUsage.h"
+#include "JSDOMConvertBoolean.h"
+#include "JSDOMConvertEnumeration.h"
+#include "JSDOMConvertSequences.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMGlobalObject.h"
+#include "JSRsaOtherPrimesInfo.h"
+#include <JavaScriptCore/JSArray.h>
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> JsonWebKey convertDictionary<JsonWebKey>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ JsonWebKey result;
+ JSValue algValue;
+ if (isNullOrUndefined)
+ algValue = jsUndefined();
+ else {
+ algValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "alg"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!algValue.isUndefined()) {
+ result.alg = convert<IDLDOMString>(lexicalGlobalObject, algValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue crvValue;
+ if (isNullOrUndefined)
+ crvValue = jsUndefined();
+ else {
+ crvValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "crv"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!crvValue.isUndefined()) {
+ result.crv = convert<IDLDOMString>(lexicalGlobalObject, crvValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue dValue;
+ if (isNullOrUndefined)
+ dValue = jsUndefined();
+ else {
+ dValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "d"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!dValue.isUndefined()) {
+ result.d = convert<IDLDOMString>(lexicalGlobalObject, dValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue dpValue;
+ if (isNullOrUndefined)
+ dpValue = jsUndefined();
+ else {
+ dpValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "dp"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!dpValue.isUndefined()) {
+ result.dp = convert<IDLDOMString>(lexicalGlobalObject, dpValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue dqValue;
+ if (isNullOrUndefined)
+ dqValue = jsUndefined();
+ else {
+ dqValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "dq"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!dqValue.isUndefined()) {
+ result.dq = convert<IDLDOMString>(lexicalGlobalObject, dqValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue eValue;
+ if (isNullOrUndefined)
+ eValue = jsUndefined();
+ else {
+ eValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "e"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!eValue.isUndefined()) {
+ result.e = convert<IDLDOMString>(lexicalGlobalObject, eValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue extValue;
+ if (isNullOrUndefined)
+ extValue = jsUndefined();
+ else {
+ extValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "ext"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!extValue.isUndefined()) {
+ result.ext = convert<IDLBoolean>(lexicalGlobalObject, extValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue kValue;
+ if (isNullOrUndefined)
+ kValue = jsUndefined();
+ else {
+ kValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "k"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!kValue.isUndefined()) {
+ result.k = convert<IDLDOMString>(lexicalGlobalObject, kValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue key_opsValue;
+ if (isNullOrUndefined)
+ key_opsValue = jsUndefined();
+ else {
+ key_opsValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "key_ops"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!key_opsValue.isUndefined()) {
+ result.key_ops = convert<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(lexicalGlobalObject, key_opsValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue ktyValue;
+ if (isNullOrUndefined)
+ ktyValue = jsUndefined();
+ else {
+ ktyValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "kty"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!ktyValue.isUndefined()) {
+ result.kty = convert<IDLDOMString>(lexicalGlobalObject, ktyValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "kty", "JsonWebKey", "DOMString");
+ return { };
+ }
+ JSValue nValue;
+ if (isNullOrUndefined)
+ nValue = jsUndefined();
+ else {
+ nValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "n"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nValue.isUndefined()) {
+ result.n = convert<IDLDOMString>(lexicalGlobalObject, nValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue othValue;
+ if (isNullOrUndefined)
+ othValue = jsUndefined();
+ else {
+ othValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "oth"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!othValue.isUndefined()) {
+ result.oth = convert<IDLSequence<IDLDictionary<RsaOtherPrimesInfo>>>(lexicalGlobalObject, othValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue pValue;
+ if (isNullOrUndefined)
+ pValue = jsUndefined();
+ else {
+ pValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "p"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!pValue.isUndefined()) {
+ result.p = convert<IDLDOMString>(lexicalGlobalObject, pValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue qValue;
+ if (isNullOrUndefined)
+ qValue = jsUndefined();
+ else {
+ qValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "q"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!qValue.isUndefined()) {
+ result.q = convert<IDLDOMString>(lexicalGlobalObject, qValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue qiValue;
+ if (isNullOrUndefined)
+ qiValue = jsUndefined();
+ else {
+ qiValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "qi"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!qiValue.isUndefined()) {
+ result.qi = convert<IDLDOMString>(lexicalGlobalObject, qiValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue useValue;
+ if (isNullOrUndefined)
+ useValue = jsUndefined();
+ else {
+ useValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "use"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!useValue.isUndefined()) {
+ result.use = convert<IDLDOMString>(lexicalGlobalObject, useValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue xValue;
+ if (isNullOrUndefined)
+ xValue = jsUndefined();
+ else {
+ xValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "x"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!xValue.isUndefined()) {
+ result.x = convert<IDLDOMString>(lexicalGlobalObject, xValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ JSValue yValue;
+ if (isNullOrUndefined)
+ yValue = jsUndefined();
+ else {
+ yValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "y"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!yValue.isUndefined()) {
+ result.y = convert<IDLDOMString>(lexicalGlobalObject, yValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const JsonWebKey& dictionary)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
+
+ if (!IDLDOMString::isNullValue(dictionary.alg)) {
+ auto algValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.alg));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "alg"_s), algValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.crv)) {
+ auto crvValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.crv));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "crv"_s), crvValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.d)) {
+ auto dValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.d));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "d"_s), dValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.dp)) {
+ auto dpValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.dp));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "dp"_s), dpValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.dq)) {
+ auto dqValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.dq));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "dq"_s), dqValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.e)) {
+ auto eValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.e));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "e"_s), eValue);
+ }
+ if (!IDLBoolean::isNullValue(dictionary.ext)) {
+ auto extValue = toJS<IDLBoolean>(lexicalGlobalObject, throwScope, IDLBoolean::extractValueFromNullable(dictionary.ext));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "ext"_s), extValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.k)) {
+ auto kValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.k));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "k"_s), kValue);
+ }
+ if (!IDLSequence<IDLEnumeration<CryptoKeyUsage>>::isNullValue(dictionary.key_ops)) {
+ auto key_opsValue = toJS<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(lexicalGlobalObject, globalObject, throwScope, IDLSequence<IDLEnumeration<CryptoKeyUsage>>::extractValueFromNullable(dictionary.key_ops));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "key_ops"_s), key_opsValue);
+ }
+ auto ktyValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.kty);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "kty"_s), ktyValue);
+ if (!IDLDOMString::isNullValue(dictionary.n)) {
+ auto nValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.n));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "n"_s), nValue);
+ }
+ if (!IDLSequence<IDLDictionary<RsaOtherPrimesInfo>>::isNullValue(dictionary.oth)) {
+ auto othValue = toJS<IDLSequence<IDLDictionary<RsaOtherPrimesInfo>>>(lexicalGlobalObject, globalObject, throwScope, IDLSequence<IDLDictionary<RsaOtherPrimesInfo>>::extractValueFromNullable(dictionary.oth));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "oth"_s), othValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.p)) {
+ auto pValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.p));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "p"_s), pValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.q)) {
+ auto qValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.q));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "q"_s), qValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.qi)) {
+ auto qiValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.qi));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "qi"_s), qiValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.use)) {
+ auto useValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.use));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "use"_s), useValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.x)) {
+ auto xValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.x));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "x"_s), xValue);
+ }
+ if (!IDLDOMString::isNullValue(dictionary.y)) {
+ auto yValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, IDLDOMString::extractValueFromNullable(dictionary.y));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "y"_s), yValue);
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSJsonWebKey.dep b/src/bun.js/bindings/webcrypto/JSJsonWebKey.dep
new file mode 100644
index 000000000..c68f31aca
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSJsonWebKey.dep
@@ -0,0 +1 @@
+JsonWebKey.h :
diff --git a/src/bun.js/bindings/webcrypto/JSJsonWebKey.h b/src/bun.js/bindings/webcrypto/JSJsonWebKey.h
new file mode 100644
index 000000000..07e7960be
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSJsonWebKey.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSDOMConvertDictionary.h"
+#include "JsonWebKey.h"
+
+namespace WebCore {
+
+template<> JsonWebKey convertDictionary<JsonWebKey>(JSC::JSGlobalObject&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const JsonWebKey&);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSPbkdf2Params.cpp b/src/bun.js/bindings/webcrypto/JSPbkdf2Params.cpp
new file mode 100644
index 000000000..871d8ffd9
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSPbkdf2Params.cpp
@@ -0,0 +1,115 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSPbkdf2Params.h"
+
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertObject.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmPbkdf2Params convertDictionary<CryptoAlgorithmPbkdf2Params>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmPbkdf2Params result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "Pbkdf2Params", "DOMString");
+ return { };
+ }
+ JSValue hashValue;
+ if (isNullOrUndefined)
+ hashValue = jsUndefined();
+ else {
+ hashValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hash"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!hashValue.isUndefined()) {
+ result.hash = convert<IDLUnion<IDLObject, IDLDOMString>>(lexicalGlobalObject, hashValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "hash", "Pbkdf2Params", "(object or DOMString)");
+ return { };
+ }
+ JSValue iterationsValue;
+ if (isNullOrUndefined)
+ iterationsValue = jsUndefined();
+ else {
+ iterationsValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "iterations"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!iterationsValue.isUndefined()) {
+ result.iterations = convert<IDLEnforceRangeAdaptor<IDLUnsignedLong>>(lexicalGlobalObject, iterationsValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "iterations", "Pbkdf2Params", "unsigned long");
+ return { };
+ }
+ JSValue saltValue;
+ if (isNullOrUndefined)
+ saltValue = jsUndefined();
+ else {
+ saltValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "salt"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!saltValue.isUndefined()) {
+ result.salt = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(lexicalGlobalObject, saltValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "salt", "Pbkdf2Params", "(ArrayBufferView or ArrayBuffer)");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSPbkdf2Params.dep b/src/bun.js/bindings/webcrypto/JSPbkdf2Params.dep
new file mode 100644
index 000000000..c950639a4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSPbkdf2Params.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmPbkdf2Params.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSPbkdf2Params.h b/src/bun.js/bindings/webcrypto/JSPbkdf2Params.h
new file mode 100644
index 000000000..176e91b79
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSPbkdf2Params.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmPbkdf2Params.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmPbkdf2Params convertDictionary<CryptoAlgorithmPbkdf2Params>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.cpp b/src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.cpp
new file mode 100644
index 000000000..e48fba0fd
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.cpp
@@ -0,0 +1,85 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSRsaHashedImportParams.h"
+
+#include "JSDOMConvertObject.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmRsaHashedImportParams convertDictionary<CryptoAlgorithmRsaHashedImportParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmRsaHashedImportParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "RsaHashedImportParams", "DOMString");
+ return { };
+ }
+ JSValue hashValue;
+ if (isNullOrUndefined)
+ hashValue = jsUndefined();
+ else {
+ hashValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hash"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!hashValue.isUndefined()) {
+ result.hash = convert<IDLUnion<IDLObject, IDLDOMString>>(lexicalGlobalObject, hashValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "hash", "RsaHashedImportParams", "(object or DOMString)");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.dep b/src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.dep
new file mode 100644
index 000000000..7a7393d6e
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmRsaHashedImportParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.h b/src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.h
new file mode 100644
index 000000000..116bceb04
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaHashedImportParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRsaHashedImportParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmRsaHashedImportParams convertDictionary<CryptoAlgorithmRsaHashedImportParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.cpp b/src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.cpp
new file mode 100644
index 000000000..c5abfe52a
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.cpp
@@ -0,0 +1,115 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSRsaHashedKeyGenParams.h"
+
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertObject.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmRsaHashedKeyGenParams convertDictionary<CryptoAlgorithmRsaHashedKeyGenParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmRsaHashedKeyGenParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "RsaHashedKeyGenParams", "DOMString");
+ return { };
+ }
+ JSValue modulusLengthValue;
+ if (isNullOrUndefined)
+ modulusLengthValue = jsUndefined();
+ else {
+ modulusLengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "modulusLength"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!modulusLengthValue.isUndefined()) {
+ result.modulusLength = convert<IDLEnforceRangeAdaptor<IDLUnsignedLong>>(lexicalGlobalObject, modulusLengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "modulusLength", "RsaHashedKeyGenParams", "unsigned long");
+ return { };
+ }
+ JSValue publicExponentValue;
+ if (isNullOrUndefined)
+ publicExponentValue = jsUndefined();
+ else {
+ publicExponentValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "publicExponent"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!publicExponentValue.isUndefined()) {
+ result.publicExponent = convert<IDLUint8Array>(lexicalGlobalObject, publicExponentValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "publicExponent", "RsaHashedKeyGenParams", "Uint8Array");
+ return { };
+ }
+ JSValue hashValue;
+ if (isNullOrUndefined)
+ hashValue = jsUndefined();
+ else {
+ hashValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hash"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!hashValue.isUndefined()) {
+ result.hash = convert<IDLUnion<IDLObject, IDLDOMString>>(lexicalGlobalObject, hashValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "hash", "RsaHashedKeyGenParams", "(object or DOMString)");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.dep b/src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.dep
new file mode 100644
index 000000000..788f8828b
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.dep
@@ -0,0 +1,3 @@
+CryptoAlgorithmRsaHashedKeyGenParams.h : RsaKeyGenParams.idl CryptoAlgorithmParameters.idl
+RsaKeyGenParams.idl :
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.h b/src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.h
new file mode 100644
index 000000000..30e9075e4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaHashedKeyGenParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRsaHashedKeyGenParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmRsaHashedKeyGenParams convertDictionary<CryptoAlgorithmRsaHashedKeyGenParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.cpp b/src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.cpp
new file mode 100644
index 000000000..54644978a
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.cpp
@@ -0,0 +1,98 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSRsaKeyGenParams.h"
+
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include <JavaScriptCore/JSCInlines.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmRsaKeyGenParams convertDictionary<CryptoAlgorithmRsaKeyGenParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmRsaKeyGenParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "RsaKeyGenParams", "DOMString");
+ return { };
+ }
+ JSValue modulusLengthValue;
+ if (isNullOrUndefined)
+ modulusLengthValue = jsUndefined();
+ else {
+ modulusLengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "modulusLength"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!modulusLengthValue.isUndefined()) {
+ result.modulusLength = convert<IDLEnforceRangeAdaptor<IDLUnsignedLong>>(lexicalGlobalObject, modulusLengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "modulusLength", "RsaKeyGenParams", "unsigned long");
+ return { };
+ }
+ JSValue publicExponentValue;
+ if (isNullOrUndefined)
+ publicExponentValue = jsUndefined();
+ else {
+ publicExponentValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "publicExponent"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!publicExponentValue.isUndefined()) {
+ result.publicExponent = convert<IDLUint8Array>(lexicalGlobalObject, publicExponentValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "publicExponent", "RsaKeyGenParams", "Uint8Array");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.dep b/src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.dep
new file mode 100644
index 000000000..228557474
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmRsaKeyGenParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.h b/src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.h
new file mode 100644
index 000000000..5ed39bcff
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaKeyGenParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRsaKeyGenParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmRsaKeyGenParams convertDictionary<CryptoAlgorithmRsaKeyGenParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaOaepParams.cpp b/src/bun.js/bindings/webcrypto/JSRsaOaepParams.cpp
new file mode 100644
index 000000000..16264b7d9
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaOaepParams.cpp
@@ -0,0 +1,82 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSRsaOaepParams.h"
+
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <variant>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmRsaOaepParams convertDictionary<CryptoAlgorithmRsaOaepParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmRsaOaepParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "RsaOaepParams", "DOMString");
+ return { };
+ }
+ JSValue labelValue;
+ if (isNullOrUndefined)
+ labelValue = jsUndefined();
+ else {
+ labelValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "label"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!labelValue.isUndefined()) {
+ result.label = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(lexicalGlobalObject, labelValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaOaepParams.dep b/src/bun.js/bindings/webcrypto/JSRsaOaepParams.dep
new file mode 100644
index 000000000..1380355f2
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaOaepParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmRsaOaepParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSRsaOaepParams.h b/src/bun.js/bindings/webcrypto/JSRsaOaepParams.h
new file mode 100644
index 000000000..049a11cf0
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaOaepParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRsaOaepParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmRsaOaepParams convertDictionary<CryptoAlgorithmRsaOaepParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.cpp b/src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.cpp
new file mode 100644
index 000000000..420e17fb4
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.cpp
@@ -0,0 +1,117 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSRsaOtherPrimesInfo.h"
+
+#include "JSDOMConvertStrings.h"
+#include "JSDOMGlobalObject.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> RsaOtherPrimesInfo convertDictionary<RsaOtherPrimesInfo>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ RsaOtherPrimesInfo result;
+ JSValue dValue;
+ if (isNullOrUndefined)
+ dValue = jsUndefined();
+ else {
+ dValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "d"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!dValue.isUndefined()) {
+ result.d = convert<IDLDOMString>(lexicalGlobalObject, dValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "d", "RsaOtherPrimesInfo", "DOMString");
+ return { };
+ }
+ JSValue rValue;
+ if (isNullOrUndefined)
+ rValue = jsUndefined();
+ else {
+ rValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "r"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!rValue.isUndefined()) {
+ result.r = convert<IDLDOMString>(lexicalGlobalObject, rValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "r", "RsaOtherPrimesInfo", "DOMString");
+ return { };
+ }
+ JSValue tValue;
+ if (isNullOrUndefined)
+ tValue = jsUndefined();
+ else {
+ tValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "t"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!tValue.isUndefined()) {
+ result.t = convert<IDLDOMString>(lexicalGlobalObject, tValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "t", "RsaOtherPrimesInfo", "DOMString");
+ return { };
+ }
+ return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const RsaOtherPrimesInfo& dictionary)
+{
+ auto& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
+
+ auto dValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.d);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "d"_s), dValue);
+ auto rValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.r);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "r"_s), rValue);
+ auto tValue = toJS<IDLDOMString>(lexicalGlobalObject, throwScope, dictionary.t);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ result->putDirect(vm, JSC::Identifier::fromString(vm, "t"_s), tValue);
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.dep b/src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.dep
new file mode 100644
index 000000000..ca7765d12
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.dep
@@ -0,0 +1 @@
+RsaOtherPrimesInfo.h :
diff --git a/src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.h b/src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.h
new file mode 100644
index 000000000..2f8fa46f2
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaOtherPrimesInfo.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSDOMConvertDictionary.h"
+#include "RsaOtherPrimesInfo.h"
+
+namespace WebCore {
+
+template<> RsaOtherPrimesInfo convertDictionary<RsaOtherPrimesInfo>(JSC::JSGlobalObject&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const RsaOtherPrimesInfo&);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaPssParams.cpp b/src/bun.js/bindings/webcrypto/JSRsaPssParams.cpp
new file mode 100644
index 000000000..3498ec0e9
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaPssParams.cpp
@@ -0,0 +1,83 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSRsaPssParams.h"
+
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include <JavaScriptCore/JSCInlines.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+#if ENABLE(WEB_CRYPTO)
+
+template<> CryptoAlgorithmRsaPssParams convertDictionary<CryptoAlgorithmRsaPssParams>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ VM& vm = JSC::getVM(&lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ bool isNullOrUndefined = value.isUndefinedOrNull();
+ auto* object = isNullOrUndefined ? nullptr : value.getObject();
+ if (UNLIKELY(!isNullOrUndefined && !object)) {
+ throwTypeError(&lexicalGlobalObject, throwScope);
+ return { };
+ }
+ CryptoAlgorithmRsaPssParams result;
+ JSValue nameValue;
+ if (isNullOrUndefined)
+ nameValue = jsUndefined();
+ else {
+ nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!nameValue.isUndefined()) {
+ result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "name", "RsaPssParams", "DOMString");
+ return { };
+ }
+ JSValue saltLengthValue;
+ if (isNullOrUndefined)
+ saltLengthValue = jsUndefined();
+ else {
+ saltLengthValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "saltLength"_s));
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ if (!saltLengthValue.isUndefined()) {
+ result.saltLength = convert<IDLEnforceRangeAdaptor<IDLUnsignedLong>>(lexicalGlobalObject, saltLengthValue);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ } else {
+ throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "saltLength", "RsaPssParams", "unsigned long");
+ return { };
+ }
+ return result;
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSRsaPssParams.dep b/src/bun.js/bindings/webcrypto/JSRsaPssParams.dep
new file mode 100644
index 000000000..a23b9a774
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaPssParams.dep
@@ -0,0 +1,2 @@
+CryptoAlgorithmRsaPssParams.h : CryptoAlgorithmParameters.idl
+CryptoAlgorithmParameters.idl :
diff --git a/src/bun.js/bindings/webcrypto/JSRsaPssParams.h b/src/bun.js/bindings/webcrypto/JSRsaPssParams.h
new file mode 100644
index 000000000..85013f028
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSRsaPssParams.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithmRsaPssParams.h"
+#include "JSDOMConvertDictionary.h"
+
+namespace WebCore {
+
+template<> CryptoAlgorithmRsaPssParams convertDictionary<CryptoAlgorithmRsaPssParams>(JSC::JSGlobalObject&, JSC::JSValue);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSSubtleCrypto.cpp b/src/bun.js/bindings/webcrypto/JSSubtleCrypto.cpp
new file mode 100644
index 000000000..66dddf20e
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSSubtleCrypto.cpp
@@ -0,0 +1,678 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSSubtleCrypto.h"
+
+#include "ActiveDOMObject.h"
+#include "DOMPromiseProxy.h"
+#include "ExtendedDOMClientIsoSubspaces.h"
+#include "ExtendedDOMIsoSubspaces.h"
+#include "JSCryptoKey.h"
+#include "JSCryptoKeyUsage.h"
+#include "JSDOMBinding.h"
+#include "JSDOMConstructorNotConstructable.h"
+#include "JSDOMConvertAny.h"
+#include "JSDOMConvertBoolean.h"
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertDictionary.h"
+#include "JSDOMConvertInterface.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertObject.h"
+#include "JSDOMConvertPromise.h"
+#include "JSDOMConvertSequences.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include "JSDOMExceptionHandling.h"
+#include "JSDOMGlobalObject.h"
+#include "JSDOMGlobalObjectInlines.h"
+#include "JSDOMOperation.h"
+#include "JSDOMOperationReturningPromise.h"
+#include "JSDOMWrapperCache.h"
+#include "JSJsonWebKey.h"
+#include "ScriptExecutionContext.h"
+#include "WebCoreJSClientData.h"
+#include "WebCoreOpaqueRoot.h"
+#include <JavaScriptCore/FunctionPrototype.h>
+#include <JavaScriptCore/HeapAnalyzer.h>
+#include <JavaScriptCore/JSArray.h>
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
+#include <JavaScriptCore/JSString.h>
+#include <JavaScriptCore/SlotVisitorMacros.h>
+#include <JavaScriptCore/SubspaceInlines.h>
+#include <variant>
+#include <wtf/GetPtr.h>
+#include <wtf/PointerPreparations.h>
+#include <wtf/SortedArrayMap.h>
+#include <wtf/URL.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+String convertEnumerationToString(SubtleCrypto::KeyFormat enumerationValue)
+{
+ static const NeverDestroyed<String> values[] = {
+ MAKE_STATIC_STRING_IMPL("raw"),
+ MAKE_STATIC_STRING_IMPL("spki"),
+ MAKE_STATIC_STRING_IMPL("pkcs8"),
+ MAKE_STATIC_STRING_IMPL("jwk"),
+ };
+ static_assert(static_cast<size_t>(SubtleCrypto::KeyFormat::Raw) == 0, "SubtleCrypto::KeyFormat::Raw is not 0 as expected");
+ static_assert(static_cast<size_t>(SubtleCrypto::KeyFormat::Spki) == 1, "SubtleCrypto::KeyFormat::Spki is not 1 as expected");
+ static_assert(static_cast<size_t>(SubtleCrypto::KeyFormat::Pkcs8) == 2, "SubtleCrypto::KeyFormat::Pkcs8 is not 2 as expected");
+ static_assert(static_cast<size_t>(SubtleCrypto::KeyFormat::Jwk) == 3, "SubtleCrypto::KeyFormat::Jwk is not 3 as expected");
+ ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
+ return values[static_cast<size_t>(enumerationValue)];
+}
+
+template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject, SubtleCrypto::KeyFormat enumerationValue)
+{
+ return jsStringWithCache(lexicalGlobalObject.vm(), convertEnumerationToString(enumerationValue));
+}
+
+template<> std::optional<SubtleCrypto::KeyFormat> parseEnumeration<SubtleCrypto::KeyFormat>(JSGlobalObject& lexicalGlobalObject, JSValue value)
+{
+ auto stringValue = value.toWTFString(&lexicalGlobalObject);
+ static constexpr std::pair<ComparableASCIILiteral, SubtleCrypto::KeyFormat> mappings[] = {
+ { "jwk", SubtleCrypto::KeyFormat::Jwk },
+ { "pkcs8", SubtleCrypto::KeyFormat::Pkcs8 },
+ { "raw", SubtleCrypto::KeyFormat::Raw },
+ { "spki", SubtleCrypto::KeyFormat::Spki },
+ };
+ static constexpr SortedArrayMap enumerationMapping { mappings };
+ if (auto* enumerationValue = enumerationMapping.tryGet(stringValue); LIKELY(enumerationValue))
+ return *enumerationValue;
+ return std::nullopt;
+}
+
+template<> const char* expectedEnumerationValues<SubtleCrypto::KeyFormat>()
+{
+ return "\"raw\", \"spki\", \"pkcs8\", \"jwk\"";
+}
+
+// Functions
+
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_encrypt);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_decrypt);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_sign);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_verify);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_digest);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_generateKey);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_deriveKey);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_deriveBits);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_importKey);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_exportKey);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_wrapKey);
+static JSC_DECLARE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_unwrapKey);
+
+// Attributes
+
+static JSC_DECLARE_CUSTOM_GETTER(jsSubtleCryptoConstructor);
+
+class JSSubtleCryptoPrototype final : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+ static JSSubtleCryptoPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ JSSubtleCryptoPrototype* ptr = new (NotNull, JSC::allocateCell<JSSubtleCryptoPrototype>(vm)) JSSubtleCryptoPrototype(vm, globalObject, structure);
+ ptr->finishCreation(vm);
+ return ptr;
+ }
+
+ DECLARE_INFO;
+ template<typename CellType, JSC::SubspaceAccess>
+ static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSSubtleCryptoPrototype, Base);
+ return &vm.plainObjectSpace();
+ }
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+private:
+ JSSubtleCryptoPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+ : JSC::JSNonFinalObject(vm, structure)
+ {
+ }
+
+ void finishCreation(JSC::VM&);
+};
+STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSSubtleCryptoPrototype, JSSubtleCryptoPrototype::Base);
+
+using JSSubtleCryptoDOMConstructor = JSDOMConstructorNotConstructable<JSSubtleCrypto>;
+
+template<> const ClassInfo JSSubtleCryptoDOMConstructor::s_info = { "SubtleCrypto"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSubtleCryptoDOMConstructor) };
+
+template<> JSValue JSSubtleCryptoDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
+{
+ UNUSED_PARAM(vm);
+ return globalObject.functionPrototype();
+}
+
+template<> void JSSubtleCryptoDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+ JSString* nameString = jsNontrivialString(vm, "SubtleCrypto"_s);
+ m_originalName.set(vm, this, nameString);
+ putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+ putDirect(vm, vm.propertyNames->prototype, JSSubtleCrypto::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
+}
+
+/* Hash table for prototype */
+
+static const HashTableValue JSSubtleCryptoPrototypeTableValues[] =
+{
+ { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsSubtleCryptoConstructor, 0 } },
+ { "encrypt"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_encrypt, 3 } },
+ { "decrypt"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_decrypt, 3 } },
+ { "sign"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_sign, 3 } },
+ { "verify"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_verify, 4 } },
+ { "digest"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_digest, 2 } },
+ { "generateKey"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_generateKey, 3 } },
+ { "deriveKey"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_deriveKey, 5 } },
+ { "deriveBits"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_deriveBits, 3 } },
+ { "importKey"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_importKey, 5 } },
+ { "exportKey"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_exportKey, 2 } },
+ { "wrapKey"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_wrapKey, 4 } },
+ { "unwrapKey"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsSubtleCryptoPrototypeFunction_unwrapKey, 7 } },
+};
+
+const ClassInfo JSSubtleCryptoPrototype::s_info = { "SubtleCrypto"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSubtleCryptoPrototype) };
+
+void JSSubtleCryptoPrototype::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ reifyStaticProperties(vm, JSSubtleCrypto::info(), JSSubtleCryptoPrototypeTableValues, *this);
+ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+}
+
+const ClassInfo JSSubtleCrypto::s_info = { "SubtleCrypto"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSubtleCrypto) };
+
+JSSubtleCrypto::JSSubtleCrypto(Structure* structure, JSDOMGlobalObject& globalObject, Ref<SubtleCrypto>&& impl)
+ : JSDOMWrapper<SubtleCrypto>(structure, globalObject, WTFMove(impl))
+{
+}
+
+void JSSubtleCrypto::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+
+ // static_assert(!std::is_base_of<ActiveDOMObject, SubtleCrypto>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
+
+}
+
+JSObject* JSSubtleCrypto::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return JSSubtleCryptoPrototype::create(vm, &globalObject, JSSubtleCryptoPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+JSObject* JSSubtleCrypto::prototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+ return getDOMPrototype<JSSubtleCrypto>(vm, globalObject);
+}
+
+JSValue JSSubtleCrypto::getConstructor(VM& vm, const JSGlobalObject* globalObject)
+{
+ return getDOMConstructor<JSSubtleCryptoDOMConstructor, DOMConstructorID::SubtleCrypto>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
+}
+
+void JSSubtleCrypto::destroy(JSC::JSCell* cell)
+{
+ JSSubtleCrypto* thisObject = static_cast<JSSubtleCrypto*>(cell);
+ thisObject->JSSubtleCrypto::~JSSubtleCrypto();
+}
+
+JSC_DEFINE_CUSTOM_GETTER(jsSubtleCryptoConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
+{
+ VM& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto* prototype = jsDynamicCast<JSSubtleCryptoPrototype*>(JSValue::decode(thisValue));
+ if (UNLIKELY(!prototype))
+ return throwVMTypeError(lexicalGlobalObject, throwScope);
+ return JSValue::encode(JSSubtleCrypto::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_encryptBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 3))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument0.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto key = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 1, "key", "SubtleCrypto", "encrypt", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*lexicalGlobalObject, argument2.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLAny>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.encrypt(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(algorithm), *key, WTFMove(data), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_encrypt, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_encryptBody>(*lexicalGlobalObject, *callFrame, "encrypt");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_decryptBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 3))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument0.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto key = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 1, "key", "SubtleCrypto", "decrypt", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*lexicalGlobalObject, argument2.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLAny>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.decrypt(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(algorithm), *key, WTFMove(data), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_decrypt, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_decryptBody>(*lexicalGlobalObject, *callFrame, "decrypt");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_signBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 3))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument0.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto key = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 1, "key", "SubtleCrypto", "sign", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*lexicalGlobalObject, argument2.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLAny>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.sign(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(algorithm), *key, WTFMove(data), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_sign, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_signBody>(*lexicalGlobalObject, *callFrame, "sign");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_verifyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 4))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument0.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto key = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 1, "key", "SubtleCrypto", "verify", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto signature = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*lexicalGlobalObject, argument2.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument3 = callFrame->uncheckedArgument(3);
+ auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*lexicalGlobalObject, argument3.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLAny>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.verify(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(algorithm), *key, WTFMove(signature), WTFMove(data), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_verify, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_verifyBody>(*lexicalGlobalObject, *callFrame, "verify");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_digestBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 2))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument0.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto data = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*lexicalGlobalObject, argument1.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLAny>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.digest(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(algorithm), WTFMove(data), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_digest, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_digestBody>(*lexicalGlobalObject, *callFrame, "digest");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_generateKeyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 3))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument0.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto extractable = convert<IDLBoolean>(*lexicalGlobalObject, argument1.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto keyUsages = convert<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(*lexicalGlobalObject, argument2.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLAny>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.generateKey(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(algorithm), WTFMove(extractable), WTFMove(keyUsages), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_generateKey, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_generateKeyBody>(*lexicalGlobalObject, *callFrame, "generateKey");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_deriveKeyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 5))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument0.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto baseKey = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 1, "baseKey", "SubtleCrypto", "deriveKey", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto derivedKeyType = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument2.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument3 = callFrame->uncheckedArgument(3);
+ auto extractable = convert<IDLBoolean>(*lexicalGlobalObject, argument3.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument4 = callFrame->uncheckedArgument(4);
+ auto keyUsages = convert<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(*lexicalGlobalObject, argument4.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLAny>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.deriveKey(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(algorithm), *baseKey, WTFMove(derivedKeyType), WTFMove(extractable), WTFMove(keyUsages), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_deriveKey, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_deriveKeyBody>(*lexicalGlobalObject, *callFrame, "deriveKey");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_deriveBitsBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 3))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument0.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto baseKey = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 1, "baseKey", "SubtleCrypto", "deriveBits", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto length = convert<IDLUnsignedLong>(*lexicalGlobalObject, argument2.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLArrayBuffer>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.deriveBits(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(algorithm), *baseKey, WTFMove(length), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_deriveBits, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_deriveBitsBody>(*lexicalGlobalObject, *callFrame, "deriveBits");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_importKeyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 5))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto format = convert<IDLEnumeration<SubtleCrypto::KeyFormat>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentMustBeEnumError(lexicalGlobalObject, scope, 0, "format", "SubtleCrypto", "importKey", expectedEnumerationValues<SubtleCrypto::KeyFormat>()); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto keyData = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer, IDLDictionary<JsonWebKey>>>(*lexicalGlobalObject, argument1.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto algorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument2.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument3 = callFrame->uncheckedArgument(3);
+ auto extractable = convert<IDLBoolean>(*lexicalGlobalObject, argument3.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument4 = callFrame->uncheckedArgument(4);
+ auto keyUsages = convert<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(*lexicalGlobalObject, argument4.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLInterface<CryptoKey>>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.importKey(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(format), WTFMove(keyData), WTFMove(algorithm), WTFMove(extractable), WTFMove(keyUsages), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_importKey, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_importKeyBody>(*lexicalGlobalObject, *callFrame, "importKey");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_exportKeyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 2))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto format = convert<IDLEnumeration<SubtleCrypto::KeyFormat>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentMustBeEnumError(lexicalGlobalObject, scope, 0, "format", "SubtleCrypto", "exportKey", expectedEnumerationValues<SubtleCrypto::KeyFormat>()); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto key = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 1, "key", "SubtleCrypto", "exportKey", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLAny>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.exportKey(WTFMove(format), *key, WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_exportKey, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_exportKeyBody>(*lexicalGlobalObject, *callFrame, "exportKey");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_wrapKeyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 4))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto format = convert<IDLEnumeration<SubtleCrypto::KeyFormat>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentMustBeEnumError(lexicalGlobalObject, scope, 0, "format", "SubtleCrypto", "wrapKey", expectedEnumerationValues<SubtleCrypto::KeyFormat>()); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto key = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 1, "key", "SubtleCrypto", "wrapKey", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto wrappingKey = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument2.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 2, "wrappingKey", "SubtleCrypto", "wrapKey", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument3 = callFrame->uncheckedArgument(3);
+ auto wrapAlgorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument3.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLAny>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.wrapKey(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(format), *key, *wrappingKey, WTFMove(wrapAlgorithm), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_wrapKey, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_wrapKeyBody>(*lexicalGlobalObject, *callFrame, "wrapKey");
+}
+
+static inline JSC::EncodedJSValue jsSubtleCryptoPrototypeFunction_unwrapKeyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSSubtleCrypto>::ClassParameter castedThis, Ref<DeferredPromise>&& promise)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ UNUSED_PARAM(callFrame);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(callFrame->argumentCount() < 7))
+ return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+ EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
+ auto format = convert<IDLEnumeration<SubtleCrypto::KeyFormat>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentMustBeEnumError(lexicalGlobalObject, scope, 0, "format", "SubtleCrypto", "unwrapKey", expectedEnumerationValues<SubtleCrypto::KeyFormat>()); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
+ auto wrappedKey = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*lexicalGlobalObject, argument1.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument2 = callFrame->uncheckedArgument(2);
+ auto unwrappingKey = convert<IDLInterface<CryptoKey>>(*lexicalGlobalObject, argument2.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 2, "unwrappingKey", "SubtleCrypto", "unwrapKey", "CryptoKey"); });
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument3 = callFrame->uncheckedArgument(3);
+ auto unwrapAlgorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument3.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument4 = callFrame->uncheckedArgument(4);
+ auto unwrappedKeyAlgorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument4.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument5 = callFrame->uncheckedArgument(5);
+ auto extractable = convert<IDLBoolean>(*lexicalGlobalObject, argument5.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ EnsureStillAliveScope argument6 = callFrame->uncheckedArgument(6);
+ auto keyUsages = convert<IDLSequence<IDLEnumeration<CryptoKeyUsage>>>(*lexicalGlobalObject, argument6.value());
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLInterface<CryptoKey>>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.unwrapKey(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(format), WTFMove(wrappedKey), *unwrappingKey, WTFMove(unwrapAlgorithm), WTFMove(unwrappedKeyAlgorithm), WTFMove(extractable), WTFMove(keyUsages), WTFMove(promise)); })));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsSubtleCryptoPrototypeFunction_unwrapKey, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
+{
+ return IDLOperationReturningPromise<JSSubtleCrypto>::call<jsSubtleCryptoPrototypeFunction_unwrapKeyBody>(*lexicalGlobalObject, *callFrame, "unwrapKey");
+}
+
+JSC::GCClient::IsoSubspace* JSSubtleCrypto::subspaceForImpl(JSC::VM& vm)
+{
+ return WebCore::subspaceForImpl<JSSubtleCrypto, UseCustomHeapCellType::No>(vm,
+ [] (auto& spaces) { return spaces.m_clientSubspaceForSubtleCrypto.get(); },
+ [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForSubtleCrypto = WTFMove(space); },
+ [] (auto& spaces) { return spaces.m_subspaceForSubtleCrypto.get(); },
+ [] (auto& spaces, auto&& space) { spaces.m_subspaceForSubtleCrypto = WTFMove(space); }
+ );
+}
+
+void JSSubtleCrypto::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
+{
+ auto* thisObject = jsCast<JSSubtleCrypto*>(cell);
+ analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
+ if (thisObject->scriptExecutionContext())
+ analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
+ Base::analyzeHeap(cell, analyzer);
+}
+
+bool JSSubtleCryptoOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void* context, AbstractSlotVisitor& visitor, const char** reason)
+{
+ auto* jsSubtleCrypto = jsCast<JSSubtleCrypto*>(handle.slot()->asCell());
+ ScriptExecutionContext* owner = WTF::getPtr(jsSubtleCrypto->wrapped().scriptExecutionContext());
+ if (!owner)
+ return false;
+ if (UNLIKELY(reason))
+ *reason = "Reachable from ScriptExecutionContext";
+ return visitor.containsOpaqueRoot(context);
+}
+
+void JSSubtleCryptoOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
+{
+ auto* jsSubtleCrypto = static_cast<JSSubtleCrypto*>(handle.slot()->asCell());
+ auto& world = *static_cast<DOMWrapperWorld*>(context);
+ uncacheWrapper(world, &jsSubtleCrypto->wrapped(), jsSubtleCrypto);
+}
+
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern "C" { extern void (*const __identifier("??_7SubtleCrypto@WebCore@@6B@")[])(); }
+#else
+extern "C" { extern void* _ZTVN7WebCore12SubtleCryptoE[]; }
+#endif
+#endif
+
+JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<SubtleCrypto>&& impl)
+{
+
+ if constexpr (std::is_polymorphic_v<SubtleCrypto>) {
+#if ENABLE(BINDING_INTEGRITY)
+ const void* actualVTablePointer = getVTablePointer(impl.ptr());
+#if PLATFORM(WIN)
+ void* expectedVTablePointer = __identifier("??_7SubtleCrypto@WebCore@@6B@");
+#else
+ void* expectedVTablePointer = &_ZTVN7WebCore12SubtleCryptoE[2];
+#endif
+
+ // If you hit this assertion you either have a use after free bug, or
+ // SubtleCrypto has subclasses. If SubtleCrypto has subclasses that get passed
+ // to toJS() we currently require SubtleCrypto you to opt out of binding hardening
+ // by adding the SkipVTableValidation attribute to the interface IDL definition
+ RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+ }
+ return createWrapper<SubtleCrypto>(globalObject, WTFMove(impl));
+}
+
+JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, SubtleCrypto& impl)
+{
+ return wrap(lexicalGlobalObject, globalObject, impl);
+}
+
+SubtleCrypto* JSSubtleCrypto::toWrapped(JSC::VM&, JSC::JSValue value)
+{
+ if (auto* wrapper = jsDynamicCast<JSSubtleCrypto*>(value))
+ return &wrapper->wrapped();
+ return nullptr;
+}
+
+}
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JSSubtleCrypto.dep b/src/bun.js/bindings/webcrypto/JSSubtleCrypto.dep
new file mode 100644
index 000000000..d1a56becf
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSSubtleCrypto.dep
@@ -0,0 +1 @@
+JSSubtleCrypto.h :
diff --git a/src/bun.js/bindings/webcrypto/JSSubtleCrypto.h b/src/bun.js/bindings/webcrypto/JSSubtleCrypto.h
new file mode 100644
index 000000000..d5d082dd1
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JSSubtleCrypto.h
@@ -0,0 +1,104 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "JSDOMConvertEnumeration.h"
+#include "JSDOMWrapper.h"
+#include "SubtleCrypto.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+class JSSubtleCrypto : public JSDOMWrapper<SubtleCrypto> {
+public:
+ using Base = JSDOMWrapper<SubtleCrypto>;
+ static JSSubtleCrypto* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<SubtleCrypto>&& impl)
+ {
+ JSSubtleCrypto* ptr = new (NotNull, JSC::allocateCell<JSSubtleCrypto>(globalObject->vm())) JSSubtleCrypto(structure, *globalObject, WTFMove(impl));
+ ptr->finishCreation(globalObject->vm());
+ return ptr;
+ }
+
+ static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
+ static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
+ static SubtleCrypto* toWrapped(JSC::VM&, JSC::JSValue);
+ static void destroy(JSC::JSCell*);
+
+ DECLARE_INFO;
+
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray);
+ }
+
+ static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
+ template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return subspaceForImpl(vm);
+ }
+ static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
+ static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
+protected:
+ JSSubtleCrypto(JSC::Structure*, JSDOMGlobalObject&, Ref<SubtleCrypto>&&);
+
+ void finishCreation(JSC::VM&);
+};
+
+class JSSubtleCryptoOwner final : public JSC::WeakHandleOwner {
+public:
+ bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final;
+ void finalize(JSC::Handle<JSC::Unknown>, void* context) final;
+};
+
+inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, SubtleCrypto*)
+{
+ static NeverDestroyed<JSSubtleCryptoOwner> owner;
+ return &owner.get();
+}
+
+inline void* wrapperKey(SubtleCrypto* wrappableObject)
+{
+ return wrappableObject;
+}
+
+JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, SubtleCrypto&);
+inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, SubtleCrypto* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<SubtleCrypto>&&);
+inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<SubtleCrypto>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
+
+template<> struct JSDOMWrapperConverterTraits<SubtleCrypto> {
+ using WrapperClass = JSSubtleCrypto;
+ using ToWrappedReturnType = SubtleCrypto*;
+};
+String convertEnumerationToString(SubtleCrypto::KeyFormat);
+template<> JSC::JSString* convertEnumerationToJS(JSC::JSGlobalObject&, SubtleCrypto::KeyFormat);
+
+template<> std::optional<SubtleCrypto::KeyFormat> parseEnumeration<SubtleCrypto::KeyFormat>(JSC::JSGlobalObject&, JSC::JSValue);
+template<> const char* expectedEnumerationValues<SubtleCrypto::KeyFormat>();
+
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JsonWebKey.h b/src/bun.js/bindings/webcrypto/JsonWebKey.h
new file mode 100644
index 000000000..eec00d747
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JsonWebKey.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoKeyUsage.h"
+#include "RsaOtherPrimesInfo.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+struct JsonWebKey {
+ String kty;
+ String use;
+ // FIXME: Consider merging key_ops and usages.
+ std::optional<Vector<CryptoKeyUsage>> key_ops;
+ CryptoKeyUsageBitmap usages;
+ String alg;
+
+ std::optional<bool> ext;
+
+ String crv;
+ String x;
+ String y;
+ String d;
+ String n;
+ String e;
+ String p;
+ String q;
+ String dp;
+ String dq;
+ String qi;
+ std::optional<Vector<RsaOtherPrimesInfo>> oth;
+ String k;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/JsonWebKey.idl b/src/bun.js/bindings/webcrypto/JsonWebKey.idl
new file mode 100644
index 000000000..5f4ca5c44
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/JsonWebKey.idl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ JSGenerateToJSObject,
+] dictionary JsonWebKey {
+ // The following fields are defined in Section 3.1 of JSON Web Key
+ required DOMString kty;
+ DOMString use;
+ sequence<CryptoKeyUsage> key_ops;
+ DOMString alg;
+
+ // The following fields are defined in JSON Web Key Parameters Registration
+ boolean ext;
+
+ // The following fields are defined in Section 6 of JSON Web Algorithms
+ DOMString crv;
+ DOMString x;
+ DOMString y;
+ DOMString d;
+ DOMString n;
+ DOMString e;
+ DOMString p;
+ DOMString q;
+ DOMString dp;
+ DOMString dq;
+ DOMString qi;
+ sequence<RsaOtherPrimesInfo> oth;
+ DOMString k;
+};
diff --git a/src/bun.js/bindings/webcrypto/OpenSSLCryptoUniquePtr.h b/src/bun.js/bindings/webcrypto/OpenSSLCryptoUniquePtr.h
new file mode 100644
index 000000000..b87aa561a
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/OpenSSLCryptoUniquePtr.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 Igalia S.L.
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <memory>
+#include <openssl/ec.h>
+#include <openssl/hmac.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/kdf.h>
+#include <openssl/param_build.h>
+#endif
+#include <openssl/x509.h>
+
+namespace WebCore {
+
+template <typename T>
+struct OpenSSLCryptoPtrDeleter {
+ void operator()(T* ptr) const = delete;
+};
+
+template <typename T>
+using OpenSSLCryptoPtr = std::unique_ptr<T, OpenSSLCryptoPtrDeleter<T>>;
+
+#define DEFINE_OPENSSL_CRYPTO_PTR_FULL(alias, typeName, deleterFunc) \
+ template<> struct OpenSSLCryptoPtrDeleter<typeName> { \
+ void operator()(typeName* ptr) const { \
+ deleterFunc; \
+ } \
+ }; \
+ using alias = OpenSSLCryptoPtr<typeName>;
+
+#define DEFINE_OPENSSL_CRYPTO_PTR(alias, typeName, deleterFunc) \
+ DEFINE_OPENSSL_CRYPTO_PTR_FULL(alias, typeName, deleterFunc(ptr))
+
+DEFINE_OPENSSL_CRYPTO_PTR(EvpCipherCtxPtr, EVP_CIPHER_CTX, EVP_CIPHER_CTX_free)
+DEFINE_OPENSSL_CRYPTO_PTR(EvpDigestCtxPtr, EVP_MD_CTX, EVP_MD_CTX_free)
+DEFINE_OPENSSL_CRYPTO_PTR(EvpPKeyPtr, EVP_PKEY, EVP_PKEY_free)
+DEFINE_OPENSSL_CRYPTO_PTR(EvpPKeyCtxPtr, EVP_PKEY_CTX, EVP_PKEY_CTX_free)
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+DEFINE_OPENSSL_CRYPTO_PTR(OsslParamBldPtr, OSSL_PARAM_BLD, OSSL_PARAM_BLD_free)
+DEFINE_OPENSSL_CRYPTO_PTR(OsslParamPtr, OSSL_PARAM, OSSL_PARAM_free)
+DEFINE_OPENSSL_CRYPTO_PTR(EVPKDFCtxPtr, EVP_KDF_CTX, EVP_KDF_CTX_free)
+DEFINE_OPENSSL_CRYPTO_PTR(EVPKDFPtr, EVP_KDF, EVP_KDF_free)
+#endif // OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+// These are deprecated in OpenSSL 3. FIXME: Migrate to EvpKey. See Bug #245146.
+DEFINE_OPENSSL_CRYPTO_PTR(RSAPtr, RSA, RSA_free)
+DEFINE_OPENSSL_CRYPTO_PTR(ECKeyPtr, EC_KEY, EC_KEY_free)
+DEFINE_OPENSSL_CRYPTO_PTR(HMACCtxPtr, HMAC_CTX, HMAC_CTX_free)
+
+DEFINE_OPENSSL_CRYPTO_PTR(ECPointPtr, EC_POINT, EC_POINT_clear_free)
+DEFINE_OPENSSL_CRYPTO_PTR(PKCS8PrivKeyInfoPtr, PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free)
+DEFINE_OPENSSL_CRYPTO_PTR(BIGNUMPtr, BIGNUM, BN_clear_free)
+DEFINE_OPENSSL_CRYPTO_PTR(BNCtxPtr, BN_CTX, BN_CTX_free)
+DEFINE_OPENSSL_CRYPTO_PTR(ECDSASigPtr, ECDSA_SIG, ECDSA_SIG_free)
+DEFINE_OPENSSL_CRYPTO_PTR(X509Ptr, X509, X509_free)
+DEFINE_OPENSSL_CRYPTO_PTR(BIOPtr, BIO, BIO_free)
+
+DEFINE_OPENSSL_CRYPTO_PTR_FULL(ASN1SequencePtr, ASN1_SEQUENCE_ANY, sk_ASN1_TYPE_pop_free(ptr, ASN1_TYPE_free))
+
+#undef DEFINE_OPENSSL_CRYPTO_PTR
+#undef DEFINE_OPENSSL_CRYPTO_PTR_FULL
+
+} // namespace WebCore
diff --git a/src/bun.js/bindings/webcrypto/OpenSSLUtilities.cpp b/src/bun.js/bindings/webcrypto/OpenSSLUtilities.cpp
new file mode 100644
index 000000000..2996cae2a
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/OpenSSLUtilities.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2021 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "OpenSSLUtilities.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "OpenSSLCryptoUniquePtr.h"
+
+namespace WebCore {
+
+const EVP_MD* digestAlgorithm(CryptoAlgorithmIdentifier hashFunction)
+{
+ switch (hashFunction) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ return EVP_sha1();
+ case CryptoAlgorithmIdentifier::SHA_224:
+ return EVP_sha224();
+ case CryptoAlgorithmIdentifier::SHA_256:
+ return EVP_sha256();
+ case CryptoAlgorithmIdentifier::SHA_384:
+ return EVP_sha384();
+ case CryptoAlgorithmIdentifier::SHA_512:
+ return EVP_sha512();
+ default:
+ return nullptr;
+ }
+}
+
+std::optional<Vector<uint8_t>> calculateDigest(const EVP_MD* algorithm, const Vector<uint8_t>& message)
+{
+ EvpDigestCtxPtr ctx;
+ if (!(ctx = EvpDigestCtxPtr(EVP_MD_CTX_create())))
+ return std::nullopt;
+
+ int digestLength = EVP_MD_size(algorithm);
+ if (digestLength <= 0)
+ return std::nullopt;
+ Vector<uint8_t> digest(digestLength);
+
+ if (EVP_DigestInit_ex(ctx.get(), algorithm, nullptr) != 1)
+ return std::nullopt;
+
+ if (EVP_DigestUpdate(ctx.get(), message.data(), message.size()) != 1)
+ return std::nullopt;
+
+ if (EVP_DigestFinal_ex(ctx.get(), digest.data(), nullptr) != 1)
+ return std::nullopt;
+
+ return digest;
+}
+
+Vector<uint8_t> convertToBytes(const BIGNUM* bignum)
+{
+ Vector<uint8_t> bytes(BN_num_bytes(bignum));
+ BN_bn2bin(bignum, bytes.data());
+ return bytes;
+}
+
+Vector<uint8_t> convertToBytesExpand(const BIGNUM* bignum, size_t minimumBufferSize)
+{
+ int length = BN_num_bytes(bignum);
+ if (length < 0)
+ return { };
+
+ size_t bufferSize = std::max<size_t>(length, minimumBufferSize);
+
+ Vector<uint8_t> bytes(bufferSize);
+
+ size_t paddingLength = bufferSize - length;
+ if (paddingLength > 0) {
+ uint8_t padding = BN_is_negative(bignum) ? 0xFF : 0x00;
+ for (size_t i = 0; i < paddingLength; i++)
+ bytes[i] = padding;
+ }
+ BN_bn2bin(bignum, bytes.data() + paddingLength);
+ return bytes;
+}
+
+BIGNUMPtr convertToBigNumber(const Vector<uint8_t>& bytes)
+{
+ return BIGNUMPtr(BN_bin2bn(bytes.data(), bytes.size(), nullptr));
+}
+
+bool AESKey::setKey(const Vector<uint8_t>& key, int enc)
+{
+ size_t keySize = key.size() * 8;
+ if (keySize != 128 && keySize != 192 && keySize != 256)
+ return false;
+
+ if (enc == AES_ENCRYPT) {
+ if (AES_set_encrypt_key(key.data(), keySize, &m_key) < 0)
+ return false;
+ return true;
+ }
+
+ if (enc == AES_DECRYPT) {
+ if (AES_set_decrypt_key(key.data(), keySize, &m_key) < 0)
+ return false;
+ return true;
+ }
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+AESKey::~AESKey()
+{
+ memset(&m_key, 0, sizeof m_key);
+}
+
+} // namespace WebCore
+
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/OpenSSLUtilities.h b/src/bun.js/bindings/webcrypto/OpenSSLUtilities.h
new file mode 100644
index 000000000..53d884c58
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/OpenSSLUtilities.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmIdentifier.h"
+#include "OpenSSLCryptoUniquePtr.h"
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#include <stdint.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+const EVP_MD* digestAlgorithm(CryptoAlgorithmIdentifier hashFunction);
+
+std::optional<Vector<uint8_t>> calculateDigest(const EVP_MD* algorithm, const Vector<uint8_t>& message);
+
+Vector<uint8_t> convertToBytes(const BIGNUM*);
+
+Vector<uint8_t> convertToBytesExpand(const BIGNUM*, size_t bufferSize);
+
+BIGNUMPtr convertToBigNumber(const Vector<uint8_t>& bytes);
+
+class AESKey {
+ WTF_MAKE_NONCOPYABLE(AESKey);
+public:
+ AESKey() = default;
+ ~AESKey();
+
+ bool setKey(const Vector<uint8_t>& key, int enc /* AES_ENCRYPT or AES_DECRYPT */);
+
+ AES_KEY* key() { return &m_key; }
+private:
+ AES_KEY m_key;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/Pbkdf2Params.idl b/src/bun.js/bindings/webcrypto/Pbkdf2Params.idl
new file mode 100644
index 000000000..6d3cf6a2a
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/Pbkdf2Params.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef (object or DOMString) HashAlgorithmIdentifier;
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmPbkdf2Params,
+] dictionary Pbkdf2Params : CryptoAlgorithmParameters {
+ required BufferSource salt;
+ required [EnforceRange] unsigned long iterations;
+ required HashAlgorithmIdentifier hash;
+};
diff --git a/src/bun.js/bindings/webcrypto/RsaHashedImportParams.idl b/src/bun.js/bindings/webcrypto/RsaHashedImportParams.idl
new file mode 100644
index 000000000..29136ca54
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/RsaHashedImportParams.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef (object or DOMString) HashAlgorithmIdentifier;
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmRsaHashedImportParams
+] dictionary RsaHashedImportParams : CryptoAlgorithmParameters {
+ // The hash algorithm to use
+ required HashAlgorithmIdentifier hash;
+};
diff --git a/src/bun.js/bindings/webcrypto/RsaHashedKeyGenParams.idl b/src/bun.js/bindings/webcrypto/RsaHashedKeyGenParams.idl
new file mode 100644
index 000000000..eed495d55
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/RsaHashedKeyGenParams.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef (object or DOMString) HashAlgorithmIdentifier;
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmRsaHashedKeyGenParams
+] dictionary RsaHashedKeyGenParams : RsaKeyGenParams {
+ // The hash algorithm to use
+ required HashAlgorithmIdentifier hash;
+};
diff --git a/src/bun.js/bindings/webcrypto/RsaKeyGenParams.idl b/src/bun.js/bindings/webcrypto/RsaKeyGenParams.idl
new file mode 100644
index 000000000..e7d3862cb
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/RsaKeyGenParams.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmRsaKeyGenParams
+] dictionary RsaKeyGenParams : CryptoAlgorithmParameters {
+ // The length, in bits, of the RSA modulus
+ required [EnforceRange] unsigned long modulusLength;
+ // The RSA public exponent
+ required Uint8Array publicExponent;
+};
diff --git a/src/bun.js/bindings/webcrypto/RsaOaepParams.idl b/src/bun.js/bindings/webcrypto/RsaOaepParams.idl
new file mode 100644
index 000000000..615c677c3
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/RsaOaepParams.idl
@@ -0,0 +1,32 @@
+/*
+* Copyright (C) 2016 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmRsaOaepParams
+] dictionary RsaOaepParams : CryptoAlgorithmParameters {
+ // The optional label/application data to associate with the message
+ BufferSource label;
+};
diff --git a/src/bun.js/bindings/webcrypto/RsaOtherPrimesInfo.h b/src/bun.js/bindings/webcrypto/RsaOtherPrimesInfo.h
new file mode 100644
index 000000000..1a8adc7ce
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/RsaOtherPrimesInfo.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/text/WTFString.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+struct RsaOtherPrimesInfo {
+ String r;
+ String d;
+ String t;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/RsaOtherPrimesInfo.idl b/src/bun.js/bindings/webcrypto/RsaOtherPrimesInfo.idl
new file mode 100644
index 000000000..9b1f30e2b
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/RsaOtherPrimesInfo.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ JSGenerateToJSObject,
+] dictionary RsaOtherPrimesInfo {
+ // The following fields are defined in Section 6.3.2.7 of JSON Web Algorithms
+ required DOMString r;
+ required DOMString d;
+ required DOMString t;
+};
diff --git a/src/bun.js/bindings/webcrypto/RsaPssParams.idl b/src/bun.js/bindings/webcrypto/RsaPssParams.idl
new file mode 100644
index 000000000..9a728324f
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/RsaPssParams.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_CRYPTO,
+ ImplementedAs=CryptoAlgorithmRsaPssParams
+] dictionary RsaPssParams : CryptoAlgorithmParameters {
+ // The desired length of the random salt
+ required [EnforceRange] unsigned long saltLength;
+};
diff --git a/src/bun.js/bindings/webcrypto/SerializedCryptoKeyWrap.h b/src/bun.js/bindings/webcrypto/SerializedCryptoKeyWrap.h
new file mode 100644
index 000000000..f1cf02058
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/SerializedCryptoKeyWrap.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Forward.h>
+#include <wtf/text/WTFString.h>
+
+#if ENABLE(WEB_CRYPTO)
+
+namespace WebCore {
+
+// The purpose of the following APIs is to protect serialized CryptoKey data in IndexedDB or
+// any other local storage that go through the structured clone algorithm. However, a side effect
+// of this extra layer of protection is redundant communications between mainThread(document) and
+// workerThreads. Please refer to WorkerGlobalScope for detailed explanation. P.S. This extra layer
+// of protection is not required by the spec as of 11 December 2014:
+// https://www.w3.org/TR/WebCryptoAPI/#security-developers
+
+WEBCORE_EXPORT std::optional<Vector<uint8_t>> defaultWebCryptoMasterKey();
+WEBCORE_EXPORT bool deleteDefaultWebCryptoMasterKey();
+
+WEBCORE_EXPORT bool wrapSerializedCryptoKey(const Vector<uint8_t>& masterKey, const Vector<uint8_t>& key, Vector<uint8_t>& result);
+WEBCORE_EXPORT bool unwrapSerializedCryptoKey(const Vector<uint8_t>& masterKey, const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key);
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/SerializedCryptoKeyWrapOpenSSL.cpp b/src/bun.js/bindings/webcrypto/SerializedCryptoKeyWrapOpenSSL.cpp
new file mode 100644
index 000000000..50088d542
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/SerializedCryptoKeyWrapOpenSSL.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SerializedCryptoKeyWrap.h"
+
+#include "CryptoAlgorithmAES_CTR.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+// #include "NotImplemented.h"
+
+namespace WebCore {
+
+std::optional<Vector<uint8_t>> defaultWebCryptoMasterKey()
+{
+ // notImplemented();
+ return std::nullopt;
+}
+
+// Initially these helper functions were intended to perform KEK wrapping and unwrapping,
+// but this is not required anymore, despite the function names and the Mac implementation
+// still indicating otherwise.
+// See https://bugs.webkit.org/show_bug.cgi?id=173883 for more info.
+
+bool wrapSerializedCryptoKey(const Vector<uint8_t>& masterKey, const Vector<uint8_t>& key, Vector<uint8_t>& result)
+{
+ UNUSED_PARAM(masterKey);
+
+ // No wrapping performed -- the serialized key data is copied into the `result` variable.
+ result = Vector<uint8_t>(key);
+ return true;
+}
+
+bool unwrapSerializedCryptoKey(const Vector<uint8_t>& masterKey, const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key)
+{
+ UNUSED_PARAM(masterKey);
+
+ // No unwrapping performed -- the serialized key data is copied into the `key` variable.
+ key = Vector<uint8_t>(wrappedKey);
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_CRYPTO)
diff --git a/src/bun.js/bindings/webcrypto/SubtleCrypto.cpp b/src/bun.js/bindings/webcrypto/SubtleCrypto.cpp
new file mode 100644
index 000000000..d8b7d7942
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/SubtleCrypto.cpp
@@ -0,0 +1,1193 @@
+/*
+ * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SubtleCrypto.h"
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "CryptoAlgorithm.h"
+#include "CryptoAlgorithmRegistry.h"
+#include "JSAesCbcCfbParams.h"
+#include "JSAesCtrParams.h"
+#include "JSAesGcmParams.h"
+#include "JSAesKeyParams.h"
+#include "JSCryptoAlgorithmParameters.h"
+#include "JSCryptoKey.h"
+#include "JSCryptoKeyPair.h"
+#include "JSDOMPromiseDeferred.h"
+#include "JSDOMWrapper.h"
+#include "JSEcKeyParams.h"
+#include "JSEcdhKeyDeriveParams.h"
+#include "JSEcdsaParams.h"
+#include "JSHkdfParams.h"
+#include "JSHmacKeyParams.h"
+#include "JSJsonWebKey.h"
+#include "JSPbkdf2Params.h"
+#include "JSRsaHashedImportParams.h"
+#include "JSRsaHashedKeyGenParams.h"
+#include "JSRsaKeyGenParams.h"
+#include "JSRsaOaepParams.h"
+#include "JSRsaPssParams.h"
+#include <JavaScriptCore/JSONObject.h>
+
+namespace WebCore {
+using namespace JSC;
+
+SubtleCrypto::SubtleCrypto(ScriptExecutionContext* context)
+ : ContextDestructionObserver(context)
+ , m_workQueue(WorkQueue::create("com.apple.WebKit.CryptoQueue"))
+{
+}
+
+SubtleCrypto::~SubtleCrypto() = default;
+
+enum class Operations {
+ Encrypt,
+ Decrypt,
+ Sign,
+ Verify,
+ Digest,
+ GenerateKey,
+ DeriveBits,
+ ImportKey,
+ WrapKey,
+ UnwrapKey,
+ GetKeyLength
+};
+
+static ExceptionOr<std::unique_ptr<CryptoAlgorithmParameters>> normalizeCryptoAlgorithmParameters(JSGlobalObject&, WebCore::SubtleCrypto::AlgorithmIdentifier, Operations);
+
+static ExceptionOr<CryptoAlgorithmIdentifier> toHashIdentifier(JSGlobalObject& state, SubtleCrypto::AlgorithmIdentifier algorithmIdentifier)
+{
+ auto digestParams = normalizeCryptoAlgorithmParameters(state, algorithmIdentifier, Operations::Digest);
+ if (digestParams.hasException())
+ return digestParams.releaseException();
+ return digestParams.returnValue()->identifier;
+}
+
+static ExceptionOr<std::unique_ptr<CryptoAlgorithmParameters>> normalizeCryptoAlgorithmParameters(JSGlobalObject& state, SubtleCrypto::AlgorithmIdentifier algorithmIdentifier, Operations operation)
+{
+ VM& vm = state.vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (std::holds_alternative<String>(algorithmIdentifier)) {
+ auto newParams = Strong<JSObject>(vm, constructEmptyObject(&state));
+ newParams->putDirect(vm, Identifier::fromString(vm, "name"_s), jsString(vm, std::get<String>(algorithmIdentifier)));
+
+ return normalizeCryptoAlgorithmParameters(state, newParams, operation);
+ }
+
+ auto& value = std::get<JSC::Strong<JSC::JSObject>>(algorithmIdentifier);
+
+ auto params = convertDictionary<CryptoAlgorithmParameters>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+
+ auto identifier = CryptoAlgorithmRegistry::singleton().identifier(params.name);
+ if (UNLIKELY(!identifier))
+ return Exception { NotSupportedError };
+
+ std::unique_ptr<CryptoAlgorithmParameters> result;
+ switch (operation) {
+ case Operations::Encrypt:
+ case Operations::Decrypt:
+ switch (*identifier) {
+ case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
+ result = makeUnique<CryptoAlgorithmParameters>(params);
+ break;
+ case CryptoAlgorithmIdentifier::RSA_OAEP: {
+ auto params = convertDictionary<CryptoAlgorithmRsaOaepParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmRsaOaepParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::AES_CBC:
+ case CryptoAlgorithmIdentifier::AES_CFB: {
+ auto params = convertDictionary<CryptoAlgorithmAesCbcCfbParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmAesCbcCfbParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::AES_CTR: {
+ auto params = convertDictionary<CryptoAlgorithmAesCtrParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmAesCtrParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::AES_GCM: {
+ auto params = convertDictionary<CryptoAlgorithmAesGcmParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmAesGcmParams>(params);
+ break;
+ }
+ default:
+ return Exception { NotSupportedError };
+ }
+ break;
+ case Operations::Sign:
+ case Operations::Verify:
+ switch (*identifier) {
+ case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::HMAC:
+ result = makeUnique<CryptoAlgorithmParameters>(params);
+ break;
+ case CryptoAlgorithmIdentifier::ECDSA: {
+ auto params = convertDictionary<CryptoAlgorithmEcdsaParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ auto hashIdentifier = toHashIdentifier(state, params.hash);
+ if (hashIdentifier.hasException())
+ return hashIdentifier.releaseException();
+ params.hashIdentifier = hashIdentifier.releaseReturnValue();
+ result = makeUnique<CryptoAlgorithmEcdsaParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::RSA_PSS: {
+ auto params = convertDictionary<CryptoAlgorithmRsaPssParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmRsaPssParams>(params);
+ break;
+ }
+ default:
+ return Exception { NotSupportedError };
+ }
+ break;
+ case Operations::Digest:
+ switch (*identifier) {
+ case CryptoAlgorithmIdentifier::SHA_1:
+ case CryptoAlgorithmIdentifier::SHA_224:
+ case CryptoAlgorithmIdentifier::SHA_256:
+ case CryptoAlgorithmIdentifier::SHA_384:
+ case CryptoAlgorithmIdentifier::SHA_512:
+ result = makeUnique<CryptoAlgorithmParameters>(params);
+ break;
+ default:
+ return Exception { NotSupportedError };
+ }
+ break;
+ case Operations::GenerateKey:
+ switch (*identifier) {
+ case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5: {
+ auto params = convertDictionary<CryptoAlgorithmRsaKeyGenParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmRsaKeyGenParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSA_PSS:
+ case CryptoAlgorithmIdentifier::RSA_OAEP: {
+ auto params = convertDictionary<CryptoAlgorithmRsaHashedKeyGenParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ auto hashIdentifier = toHashIdentifier(state, params.hash);
+ if (hashIdentifier.hasException())
+ return hashIdentifier.releaseException();
+ params.hashIdentifier = hashIdentifier.releaseReturnValue();
+ result = makeUnique<CryptoAlgorithmRsaHashedKeyGenParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::AES_CTR:
+ case CryptoAlgorithmIdentifier::AES_CBC:
+ case CryptoAlgorithmIdentifier::AES_GCM:
+ case CryptoAlgorithmIdentifier::AES_CFB:
+ case CryptoAlgorithmIdentifier::AES_KW: {
+ auto params = convertDictionary<CryptoAlgorithmAesKeyParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmAesKeyParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::HMAC: {
+ auto params = convertDictionary<CryptoAlgorithmHmacKeyParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ auto hashIdentifier = toHashIdentifier(state, params.hash);
+ if (hashIdentifier.hasException())
+ return hashIdentifier.releaseException();
+ params.hashIdentifier = hashIdentifier.releaseReturnValue();
+ result = makeUnique<CryptoAlgorithmHmacKeyParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::ECDSA:
+ case CryptoAlgorithmIdentifier::ECDH: {
+ auto params = convertDictionary<CryptoAlgorithmEcKeyParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmEcKeyParams>(params);
+ break;
+ }
+ default:
+ return Exception { NotSupportedError };
+ }
+ break;
+ case Operations::DeriveBits:
+ switch (*identifier) {
+ case CryptoAlgorithmIdentifier::ECDH: {
+ // Remove this hack once https://bugs.webkit.org/show_bug.cgi?id=169333 is fixed.
+ JSValue nameValue = value.get()->get(&state, Identifier::fromString(vm, "name"_s));
+ JSValue publicValue = value.get()->get(&state, Identifier::fromString(vm, "public"_s));
+ JSObject* newValue = constructEmptyObject(&state);
+ newValue->putDirect(vm, Identifier::fromString(vm, "name"_s), nameValue);
+ newValue->putDirect(vm, Identifier::fromString(vm, "publicKey"_s), publicValue);
+
+ auto params = convertDictionary<CryptoAlgorithmEcdhKeyDeriveParams>(state, newValue);
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmEcdhKeyDeriveParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::HKDF: {
+ auto params = convertDictionary<CryptoAlgorithmHkdfParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ auto hashIdentifier = toHashIdentifier(state, params.hash);
+ if (hashIdentifier.hasException())
+ return hashIdentifier.releaseException();
+ params.hashIdentifier = hashIdentifier.releaseReturnValue();
+ result = makeUnique<CryptoAlgorithmHkdfParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::PBKDF2: {
+ auto params = convertDictionary<CryptoAlgorithmPbkdf2Params>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ auto hashIdentifier = toHashIdentifier(state, params.hash);
+ if (hashIdentifier.hasException())
+ return hashIdentifier.releaseException();
+ params.hashIdentifier = hashIdentifier.releaseReturnValue();
+ result = makeUnique<CryptoAlgorithmPbkdf2Params>(params);
+ break;
+ }
+ default:
+ return Exception { NotSupportedError };
+ }
+ break;
+ case Operations::ImportKey:
+ switch (*identifier) {
+ case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
+ result = makeUnique<CryptoAlgorithmParameters>(params);
+ break;
+ case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSA_PSS:
+ case CryptoAlgorithmIdentifier::RSA_OAEP: {
+ auto params = convertDictionary<CryptoAlgorithmRsaHashedImportParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ auto hashIdentifier = toHashIdentifier(state, params.hash);
+ if (hashIdentifier.hasException())
+ return hashIdentifier.releaseException();
+ params.hashIdentifier = hashIdentifier.releaseReturnValue();
+ result = makeUnique<CryptoAlgorithmRsaHashedImportParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::AES_CTR:
+ case CryptoAlgorithmIdentifier::AES_CBC:
+ case CryptoAlgorithmIdentifier::AES_GCM:
+ case CryptoAlgorithmIdentifier::AES_CFB:
+ case CryptoAlgorithmIdentifier::AES_KW:
+ result = makeUnique<CryptoAlgorithmParameters>(params);
+ break;
+ case CryptoAlgorithmIdentifier::HMAC: {
+ auto params = convertDictionary<CryptoAlgorithmHmacKeyParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ auto hashIdentifier = toHashIdentifier(state, params.hash);
+ if (hashIdentifier.hasException())
+ return hashIdentifier.releaseException();
+ params.hashIdentifier = hashIdentifier.releaseReturnValue();
+ result = makeUnique<CryptoAlgorithmHmacKeyParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::ECDSA:
+ case CryptoAlgorithmIdentifier::ECDH: {
+ auto params = convertDictionary<CryptoAlgorithmEcKeyParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmEcKeyParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::HKDF:
+ case CryptoAlgorithmIdentifier::PBKDF2:
+ result = makeUnique<CryptoAlgorithmParameters>(params);
+ break;
+ default:
+ return Exception { NotSupportedError };
+ }
+ break;
+ case Operations::WrapKey:
+ case Operations::UnwrapKey:
+ switch (*identifier) {
+ case CryptoAlgorithmIdentifier::AES_KW:
+ result = makeUnique<CryptoAlgorithmParameters>(params);
+ break;
+ default:
+ return Exception { NotSupportedError };
+ }
+ break;
+ case Operations::GetKeyLength:
+ switch (*identifier) {
+ case CryptoAlgorithmIdentifier::AES_CTR:
+ case CryptoAlgorithmIdentifier::AES_CBC:
+ case CryptoAlgorithmIdentifier::AES_GCM:
+ case CryptoAlgorithmIdentifier::AES_CFB:
+ case CryptoAlgorithmIdentifier::AES_KW: {
+ auto params = convertDictionary<CryptoAlgorithmAesKeyParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ result = makeUnique<CryptoAlgorithmAesKeyParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::HMAC: {
+ auto params = convertDictionary<CryptoAlgorithmHmacKeyParams>(state, value.get());
+ RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+ auto hashIdentifier = toHashIdentifier(state, params.hash);
+ if (hashIdentifier.hasException())
+ return hashIdentifier.releaseException();
+ params.hashIdentifier = hashIdentifier.releaseReturnValue();
+ result = makeUnique<CryptoAlgorithmHmacKeyParams>(params);
+ break;
+ }
+ case CryptoAlgorithmIdentifier::HKDF:
+ case CryptoAlgorithmIdentifier::PBKDF2:
+ result = makeUnique<CryptoAlgorithmParameters>(params);
+ break;
+ default:
+ return Exception { NotSupportedError };
+ }
+ break;
+ }
+
+ result->identifier = *identifier;
+ return result;
+}
+
+static CryptoKeyUsageBitmap toCryptoKeyUsageBitmap(CryptoKeyUsage usage)
+{
+ switch (usage) {
+ case CryptoKeyUsage::Encrypt:
+ return CryptoKeyUsageEncrypt;
+ case CryptoKeyUsage::Decrypt:
+ return CryptoKeyUsageDecrypt;
+ case CryptoKeyUsage::Sign:
+ return CryptoKeyUsageSign;
+ case CryptoKeyUsage::Verify:
+ return CryptoKeyUsageVerify;
+ case CryptoKeyUsage::DeriveKey:
+ return CryptoKeyUsageDeriveKey;
+ case CryptoKeyUsage::DeriveBits:
+ return CryptoKeyUsageDeriveBits;
+ case CryptoKeyUsage::WrapKey:
+ return CryptoKeyUsageWrapKey;
+ case CryptoKeyUsage::UnwrapKey:
+ return CryptoKeyUsageUnwrapKey;
+ }
+
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+static CryptoKeyUsageBitmap toCryptoKeyUsageBitmap(const Vector<CryptoKeyUsage>& usages)
+{
+ CryptoKeyUsageBitmap result = 0;
+ // Maybe we shouldn't silently bypass duplicated usages?
+ for (auto usage : usages)
+ result |= toCryptoKeyUsageBitmap(usage);
+
+ return result;
+}
+
+// Maybe we want more specific error messages?
+static void rejectWithException(Ref<DeferredPromise>&& passedPromise, ExceptionCode ec)
+{
+ switch (ec) {
+ case NotSupportedError:
+ passedPromise->reject(ec, "The algorithm is not supported"_s);
+ return;
+ case SyntaxError:
+ passedPromise->reject(ec, "A required parameter was missing or out-of-range"_s);
+ return;
+ case InvalidStateError:
+ passedPromise->reject(ec, "The requested operation is not valid for the current state of the provided key"_s);
+ return;
+ case InvalidAccessError:
+ passedPromise->reject(ec, "The requested operation is not valid for the provided key"_s);
+ return;
+ case UnknownError:
+ passedPromise->reject(ec, "The operation failed for an unknown transient reason (e.g. out of memory)"_s);
+ return;
+ case DataError:
+ passedPromise->reject(ec, "Data provided to an operation does not meet requirements"_s);
+ return;
+ case OperationError:
+ passedPromise->reject(ec, "The operation failed for an operation-specific reason"_s);
+ return;
+ default:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+}
+
+static void normalizeJsonWebKey(JsonWebKey& webKey)
+{
+ // Maybe we shouldn't silently bypass duplicated usages?
+ webKey.usages = webKey.key_ops ? toCryptoKeyUsageBitmap(webKey.key_ops.value()) : 0;
+}
+
+// FIXME: This returns an std::optional<KeyData> and takes a promise, rather than returning an
+// ExceptionOr<KeyData> and letting the caller handle the promise, to work around an issue where
+// Variant types (which KeyData is) in ExceptionOr<> cause compile issues on some platforms. This
+// should be resolved by adopting a standards compliant std::variant (see https://webkit.org/b/175583)
+static std::optional<KeyData> toKeyData(SubtleCrypto::KeyFormat format, SubtleCrypto::KeyDataVariant&& keyDataVariant, Ref<DeferredPromise>& promise)
+{
+ switch (format) {
+ case SubtleCrypto::KeyFormat::Spki:
+ case SubtleCrypto::KeyFormat::Pkcs8:
+ case SubtleCrypto::KeyFormat::Raw:
+ return WTF::switchOn(
+ keyDataVariant,
+ [&promise](JsonWebKey&) -> std::optional<KeyData> {
+ promise->reject(Exception { TypeError });
+ return std::nullopt;
+ },
+ [](auto& bufferSource) -> std::optional<KeyData> {
+ return KeyData { Vector { static_cast<const uint8_t*>(bufferSource->data()), bufferSource->byteLength() } };
+ });
+ case SubtleCrypto::KeyFormat::Jwk:
+ return WTF::switchOn(
+ keyDataVariant,
+ [](JsonWebKey& webKey) -> std::optional<KeyData> {
+ normalizeJsonWebKey(webKey);
+ return KeyData { webKey };
+ },
+ [&promise](auto&) -> std::optional<KeyData> {
+ promise->reject(Exception { TypeError });
+ return std::nullopt;
+ });
+ }
+
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+static Vector<uint8_t> copyToVector(BufferSource&& data)
+{
+ return { data.data(), data.length() };
+}
+
+static bool isSupportedExportKey(CryptoAlgorithmIdentifier identifier)
+{
+ switch (identifier) {
+ case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+ case CryptoAlgorithmIdentifier::RSA_PSS:
+ case CryptoAlgorithmIdentifier::RSA_OAEP:
+ case CryptoAlgorithmIdentifier::AES_CTR:
+ case CryptoAlgorithmIdentifier::AES_CBC:
+ case CryptoAlgorithmIdentifier::AES_GCM:
+ case CryptoAlgorithmIdentifier::AES_CFB:
+ case CryptoAlgorithmIdentifier::AES_KW:
+ case CryptoAlgorithmIdentifier::HMAC:
+ case CryptoAlgorithmIdentifier::ECDSA:
+ case CryptoAlgorithmIdentifier::ECDH:
+ return true;
+ default:
+ return false;
+ }
+}
+
+RefPtr<DeferredPromise> getPromise(DeferredPromise* index, WeakPtr<SubtleCrypto> weakThis)
+{
+ if (weakThis)
+ return weakThis->m_pendingPromises.take(index);
+ return nullptr;
+}
+
+static std::unique_ptr<CryptoAlgorithmParameters> crossThreadCopyImportParams(const CryptoAlgorithmParameters& importParams)
+{
+ switch (importParams.parametersClass()) {
+ case CryptoAlgorithmParameters::Class::None: {
+ auto result = makeUnique<CryptoAlgorithmParameters>();
+ result->identifier = importParams.identifier;
+ return result;
+ }
+ case CryptoAlgorithmParameters::Class::EcKeyParams:
+ return makeUnique<CryptoAlgorithmEcKeyParams>(crossThreadCopy(downcast<CryptoAlgorithmEcKeyParams>(importParams)));
+ case CryptoAlgorithmParameters::Class::HmacKeyParams:
+ return makeUnique<CryptoAlgorithmHmacKeyParams>(crossThreadCopy(downcast<CryptoAlgorithmHmacKeyParams>(importParams)));
+ case CryptoAlgorithmParameters::Class::RsaHashedImportParams:
+ return makeUnique<CryptoAlgorithmRsaHashedImportParams>(crossThreadCopy(downcast<CryptoAlgorithmRsaHashedImportParams>(importParams)));
+ default:
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+}
+
+void SubtleCrypto::addAuthenticatedEncryptionWarningIfNecessary(CryptoAlgorithmIdentifier algorithmIdentifier)
+{
+ // if (algorithmIdentifier == CryptoAlgorithmIdentifier::AES_CBC || algorithmIdentifier == CryptoAlgorithmIdentifier::AES_CTR) {
+ // if (!scriptExecutionContext()->hasLoggedAuthenticatedEncryptionWarning()) {
+ // scriptExecutionContext()->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "AES-CBC and AES-CTR do not provide authentication by default, and implementing it manually can result in minor, but serious mistakes. We recommended using authenticated encryption like AES-GCM to protect against chosen-ciphertext attacks."_s);
+ // scriptExecutionContext()->setHasLoggedAuthenticatedEncryptionWarning(true);
+ // }
+ // }
+}
+
+// MARK: - Exposed functions.
+
+void SubtleCrypto::encrypt(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, CryptoKey& key, BufferSource&& dataBufferSource, Ref<DeferredPromise>&& promise)
+{
+ addAuthenticatedEncryptionWarningIfNecessary(key.algorithmIdentifier());
+
+ auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::Encrypt);
+ if (paramsOrException.hasException()) {
+ promise->reject(paramsOrException.releaseException());
+ return;
+ }
+ auto params = paramsOrException.releaseReturnValue();
+
+ auto data = copyToVector(WTFMove(dataBufferSource));
+
+ if (params->identifier != key.algorithmIdentifier()) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't match AlgorithmIdentifier"_s);
+ return;
+ }
+
+ if (!key.allows(CryptoKeyUsageEncrypt)) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't support encryption"_s);
+ return;
+ }
+
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(key.algorithmIdentifier());
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis](const Vector<uint8_t>& cipherText) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ fulfillPromiseWithArrayBuffer(promise.releaseNonNull(), cipherText.data(), cipherText.size());
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ algorithm->encrypt(*params, key, WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext(), m_workQueue);
+}
+
+void SubtleCrypto::decrypt(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, CryptoKey& key, BufferSource&& dataBufferSource, Ref<DeferredPromise>&& promise)
+{
+ addAuthenticatedEncryptionWarningIfNecessary(key.algorithmIdentifier());
+
+ auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::Decrypt);
+ if (paramsOrException.hasException()) {
+ promise->reject(paramsOrException.releaseException());
+ return;
+ }
+ auto params = paramsOrException.releaseReturnValue();
+
+ auto data = copyToVector(WTFMove(dataBufferSource));
+
+ if (params->identifier != key.algorithmIdentifier()) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't match AlgorithmIdentifier"_s);
+ return;
+ }
+
+ if (!key.allows(CryptoKeyUsageDecrypt)) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't support decryption"_s);
+ return;
+ }
+
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(key.algorithmIdentifier());
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis](const Vector<uint8_t>& plainText) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ fulfillPromiseWithArrayBuffer(promise.releaseNonNull(), plainText.data(), plainText.size());
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ algorithm->decrypt(*params, key, WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext(), m_workQueue);
+}
+
+void SubtleCrypto::sign(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, CryptoKey& key, BufferSource&& dataBufferSource, Ref<DeferredPromise>&& promise)
+{
+ auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::Sign);
+ if (paramsOrException.hasException()) {
+ promise->reject(paramsOrException.releaseException());
+ return;
+ }
+ auto params = paramsOrException.releaseReturnValue();
+
+ auto data = copyToVector(WTFMove(dataBufferSource));
+
+ if (params->identifier != key.algorithmIdentifier()) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't match AlgorithmIdentifier"_s);
+ return;
+ }
+
+ if (!key.allows(CryptoKeyUsageSign)) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't support signing"_s);
+ return;
+ }
+
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(key.algorithmIdentifier());
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis](const Vector<uint8_t>& signature) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ fulfillPromiseWithArrayBuffer(promise.releaseNonNull(), signature.data(), signature.size());
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ algorithm->sign(*params, key, WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext(), m_workQueue);
+}
+
+void SubtleCrypto::verify(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, CryptoKey& key, BufferSource&& signatureBufferSource, BufferSource&& dataBufferSource, Ref<DeferredPromise>&& promise)
+{
+ auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::Verify);
+ if (paramsOrException.hasException()) {
+ promise->reject(paramsOrException.releaseException());
+ return;
+ }
+ auto params = paramsOrException.releaseReturnValue();
+
+ auto signature = copyToVector(WTFMove(signatureBufferSource));
+ auto data = copyToVector(WTFMove(dataBufferSource));
+
+ if (params->identifier != key.algorithmIdentifier()) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't match AlgorithmIdentifier"_s);
+ return;
+ }
+
+ if (!key.allows(CryptoKeyUsageVerify)) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't support verification"_s);
+ return;
+ }
+
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(key.algorithmIdentifier());
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis](bool result) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ promise->resolve<IDLBoolean>(result);
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ algorithm->verify(*params, key, WTFMove(signature), WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext(), m_workQueue);
+}
+
+void SubtleCrypto::digest(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, BufferSource&& dataBufferSource, Ref<DeferredPromise>&& promise)
+{
+ auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::Digest);
+ if (paramsOrException.hasException()) {
+ promise->reject(paramsOrException.releaseException());
+ return;
+ }
+ auto params = paramsOrException.releaseReturnValue();
+
+ auto data = copyToVector(WTFMove(dataBufferSource));
+
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(params->identifier);
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis](const Vector<uint8_t>& digest) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ fulfillPromiseWithArrayBuffer(promise.releaseNonNull(), digest.data(), digest.size());
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ algorithm->digest(WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext(), m_workQueue);
+}
+
+void SubtleCrypto::generateKey(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, bool extractable, Vector<CryptoKeyUsage>&& keyUsages, Ref<DeferredPromise>&& promise)
+{
+ auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::GenerateKey);
+ if (paramsOrException.hasException()) {
+ promise->reject(paramsOrException.releaseException());
+ return;
+ }
+ auto params = paramsOrException.releaseReturnValue();
+
+ auto keyUsagesBitmap = toCryptoKeyUsageBitmap(keyUsages);
+
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(params->identifier);
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis](KeyOrKeyPair&& keyOrKeyPair) mutable {
+ if (auto promise = getPromise(index, weakThis)) {
+ WTF::switchOn(
+ keyOrKeyPair,
+ [&promise](RefPtr<CryptoKey>& key) {
+ if ((key->type() == CryptoKeyType::Private || key->type() == CryptoKeyType::Secret) && !key->usagesBitmap()) {
+ rejectWithException(promise.releaseNonNull(), SyntaxError);
+ return;
+ }
+ promise->resolve<IDLInterface<CryptoKey>>(*key);
+ },
+ [&promise](CryptoKeyPair& keyPair) {
+ if (!keyPair.privateKey->usagesBitmap()) {
+ rejectWithException(promise.releaseNonNull(), SyntaxError);
+ return;
+ }
+ promise->resolve<IDLDictionary<CryptoKeyPair>>(keyPair);
+ });
+ }
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ // The 26 January 2017 version of the specification suggests we should perform the following task asynchronously
+ // regardless what kind of keys it produces: https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-generateKey
+ // That's simply not efficient for AES, HMAC and EC keys. Therefore, we perform it as an async task only for RSA keys.
+ algorithm->generateKey(*params, extractable, keyUsagesBitmap, WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext());
+}
+
+void SubtleCrypto::deriveKey(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, CryptoKey& baseKey, AlgorithmIdentifier&& derivedKeyType, bool extractable, Vector<CryptoKeyUsage>&& keyUsages, Ref<DeferredPromise>&& promise)
+{
+ auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::DeriveBits);
+ if (paramsOrException.hasException()) {
+ promise->reject(paramsOrException.releaseException());
+ return;
+ }
+ auto params = paramsOrException.releaseReturnValue();
+
+ auto importParamsOrException = normalizeCryptoAlgorithmParameters(state, derivedKeyType, Operations::ImportKey);
+ if (importParamsOrException.hasException()) {
+ promise->reject(importParamsOrException.releaseException());
+ return;
+ }
+ auto importParams = importParamsOrException.releaseReturnValue();
+
+ auto getLengthParamsOrException = normalizeCryptoAlgorithmParameters(state, derivedKeyType, Operations::GetKeyLength);
+ if (getLengthParamsOrException.hasException()) {
+ promise->reject(getLengthParamsOrException.releaseException());
+ return;
+ }
+ auto getLengthParams = getLengthParamsOrException.releaseReturnValue();
+
+ auto keyUsagesBitmap = toCryptoKeyUsageBitmap(keyUsages);
+
+ if (params->identifier != baseKey.algorithmIdentifier()) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't match AlgorithmIdentifier"_s);
+ return;
+ }
+
+ if (!baseKey.allows(CryptoKeyUsageDeriveKey)) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't support CryptoKey derivation"_s);
+ return;
+ }
+
+ auto getLengthAlgorithm = CryptoAlgorithmRegistry::singleton().create(getLengthParams->identifier);
+
+ auto result = getLengthAlgorithm->getKeyLength(*getLengthParams);
+ if (result.hasException()) {
+ promise->reject(result.releaseException().code(), "Cannot get key length from derivedKeyType"_s);
+ return;
+ }
+ size_t length = result.releaseReturnValue();
+
+ auto importAlgorithm = CryptoAlgorithmRegistry::singleton().create(importParams->identifier);
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(params->identifier);
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis, importAlgorithm = WTFMove(importAlgorithm), importParams = crossThreadCopyImportParams(*importParams), extractable, keyUsagesBitmap](const Vector<uint8_t>& derivedKey) mutable {
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=169395
+ KeyData data = derivedKey;
+ auto callback = [index, weakThis](CryptoKey& key) mutable {
+ if (auto promise = getPromise(index, weakThis)) {
+ if ((key.type() == CryptoKeyType::Private || key.type() == CryptoKeyType::Secret) && !key.usagesBitmap()) {
+ rejectWithException(promise.releaseNonNull(), SyntaxError);
+ return;
+ }
+ promise->resolve<IDLInterface<CryptoKey>>(key);
+ }
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ importAlgorithm->importKey(SubtleCrypto::KeyFormat::Raw, WTFMove(data), *importParams, extractable, keyUsagesBitmap, WTFMove(callback), WTFMove(exceptionCallback));
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ algorithm->deriveBits(*params, baseKey, length, WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext(), m_workQueue);
+}
+
+void SubtleCrypto::deriveBits(JSC::JSGlobalObject& state, AlgorithmIdentifier&& algorithmIdentifier, CryptoKey& baseKey, unsigned length, Ref<DeferredPromise>&& promise)
+{
+ auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::DeriveBits);
+ if (paramsOrException.hasException()) {
+ promise->reject(paramsOrException.releaseException());
+ return;
+ }
+ auto params = paramsOrException.releaseReturnValue();
+
+ if (params->identifier != baseKey.algorithmIdentifier()) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't match AlgorithmIdentifier"_s);
+ return;
+ }
+
+ if (!baseKey.allows(CryptoKeyUsageDeriveBits)) {
+ promise->reject(InvalidAccessError, "CryptoKey doesn't support bits derivation"_s);
+ return;
+ }
+
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(params->identifier);
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis](const Vector<uint8_t>& derivedKey) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ fulfillPromiseWithArrayBuffer(promise.releaseNonNull(), derivedKey.data(), derivedKey.size());
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ algorithm->deriveBits(*params, baseKey, length, WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext(), m_workQueue);
+}
+
+void SubtleCrypto::importKey(JSC::JSGlobalObject& state, KeyFormat format, KeyDataVariant&& keyDataVariant, AlgorithmIdentifier&& algorithmIdentifier, bool extractable, Vector<CryptoKeyUsage>&& keyUsages, Ref<DeferredPromise>&& promise)
+{
+ auto paramsOrException = normalizeCryptoAlgorithmParameters(state, WTFMove(algorithmIdentifier), Operations::ImportKey);
+ if (paramsOrException.hasException()) {
+ promise->reject(paramsOrException.releaseException());
+ return;
+ }
+ auto params = paramsOrException.releaseReturnValue();
+
+ auto keyDataOrNull = toKeyData(format, WTFMove(keyDataVariant), promise);
+ if (!keyDataOrNull) {
+ // When toKeyData, it means the promise has been rejected, and we should return.
+ return;
+ }
+
+ auto keyData = *keyDataOrNull;
+ auto keyUsagesBitmap = toCryptoKeyUsageBitmap(keyUsages);
+
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(params->identifier);
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis](CryptoKey& key) mutable {
+ if (auto promise = getPromise(index, weakThis)) {
+ if ((key.type() == CryptoKeyType::Private || key.type() == CryptoKeyType::Secret) && !key.usagesBitmap()) {
+ rejectWithException(promise.releaseNonNull(), SyntaxError);
+ return;
+ }
+ promise->resolve<IDLInterface<CryptoKey>>(key);
+ }
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ // The 11 December 2014 version of the specification suggests we should perform the following task asynchronously:
+ // https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-importKey
+ // It is not beneficial for less time consuming operations. Therefore, we perform it synchronously.
+ algorithm->importKey(format, WTFMove(keyData), *params, extractable, keyUsagesBitmap, WTFMove(callback), WTFMove(exceptionCallback));
+}
+
+void SubtleCrypto::exportKey(KeyFormat format, CryptoKey& key, Ref<DeferredPromise>&& promise)
+{
+ if (!isSupportedExportKey(key.algorithmIdentifier())) {
+ promise->reject(Exception { NotSupportedError });
+ return;
+ }
+
+ if (!key.extractable()) {
+ promise->reject(InvalidAccessError, "The CryptoKey is nonextractable"_s);
+ return;
+ }
+
+ auto algorithm = CryptoAlgorithmRegistry::singleton().create(key.algorithmIdentifier());
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis](SubtleCrypto::KeyFormat format, KeyData&& key) mutable {
+ if (auto promise = getPromise(index, weakThis)) {
+ switch (format) {
+ case SubtleCrypto::KeyFormat::Spki:
+ case SubtleCrypto::KeyFormat::Pkcs8:
+ case SubtleCrypto::KeyFormat::Raw: {
+ Vector<uint8_t>& rawKey = std::get<Vector<uint8_t>>(key);
+ fulfillPromiseWithArrayBuffer(promise.releaseNonNull(), rawKey.data(), rawKey.size());
+ return;
+ }
+ case SubtleCrypto::KeyFormat::Jwk:
+ promise->resolve<IDLDictionary<JsonWebKey>>(WTFMove(std::get<JsonWebKey>(key)));
+ return;
+ }
+ ASSERT_NOT_REACHED();
+ }
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ // The 11 December 2014 version of the specification suggests we should perform the following task asynchronously:
+ // https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-exportKey
+ // It is not beneficial for less time consuming operations. Therefore, we perform it synchronously.
+ algorithm->exportKey(format, key, WTFMove(callback), WTFMove(exceptionCallback));
+}
+
+void SubtleCrypto::wrapKey(JSC::JSGlobalObject& state, KeyFormat format, CryptoKey& key, CryptoKey& wrappingKey, AlgorithmIdentifier&& wrapAlgorithmIdentifier, Ref<DeferredPromise>&& promise)
+{
+ bool isEncryption = false;
+
+ auto wrapParamsOrException = normalizeCryptoAlgorithmParameters(state, wrapAlgorithmIdentifier, Operations::WrapKey);
+ if (wrapParamsOrException.hasException()) {
+ ASSERT(wrapParamsOrException.exception().code() != ExistingExceptionError);
+
+ wrapParamsOrException = normalizeCryptoAlgorithmParameters(state, wrapAlgorithmIdentifier, Operations::Encrypt);
+ if (wrapParamsOrException.hasException()) {
+ promise->reject(wrapParamsOrException.releaseException());
+ return;
+ }
+
+ isEncryption = true;
+ }
+ auto wrapParams = wrapParamsOrException.releaseReturnValue();
+
+ if (wrapParams->identifier != wrappingKey.algorithmIdentifier()) {
+ promise->reject(InvalidAccessError, "Wrapping CryptoKey doesn't match AlgorithmIdentifier"_s);
+ return;
+ }
+
+ if (!wrappingKey.allows(CryptoKeyUsageWrapKey)) {
+ promise->reject(InvalidAccessError, "Wrapping CryptoKey doesn't support wrapKey operation"_s);
+ return;
+ }
+
+ if (!isSupportedExportKey(key.algorithmIdentifier())) {
+ promise->reject(Exception { NotSupportedError });
+ return;
+ }
+
+ if (!key.extractable()) {
+ promise->reject(InvalidAccessError, "The CryptoKey is nonextractable"_s);
+ return;
+ }
+
+ auto exportAlgorithm = CryptoAlgorithmRegistry::singleton().create(key.algorithmIdentifier());
+ auto wrapAlgorithm = CryptoAlgorithmRegistry::singleton().create(wrappingKey.algorithmIdentifier());
+
+ auto context = scriptExecutionContext();
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis, wrapAlgorithm, wrappingKey = Ref { wrappingKey }, wrapParams = WTFMove(wrapParams), isEncryption, context, workQueue = m_workQueue](SubtleCrypto::KeyFormat format, KeyData&& key) mutable {
+ if (weakThis) {
+ if (auto promise = weakThis->m_pendingPromises.get(index)) {
+ Vector<uint8_t> bytes;
+ switch (format) {
+ case SubtleCrypto::KeyFormat::Spki:
+ case SubtleCrypto::KeyFormat::Pkcs8:
+ case SubtleCrypto::KeyFormat::Raw:
+ bytes = std::get<Vector<uint8_t>>(key);
+ break;
+ case SubtleCrypto::KeyFormat::Jwk: {
+ // FIXME: Converting to JS just to JSON-Stringify seems inefficient. We should find a way to go directly from the struct to JSON.
+ auto jwk = toJS<IDLDictionary<JsonWebKey>>(*(promise->globalObject()), *(promise->globalObject()), WTFMove(std::get<JsonWebKey>(key)));
+ String jwkString = JSONStringify(promise->globalObject(), jwk, 0);
+ CString jwkUTF8String = jwkString.utf8(StrictConversion);
+ bytes.append(jwkUTF8String.data(), jwkUTF8String.length());
+ }
+ }
+
+ auto callback = [index, weakThis](const Vector<uint8_t>& wrappedKey) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ fulfillPromiseWithArrayBuffer(promise.releaseNonNull(), wrappedKey.data(), wrappedKey.size());
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ if (!isEncryption) {
+ // The 11 December 2014 version of the specification suggests we should perform the following task asynchronously:
+ // https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-wrapKey
+ // It is not beneficial for less time consuming operations. Therefore, we perform it synchronously.
+ wrapAlgorithm->wrapKey(wrappingKey.get(), WTFMove(bytes), WTFMove(callback), WTFMove(exceptionCallback));
+ return;
+ }
+ // The following operation should be performed asynchronously.
+ wrapAlgorithm->encrypt(*wrapParams, WTFMove(wrappingKey), WTFMove(bytes), WTFMove(callback), WTFMove(exceptionCallback), *context, workQueue);
+ }
+ }
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ // The following operation should be performed synchronously.
+ exportAlgorithm->exportKey(format, key, WTFMove(callback), WTFMove(exceptionCallback));
+}
+
+void SubtleCrypto::unwrapKey(JSC::JSGlobalObject& state, KeyFormat format, BufferSource&& wrappedKeyBufferSource, CryptoKey& unwrappingKey, AlgorithmIdentifier&& unwrapAlgorithmIdentifier, AlgorithmIdentifier&& unwrappedKeyAlgorithmIdentifier, bool extractable, Vector<CryptoKeyUsage>&& keyUsages, Ref<DeferredPromise>&& promise)
+{
+ auto wrappedKey = copyToVector(WTFMove(wrappedKeyBufferSource));
+
+ bool isDecryption = false;
+
+ auto unwrapParamsOrException = normalizeCryptoAlgorithmParameters(state, unwrapAlgorithmIdentifier, Operations::UnwrapKey);
+ if (unwrapParamsOrException.hasException()) {
+ unwrapParamsOrException = normalizeCryptoAlgorithmParameters(state, unwrapAlgorithmIdentifier, Operations::Decrypt);
+ if (unwrapParamsOrException.hasException()) {
+ promise->reject(unwrapParamsOrException.releaseException());
+ return;
+ }
+
+ isDecryption = true;
+ }
+ auto unwrapParams = unwrapParamsOrException.releaseReturnValue();
+
+ auto unwrappedKeyAlgorithmOrException = normalizeCryptoAlgorithmParameters(state, unwrappedKeyAlgorithmIdentifier, Operations::ImportKey);
+ if (unwrappedKeyAlgorithmOrException.hasException()) {
+ promise->reject(unwrappedKeyAlgorithmOrException.releaseException());
+ return;
+ }
+ auto unwrappedKeyAlgorithm = unwrappedKeyAlgorithmOrException.releaseReturnValue();
+
+ auto keyUsagesBitmap = toCryptoKeyUsageBitmap(keyUsages);
+
+ if (unwrapParams->identifier != unwrappingKey.algorithmIdentifier()) {
+ promise->reject(InvalidAccessError, "Unwrapping CryptoKey doesn't match unwrap AlgorithmIdentifier"_s);
+ return;
+ }
+
+ if (!unwrappingKey.allows(CryptoKeyUsageUnwrapKey)) {
+ promise->reject(InvalidAccessError, "Unwrapping CryptoKey doesn't support unwrapKey operation"_s);
+ return;
+ }
+
+ auto importAlgorithm = CryptoAlgorithmRegistry::singleton().create(unwrappedKeyAlgorithm->identifier);
+ if (UNLIKELY(!importAlgorithm)) {
+ promise->reject(Exception { NotSupportedError });
+ return;
+ }
+
+ auto unwrapAlgorithm = CryptoAlgorithmRegistry::singleton().create(unwrappingKey.algorithmIdentifier());
+ if (UNLIKELY(!unwrapAlgorithm)) {
+ promise->reject(Exception { NotSupportedError });
+ return;
+ }
+
+ auto index = promise.ptr();
+ m_pendingPromises.add(index, WTFMove(promise));
+ WeakPtr weakThis { *this };
+ auto callback = [index, weakThis, format, importAlgorithm, unwrappedKeyAlgorithm = crossThreadCopyImportParams(*unwrappedKeyAlgorithm), extractable, keyUsagesBitmap](const Vector<uint8_t>& bytes) mutable {
+ if (weakThis) {
+ if (RefPtr promise = weakThis->m_pendingPromises.get(index)) {
+ KeyData keyData;
+ switch (format) {
+ case SubtleCrypto::KeyFormat::Spki:
+ case SubtleCrypto::KeyFormat::Pkcs8:
+ case SubtleCrypto::KeyFormat::Raw:
+ keyData = bytes;
+ break;
+ case SubtleCrypto::KeyFormat::Jwk: {
+ auto& state = *(promise->globalObject());
+ auto& vm = state.vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ String jwkString(bytes.data(), bytes.size());
+ JSLockHolder locker(vm);
+ auto jwkObject = JSONParse(&state, jwkString);
+ if (!jwkObject) {
+ promise->reject(DataError, "WrappedKey cannot be converted to a JSON object"_s);
+ return;
+ }
+ auto jwk = convert<IDLDictionary<JsonWebKey>>(state, jwkObject);
+ RETURN_IF_EXCEPTION(scope, void());
+ normalizeJsonWebKey(jwk);
+
+ keyData = jwk;
+ break;
+ }
+ }
+
+ auto callback = [index, weakThis](CryptoKey& key) mutable {
+ if (auto promise = getPromise(index, weakThis)) {
+ if ((key.type() == CryptoKeyType::Private || key.type() == CryptoKeyType::Secret) && !key.usagesBitmap()) {
+ rejectWithException(promise.releaseNonNull(), SyntaxError);
+ return;
+ }
+ promise->resolve<IDLInterface<CryptoKey>>(key);
+ }
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ // The following operation should be performed synchronously.
+ importAlgorithm->importKey(format, WTFMove(keyData), *unwrappedKeyAlgorithm, extractable, keyUsagesBitmap, WTFMove(callback), WTFMove(exceptionCallback));
+ }
+ }
+ };
+ auto exceptionCallback = [index, weakThis](ExceptionCode ec) mutable {
+ if (auto promise = getPromise(index, weakThis))
+ rejectWithException(promise.releaseNonNull(), ec);
+ };
+
+ if (!isDecryption) {
+ // The 11 December 2014 version of the specification suggests we should perform the following task asynchronously:
+ // https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-unwrapKey
+ // It is not beneficial for less time consuming operations. Therefore, we perform it synchronously.
+ unwrapAlgorithm->unwrapKey(unwrappingKey, WTFMove(wrappedKey), WTFMove(callback), WTFMove(exceptionCallback));
+ return;
+ }
+
+ unwrapAlgorithm->decrypt(*unwrapParams, unwrappingKey, WTFMove(wrappedKey), WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContext(), m_workQueue);
+}
+
+}
+
+#endif
diff --git a/src/bun.js/bindings/webcrypto/SubtleCrypto.h b/src/bun.js/bindings/webcrypto/SubtleCrypto.h
new file mode 100644
index 000000000..5ee622250
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/SubtleCrypto.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_CRYPTO)
+
+#include "ContextDestructionObserver.h"
+#include "CryptoKeyFormat.h"
+#include <JavaScriptCore/Strong.h>
+#include <variant>
+#include <wtf/Ref.h>
+#include <wtf/RefCounted.h>
+#include <wtf/WeakPtr.h>
+#include <wtf/WorkQueue.h>
+
+namespace JSC {
+class ArrayBufferView;
+class ArrayBuffer;
+class CallFrame;
+}
+
+namespace WebCore {
+
+struct JsonWebKey;
+
+class BufferSource;
+class CryptoKey;
+class DeferredPromise;
+
+enum class CryptoAlgorithmIdentifier;
+enum class CryptoKeyUsage;
+
+class SubtleCrypto : public ContextDestructionObserver, public RefCounted<SubtleCrypto>, public CanMakeWeakPtr<SubtleCrypto> {
+public:
+ static Ref<SubtleCrypto> create(ScriptExecutionContext* context) { return adoptRef(*new SubtleCrypto(context)); }
+ ~SubtleCrypto();
+
+ using KeyFormat = CryptoKeyFormat;
+
+ using AlgorithmIdentifier = std::variant<JSC::Strong<JSC::JSObject>, String>;
+ using KeyDataVariant = std::variant<RefPtr<JSC::ArrayBufferView>, RefPtr<JSC::ArrayBuffer>, JsonWebKey>;
+
+ void encrypt(JSC::JSGlobalObject&, AlgorithmIdentifier&&, CryptoKey&, BufferSource&& data, Ref<DeferredPromise>&&);
+ void decrypt(JSC::JSGlobalObject&, AlgorithmIdentifier&&, CryptoKey&, BufferSource&& data, Ref<DeferredPromise>&&);
+ void sign(JSC::JSGlobalObject&, AlgorithmIdentifier&&, CryptoKey&, BufferSource&& data, Ref<DeferredPromise>&&);
+ void verify(JSC::JSGlobalObject&, AlgorithmIdentifier&&, CryptoKey&, BufferSource&& signature, BufferSource&& data, Ref<DeferredPromise>&&);
+ void digest(JSC::JSGlobalObject&, AlgorithmIdentifier&&, BufferSource&& data, Ref<DeferredPromise>&&);
+ void generateKey(JSC::JSGlobalObject&, AlgorithmIdentifier&&, bool extractable, Vector<CryptoKeyUsage>&& keyUsages, Ref<DeferredPromise>&&);
+ void deriveKey(JSC::JSGlobalObject&, AlgorithmIdentifier&&, CryptoKey& baseKey, AlgorithmIdentifier&& derivedKeyType, bool extractable, Vector<CryptoKeyUsage>&&, Ref<DeferredPromise>&&);
+ void deriveBits(JSC::JSGlobalObject&, AlgorithmIdentifier&&, CryptoKey& baseKey, unsigned length, Ref<DeferredPromise>&&);
+ void importKey(JSC::JSGlobalObject&, KeyFormat, KeyDataVariant&&, AlgorithmIdentifier&&, bool extractable, Vector<CryptoKeyUsage>&&, Ref<DeferredPromise>&&);
+ void exportKey(KeyFormat, CryptoKey&, Ref<DeferredPromise>&&);
+ void wrapKey(JSC::JSGlobalObject&, KeyFormat, CryptoKey&, CryptoKey& wrappingKey, AlgorithmIdentifier&& wrapAlgorithm, Ref<DeferredPromise>&&);
+ void unwrapKey(JSC::JSGlobalObject&, KeyFormat, BufferSource&& wrappedKey, CryptoKey& unwrappingKey, AlgorithmIdentifier&& unwrapAlgorithm, AlgorithmIdentifier&& unwrappedKeyAlgorithm, bool extractable, Vector<CryptoKeyUsage>&&, Ref<DeferredPromise>&&);
+
+private:
+ explicit SubtleCrypto(ScriptExecutionContext*);
+
+ void addAuthenticatedEncryptionWarningIfNecessary(CryptoAlgorithmIdentifier);
+ inline friend RefPtr<DeferredPromise> getPromise(DeferredPromise*, WeakPtr<SubtleCrypto>);
+
+ Ref<WorkQueue> m_workQueue;
+ HashMap<DeferredPromise*, Ref<DeferredPromise>> m_pendingPromises;
+};
+
+}
+
+#endif
diff --git a/src/bun.js/bindings/webcrypto/SubtleCrypto.idl b/src/bun.js/bindings/webcrypto/SubtleCrypto.idl
new file mode 100644
index 000000000..358b9950b
--- /dev/null
+++ b/src/bun.js/bindings/webcrypto/SubtleCrypto.idl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+enum KeyFormat { "raw", "spki", "pkcs8", "jwk" };
+
+typedef (object or DOMString) AlgorithmIdentifier;
+
+[
+ Conditional=WEB_CRYPTO,
+ Exposed=(Window,Worker),
+ GenerateIsReachable=ImplScriptExecutionContext,
+ SecureContext,
+] interface SubtleCrypto {
+ [CallWith=CurrentGlobalObject] Promise<any> encrypt(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource data);
+ [CallWith=CurrentGlobalObject] Promise<any> decrypt(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource data);
+ [CallWith=CurrentGlobalObject] Promise<any> sign(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource data);
+ [CallWith=CurrentGlobalObject] Promise<any> verify(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource signature, BufferSource data);
+ [CallWith=CurrentGlobalObject] Promise<any> digest(AlgorithmIdentifier algorithm, BufferSource data);
+ [CallWith=CurrentGlobalObject] Promise<any> generateKey(AlgorithmIdentifier algorithm, boolean extractable, sequence<CryptoKeyUsage> keyUsages);
+ [CallWith=CurrentGlobalObject] Promise<any> deriveKey(AlgorithmIdentifier algorithm, CryptoKey baseKey, AlgorithmIdentifier derivedKeyType, boolean extractable, sequence<CryptoKeyUsage> keyUsages);
+ [CallWith=CurrentGlobalObject] Promise<ArrayBuffer> deriveBits(AlgorithmIdentifier algorithm, CryptoKey baseKey, unsigned long length);
+ [CallWith=CurrentGlobalObject] Promise<CryptoKey> importKey(KeyFormat format, (BufferSource or JsonWebKey) keyData, AlgorithmIdentifier algorithm, boolean extractable, sequence<CryptoKeyUsage> keyUsages);
+ Promise<any> exportKey(KeyFormat format, CryptoKey key);
+ [CallWith=CurrentGlobalObject] Promise<any> wrapKey(KeyFormat format, CryptoKey key, CryptoKey wrappingKey, AlgorithmIdentifier wrapAlgorithm);
+ [CallWith=CurrentGlobalObject] Promise<CryptoKey> unwrapKey(KeyFormat format, BufferSource wrappedKey, CryptoKey unwrappingKey, AlgorithmIdentifier unwrapAlgorithm, AlgorithmIdentifier unwrappedKeyAlgorithm, boolean extractable, sequence<CryptoKeyUsage> keyUsages);
+};
diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig
index e17652754..d87a7edcb 100644
--- a/src/bun.js/event_loop.zig
+++ b/src/bun.js/event_loop.zig
@@ -204,6 +204,7 @@ const UnboundedQueue = @import("./unbounded_queue.zig").UnboundedQueue;
pub const ConcurrentTask = struct {
task: Task = undefined,
next: ?*ConcurrentTask = null,
+ auto_delete: bool = false,
pub const Queue = UnboundedQueue(ConcurrentTask, .next);
@@ -326,6 +327,7 @@ pub const EventLoop = struct {
writable[0] = task.task;
writable = writable[1..];
this.tasks.count += 1;
+ if (task.auto_delete) bun.default_allocator.destroy(task);
if (writable.len == 0) break;
}
diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig
index 07c5318b2..9ba69aaa2 100644
--- a/src/bun.js/javascript.zig
+++ b/src/bun.js/javascript.zig
@@ -273,7 +273,8 @@ comptime {
_ = Bun__getDefaultGlobal;
_ = Bun__getVM;
_ = Bun__drainMicrotasks;
- _ = Bun__queueMicrotask;
+ _ = Bun__queueTask;
+ _ = Bun__queueTaskConcurrently;
_ = Bun__handleRejectedPromise;
_ = Bun__readOriginTimer;
_ = Bun__onDidAppendPlugin;
@@ -281,10 +282,24 @@ comptime {
}
}
-pub export fn Bun__queueMicrotask(global: *JSGlobalObject, task: *JSC.CppTask) void {
+/// This function is called on the main thread
+/// The bunVM() call will assert this
+pub export fn Bun__queueTask(global: *JSGlobalObject, task: *JSC.CppTask) void {
global.bunVM().eventLoop().enqueueTask(Task.init(task));
}
+/// This function is called on another thread
+/// The main difference: we need to allocate the task & wakeup the thread
+/// We can avoid that if we run it from the main thread.
+pub export fn Bun__queueTaskConcurrently(global: *JSGlobalObject, task: *JSC.CppTask) void {
+ var concurrent = bun.default_allocator.create(JSC.ConcurrentTask) catch unreachable;
+ concurrent.* = JSC.ConcurrentTask{
+ .task = Task.init(task),
+ .auto_delete = true,
+ };
+ global.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(concurrent);
+}
+
pub export fn Bun__handleRejectedPromise(global: *JSGlobalObject, promise: *JSC.JSPromise) void {
const result = promise.result(global.vm());
global.bunVM().runErrorHandler(result, null);
diff --git a/src/bun.js/webcore.zig b/src/bun.js/webcore.zig
index ffc12ab99..c8bf7545d 100644
--- a/src/bun.js/webcore.zig
+++ b/src/bun.js/webcore.zig
@@ -395,19 +395,7 @@ pub const Crypto = struct {
};
var slice = array_buffer.byteSlice();
- switch (slice.len) {
- 0 => {},
- 1...JSC.RareData.EntropyCache.size / 8 => {
- if (arguments.len > 1) {
- bun.rand(slice);
- } else {
- std.mem.copy(u8, slice, globalThis.bunVM().rareData().entropySlice(slice.len));
- }
- },
- else => {
- bun.rand(slice);
- },
- }
+ randomData(globalThis, slice.ptr, slice.len);
return arguments[0];
}
@@ -418,6 +406,17 @@ pub const Crypto = struct {
array: *JSC.JSUint8Array,
) callconv(.C) JSC.JSValue {
var slice = array.slice();
+ randomData(globalThis, slice.ptr, slice.len);
+ return @intToEnum(JSC.JSValue, @bitCast(i64, @ptrToInt(array)));
+ }
+
+ fn randomData(
+ globalThis: *JSC.JSGlobalObject,
+ ptr: [*]u8,
+ len: usize,
+ ) void {
+ var slice = ptr[0..len];
+
switch (slice.len) {
0 => {},
// 512 bytes or less we reuse from the same cache as UUID generation.
@@ -428,8 +427,6 @@ pub const Crypto = struct {
bun.rand(slice);
},
}
-
- return @intToEnum(JSC.JSValue, @bitCast(i64, @ptrToInt(array)));
}
pub fn randomUUID(