diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e7023a68fb..bae886562c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -91,6 +91,9 @@ jobs: working-directory: ./test - name: Test Node.js crypto run: npm run test + - name: Test Node.js crypto w/ CryptoKey + run: npm run test-cryptokey + if: ${{ !startsWith(matrix.node-version, '14') && !startsWith(matrix.node-version, '12') }} - name: Test Web Cryptography API run: npm run test-webcrypto if: ${{ !startsWith(matrix.node-version, '14') && !startsWith(matrix.node-version, '12') }} diff --git a/package.json b/package.json index 65d11f7573..94e7f25a64 100644 --- a/package.json +++ b/package.json @@ -327,6 +327,7 @@ "build:node-webcrypto-esm": "run-s runtime-node-webcrypto lint 'build -- -p ./tsconfig/node-webcrypto-esm.json' && echo '{\"type\": \"module\"}'> dist/node/webcrypto/esm/package.json", "clear": "rm -rf dist", "coverage": "npm run-script runtime-node && c8 npm run-script test", + "coverage-cryptokey": "npm run-script runtime-node && c8 npm run-script test-cryptokey", "coverage-webcrypto": "npm run-script runtime-node-webcrypto && c8 npm run-script test-webcrypto", "docs": "run-s docs:*", "docs:generate": "typedoc --disableOutputCheck --excludeNotExported --excludePrivate --excludeProtected --gitRevision main --readme none --listInvalidSymbolLinks --plugin typedoc-plugin-markdown --out docs --includeDeclarations --excludeExternals --tsconfig ./tsconfig/browser.json --mode modules src/types.d.ts src/jwt/*.ts src/jwe/**/*.ts src/jws/**/*.ts src/jwk/*.ts src/jwks/*.ts src/util/*.ts --hideProjectName --hideGenerator --allReflectionsHaveOwnDocument --hideBreadcrumbs", @@ -343,6 +344,7 @@ "test": "npm run-script test-cjs && ava", "test-browser": "find test-browser -type f -name '*.js' -print0 | xargs -0 npx esbuild --outdir=dist-browser-tests --bundle && karma start", "test-cjs": "rm -rf test/cjs && find test -type f -name '*.mjs' -print0 | xargs -0 npx esbuild --target=esnext --outdir=test/cjs --format=cjs", + "test-cryptokey": "CRYPTOKEY=true npm test", "test-webcrypto": "WEBCRYPTO=true npm test" }, "devDependencies": { diff --git a/src/runtime/node/aesgcmkw.ts b/src/runtime/node/aesgcmkw.ts index 7e75d35ec5..20799148a2 100644 --- a/src/runtime/node/aesgcmkw.ts +++ b/src/runtime/node/aesgcmkw.ts @@ -1,17 +1,17 @@ -import type { KeyObject } from 'crypto' - import type { AesGcmKwWrapFunction, AesGcmKwUnwrapFunction } from '../interfaces.d' import encrypt from './encrypt.js' import decrypt from './decrypt.js' import ivFactory from '../../lib/iv.js' import random from './random.js' import { encode as base64url } from './base64url.js' +import { isCryptoKey, getKeyObject } from './webcrypto.js' +import type { KeyLike } from '../../types.d' const generateIv = ivFactory(random) export const wrap: AesGcmKwWrapFunction = async ( alg: string, - key: KeyObject | Uint8Array, + key: KeyLike, cek: Uint8Array, iv?: Uint8Array, ) => { @@ -19,6 +19,11 @@ export const wrap: AesGcmKwWrapFunction = async ( // eslint-disable-next-line no-param-reassign iv ||= generateIv(jweAlgorithm) + if (isCryptoKey(key)) { + // eslint-disable-next-line no-param-reassign + key = getKeyObject(key) + } + const { ciphertext: encryptedKey, tag } = await encrypt( jweAlgorithm, cek, @@ -32,13 +37,18 @@ export const wrap: AesGcmKwWrapFunction = async ( export const unwrap: AesGcmKwUnwrapFunction = async ( alg: string, - key: KeyObject | Uint8Array, + key: KeyLike, encryptedKey: Uint8Array, iv: Uint8Array, tag: Uint8Array, ) => { const jweAlgorithm = alg.substr(0, 7) + if (isCryptoKey(key)) { + // eslint-disable-next-line no-param-reassign + key = getKeyObject(key) + } + return decrypt( jweAlgorithm, key instanceof Uint8Array ? key : key.export(), diff --git a/src/runtime/node/aeskw.ts b/src/runtime/node/aeskw.ts index c3afba93b9..103ef0466d 100644 --- a/src/runtime/node/aeskw.ts +++ b/src/runtime/node/aeskw.ts @@ -4,6 +4,8 @@ import { JOSENotSupported } from '../../util/errors.js' import type { AesKwUnwrapFunction, AesKwWrapFunction } from '../interfaces.d' import { concat } from '../../lib/buffer_utils.js' import getSecretKey from './secret_key.js' +import type { KeyLike } from '../../types.d' +import { isCryptoKey, getKeyObject } from './webcrypto.js' function checkKeySize(key: KeyObject, alg: string) { if (key.symmetricKeySize! << 3 !== parseInt(alg.substr(1, 3), 10)) { @@ -11,11 +13,7 @@ function checkKeySize(key: KeyObject, alg: string) { } } -export const wrap: AesKwWrapFunction = async ( - alg: string, - key: KeyObject | Uint8Array, - cek: Uint8Array, -) => { +export const wrap: AesKwWrapFunction = async (alg: string, key: KeyLike, cek: Uint8Array) => { const size = parseInt(alg.substr(1, 3), 10) const algorithm = `aes${size}-wrap` if (!getCiphers().includes(algorithm)) { @@ -23,7 +21,14 @@ export const wrap: AesKwWrapFunction = async ( `alg ${alg} is unsupported either by JOSE or your javascript runtime`, ) } - const keyObject = getSecretKey(key) + let keyObject: KeyObject + if (key instanceof Uint8Array) { + keyObject = getSecretKey(key) + } else if (isCryptoKey(key)) { + keyObject = getKeyObject(key) + } else { + keyObject = key + } checkKeySize(keyObject, alg) const cipher = createCipheriv(algorithm, keyObject, Buffer.alloc(8, 0xa6)) return concat(cipher.update(cek), cipher.final()) @@ -31,7 +36,7 @@ export const wrap: AesKwWrapFunction = async ( export const unwrap: AesKwUnwrapFunction = async ( alg: string, - key: KeyObject | Uint8Array, + key: KeyLike, encryptedKey: Uint8Array, ) => { const size = parseInt(alg.substr(1, 3), 10) @@ -41,7 +46,14 @@ export const unwrap: AesKwUnwrapFunction = async ( `alg ${alg} is unsupported either by JOSE or your javascript runtime`, ) } - const keyObject = getSecretKey(key) + let keyObject: KeyObject + if (key instanceof Uint8Array) { + keyObject = getSecretKey(key) + } else if (isCryptoKey(key)) { + keyObject = getKeyObject(key) + } else { + keyObject = key + } checkKeySize(keyObject, alg) const cipher = createDecipheriv(algorithm, keyObject, Buffer.alloc(8, 0xa6)) return concat(cipher.update(encryptedKey), cipher.final()) diff --git a/src/runtime/node/check_cek_length.ts b/src/runtime/node/check_cek_length.ts index a5c5dd7abe..c6a170be0c 100644 --- a/src/runtime/node/check_cek_length.ts +++ b/src/runtime/node/check_cek_length.ts @@ -1,7 +1,7 @@ import { KeyObject } from 'crypto' import { JWEInvalid, JOSENotSupported } from '../../util/errors.js' -const checkCekLength = (enc: string, cek: Uint8Array | KeyObject) => { +const checkCekLength = (enc: string, cek: KeyObject | Uint8Array) => { let expected: number switch (enc) { case 'A128CBC-HS256': diff --git a/src/runtime/node/decrypt.ts b/src/runtime/node/decrypt.ts index 722c9f98b3..580a3606cc 100644 --- a/src/runtime/node/decrypt.ts +++ b/src/runtime/node/decrypt.ts @@ -8,10 +8,12 @@ import { concat } from '../../lib/buffer_utils.js' import { JOSENotSupported, JWEDecryptionFailed } from '../../util/errors.js' import timingSafeEqual from './timing_safe_equal.js' import cbcTag from './cbc_tag.js' +import { isCryptoKey, getKeyObject } from './webcrypto.js' +import type { KeyLike } from '../../types.d' async function cbcDecrypt( enc: string, - cek: Uint8Array | KeyObject, + cek: KeyObject | Uint8Array, ciphertext: Uint8Array, iv: Uint8Array, tag: Uint8Array, @@ -58,7 +60,7 @@ async function cbcDecrypt( } async function gcmDecrypt( enc: string, - cek: Uint8Array | KeyObject, + cek: KeyObject | Uint8Array, ciphertext: Uint8Array, iv: Uint8Array, tag: Uint8Array, @@ -83,12 +85,17 @@ async function gcmDecrypt( const decrypt: DecryptFunction = async ( enc: string, - cek: Uint8Array | KeyObject, + cek: KeyLike, ciphertext: Uint8Array, iv: Uint8Array, tag: Uint8Array, aad: Uint8Array, ) => { + if (isCryptoKey(cek)) { + // eslint-disable-next-line no-param-reassign + cek = getKeyObject(cek) + } + checkCekLength(enc, cek) checkIvLength(enc, iv) diff --git a/src/runtime/node/ecdhes.ts b/src/runtime/node/ecdhes.ts index 9d5b75b6b2..933e37a204 100644 --- a/src/runtime/node/ecdhes.ts +++ b/src/runtime/node/ecdhes.ts @@ -21,14 +21,15 @@ import { import type { EpkJwk } from '../../types.i.d' import digest from './digest.js' import { JOSENotSupported } from '../../util/errors.js' +import { isCryptoKey, getKeyObject } from './webcrypto.js' const generateKeyPair = promisify(generateKeyPairCb) const concatKdf = KDF.bind(undefined, digest.bind(undefined, 'sha256')) export const deriveKey: EcdhESDeriveKeyFunction = async ( - publicKey: KeyObject, - privateKey: KeyObject, + publicKey: KeyObject | CryptoKey, + privateKey: KeyObject | CryptoKey, algorithm: string, keyLength: number, apu: Uint8Array = new Uint8Array(0), @@ -41,13 +42,27 @@ export const deriveKey: EcdhESDeriveKeyFunction = async ( uint32be(keyLength), ) + if (isCryptoKey(publicKey)) { + // eslint-disable-next-line no-param-reassign + publicKey = getKeyObject(publicKey) + } + + if (isCryptoKey(privateKey)) { + // eslint-disable-next-line no-param-reassign + privateKey = getKeyObject(privateKey) + } + const sharedSecret = diffieHellman({ privateKey, publicKey }) return concatKdf(sharedSecret, keyLength, value) } export const ephemeralKeyToPublicJWK: EphemeralKeyToPublicJwkFunction = function ephemeralKeyToPublicJWK( - key: KeyObject, + key: KeyObject | CryptoKey, ) { + if (isCryptoKey(key)) { + // eslint-disable-next-line no-param-reassign + key = getKeyObject(key) + } switch (key.asymmetricKeyType) { case 'x25519': case 'x448': { @@ -72,7 +87,11 @@ export const ephemeralKeyToPublicJWK: EphemeralKeyToPublicJwkFunction = function } } -export const generateEpk: GenerateEpkFunction = async (key: KeyObject) => { +export const generateEpk: GenerateEpkFunction = async (key: KeyObject | CryptoKey) => { + if (isCryptoKey(key)) { + // eslint-disable-next-line no-param-reassign + key = getKeyObject(key) + } switch (key.asymmetricKeyType) { case 'x25519': return (await generateKeyPair('x25519')).privateKey @@ -134,5 +153,5 @@ export const publicJwkToEphemeralKey: PublicJwkToEphemeralKeyFunction = async (j } const curves = ['P-256', 'P-384', 'P-521', 'X25519', 'X448'] -export const ecdhAllowed: EcdhAllowedFunction = (key: KeyObject) => +export const ecdhAllowed: EcdhAllowedFunction = (key: KeyObject | CryptoKey) => curves.includes(getNamedCurve(key)) diff --git a/src/runtime/node/encrypt.ts b/src/runtime/node/encrypt.ts index 32dd1a354e..31d6d09d60 100644 --- a/src/runtime/node/encrypt.ts +++ b/src/runtime/node/encrypt.ts @@ -6,6 +6,8 @@ import checkIvLength from '../../lib/check_iv_length.js' import checkCekLength from './check_cek_length.js' import { concat } from '../../lib/buffer_utils.js' import cbcTag from './cbc_tag.js' +import type { KeyLike } from '../../types.d' +import { isCryptoKey, getKeyObject } from './webcrypto.js' async function cbcEncrypt( enc: string, @@ -55,10 +57,15 @@ async function gcmEncrypt( const encrypt: EncryptFunction = async ( enc: string, plaintext: Uint8Array, - cek: KeyObject | Uint8Array, + cek: KeyLike, iv: Uint8Array, aad: Uint8Array, ) => { + if (isCryptoKey(cek)) { + // eslint-disable-next-line no-param-reassign + cek = getKeyObject(cek) + } + checkCekLength(enc, cek) checkIvLength(enc, iv) diff --git a/src/runtime/node/get_named_curve.ts b/src/runtime/node/get_named_curve.ts index 78beffc065..3b48cd41bb 100644 --- a/src/runtime/node/get_named_curve.ts +++ b/src/runtime/node/get_named_curve.ts @@ -1,5 +1,6 @@ import { KeyObject, createPublicKey } from 'crypto' import { JOSENotSupported } from '../../util/errors.js' +import { isCryptoKey, getKeyObject } from './webcrypto.js' const p256 = Buffer.from([42, 134, 72, 206, 61, 3, 1, 7]) const p384 = Buffer.from([43, 129, 4, 0, 34]) @@ -23,10 +24,16 @@ const namedCurveToJOSE = (namedCurve: string) => { } } -const getNamedCurve = (key: KeyObject, raw?: boolean): string => { +const getNamedCurve = (key: KeyObject | CryptoKey, raw?: boolean): string => { if (key.type === 'secret') { throw new TypeError('only "private" or "public" key objects can be used for this operation') } + + if (isCryptoKey(key)) { + // eslint-disable-next-line no-param-reassign + key = getKeyObject(key) + } + switch (key.asymmetricKeyType) { case 'ed25519': case 'ed448': diff --git a/src/runtime/node/key_to_jwk.ts b/src/runtime/node/key_to_jwk.ts index d43299b300..a81542931f 100644 --- a/src/runtime/node/key_to_jwk.ts +++ b/src/runtime/node/key_to_jwk.ts @@ -6,8 +6,14 @@ import { encode as base64url } from './base64url.js' import Asn1SequenceDecoder from './asn1_sequence_decoder.js' import { JOSENotSupported } from '../../util/errors.js' import getNamedCurve from './get_named_curve.js' +import { isCryptoKey, getKeyObject } from './webcrypto.js' + +const keyToJWK: JWKConvertFunction = (key: KeyObject | CryptoKey): JWK => { + if (isCryptoKey(key)) { + // eslint-disable-next-line no-param-reassign + key = getKeyObject(key) + } -const keyToJWK: JWKConvertFunction = (key: KeyObject): JWK => { if (!(key instanceof KeyObject)) { throw new TypeError('invalid key argument type') } diff --git a/src/runtime/node/pbes2kw.ts b/src/runtime/node/pbes2kw.ts index b98b102bcd..da95c100eb 100644 --- a/src/runtime/node/pbes2kw.ts +++ b/src/runtime/node/pbes2kw.ts @@ -1,12 +1,12 @@ import { promisify } from 'util' -import type { KeyObject } from 'crypto' -import { pbkdf2 as pbkdf2cb } from 'crypto' +import { KeyObject, pbkdf2 as pbkdf2cb } from 'crypto' import type { Pbes2KWDecryptFunction, Pbes2KWEncryptFunction } from '../interfaces.d' import random from './random.js' import { p2s as concatSalt } from '../../lib/buffer_utils.js' import { encode as base64url } from './base64url.js' import { wrap, unwrap } from './aeskw.js' import checkP2s from '../../lib/check_p2s.js' +import { isCryptoKey, getKeyObject } from './webcrypto.js' const pbkdf2 = promisify(pbkdf2cb) @@ -20,7 +20,15 @@ export const encrypt: Pbes2KWEncryptFunction = async ( checkP2s(p2s) const salt = concatSalt(alg, p2s) const keylen = parseInt(alg.substr(13, 3), 10) >> 3 - const password = key instanceof Uint8Array ? key : key.export() + let password: Uint8Array + + if (isCryptoKey(key)) { + password = getKeyObject(key).export() + } else if (key instanceof KeyObject) { + password = key.export() + } else { + password = key + } const derivedKey = await pbkdf2(password, salt, p2c, keylen, `sha${alg.substr(8, 3)}`) const encryptedKey = await wrap(alg.substr(-6), derivedKey, cek) @@ -37,7 +45,15 @@ export const decrypt: Pbes2KWDecryptFunction = async ( checkP2s(p2s) const salt = concatSalt(alg, p2s) const keylen = parseInt(alg.substr(13, 3), 10) >> 3 - const password = key instanceof Uint8Array ? key : key.export() + let password: Uint8Array + + if (isCryptoKey(key)) { + password = getKeyObject(key).export() + } else if (key instanceof KeyObject) { + password = key.export() + } else { + password = key + } const derivedKey = await pbkdf2(password, salt, p2c, keylen, `sha${alg.substr(8, 3)}`) return unwrap(alg.substr(-6), derivedKey, encryptedKey) diff --git a/src/runtime/node/rsaes.ts b/src/runtime/node/rsaes.ts index 6e55253cd4..3f105a30ed 100644 --- a/src/runtime/node/rsaes.ts +++ b/src/runtime/node/rsaes.ts @@ -2,6 +2,7 @@ import type { KeyObject } from 'crypto' import { publicEncrypt, constants, privateDecrypt } from 'crypto' import type { RsaEsDecryptFunction, RsaEsEncryptFunction } from '../interfaces.d' import checkModulusLength from './check_modulus_length.js' +import { isCryptoKey, getKeyObject } from './webcrypto.js' const checkKey = (key: KeyObject, alg: string) => { if (key.type === 'secret' || key.asymmetricKeyType !== 'rsa') { @@ -41,22 +42,30 @@ const resolveOaepHash = (alg: string) => { export const encrypt: RsaEsEncryptFunction = async ( alg: string, - key: KeyObject, + key: KeyObject | CryptoKey, cek: Uint8Array, ) => { const padding = resolvePadding(alg) const oaepHash = resolveOaepHash(alg) + if (isCryptoKey(key)) { + // eslint-disable-next-line no-param-reassign + key = getKeyObject(key) + } checkKey(key, alg) return publicEncrypt({ key, oaepHash, padding }, cek) } export const decrypt: RsaEsDecryptFunction = async ( alg: string, - key: KeyObject, + key: KeyObject | CryptoKey, encryptedKey: Uint8Array, ) => { const padding = resolvePadding(alg) const oaepHash = resolveOaepHash(alg) + if (isCryptoKey(key)) { + // eslint-disable-next-line no-param-reassign + key = getKeyObject(key) + } checkKey(key, alg) return privateDecrypt({ key, oaepHash, padding }, encryptedKey) } diff --git a/src/runtime/node/sign.ts b/src/runtime/node/sign.ts index d2f5c8cb18..aa20f4c9db 100644 --- a/src/runtime/node/sign.ts +++ b/src/runtime/node/sign.ts @@ -1,17 +1,21 @@ import { sign as oneShotSign, createHmac, KeyObject } from 'crypto' +import type { KeyLike } from '../../types.d' import type { SignFunction } from '../interfaces.d' import nodeDigest from './dsa_digest.js' import hmacDigest from './hmac_digest.js' import nodeKey from './node_key.js' import getSecretKey from './secret_key.js' +import { isCryptoKey, getKeyObject } from './webcrypto.js' -const sign: SignFunction = async (alg, key: KeyObject | Uint8Array, data) => { +const sign: SignFunction = async (alg, key: KeyLike, data) => { let keyObject: KeyObject if (key instanceof Uint8Array) { if (!alg.startsWith('HS')) { throw new TypeError('symmetric keys are only applicable for HMAC-based JWA algorithms') } keyObject = getSecretKey(key) + } else if (isCryptoKey(key)) { + keyObject = getKeyObject(key) } else { keyObject = key } diff --git a/src/runtime/node/verify.ts b/src/runtime/node/verify.ts index 199d716de9..d66b72b4ae 100644 --- a/src/runtime/node/verify.ts +++ b/src/runtime/node/verify.ts @@ -1,11 +1,13 @@ import { verify as oneShotVerify, timingSafeEqual, KeyObject } from 'crypto' +import type { KeyLike } from '../../types.d' import type { VerifyFunction } from '../interfaces.d' import nodeDigest from './dsa_digest.js' import nodeKey from './node_key.js' import sign from './sign.js' +import { isCryptoKey, getKeyObject } from './webcrypto.js' -const verify: VerifyFunction = async (alg, key: KeyObject | Uint8Array, signature, data) => { +const verify: VerifyFunction = async (alg, key: KeyLike, signature, data) => { if (alg.startsWith('HS')) { const expected = await sign(alg, key, data) const actual = signature @@ -19,7 +21,10 @@ const verify: VerifyFunction = async (alg, key: KeyObject | Uint8Array, signatur const algorithm = nodeDigest(alg) - if (!(key instanceof KeyObject)) { + if (isCryptoKey(key)) { + // eslint-disable-next-line no-param-reassign + key = getKeyObject(key) + } else if (!(key instanceof KeyObject)) { throw new TypeError('invalid key object type provided') } diff --git a/src/runtime/node/webcrypto.ts b/src/runtime/node/webcrypto.ts index fe6a98f940..150f578627 100644 --- a/src/runtime/node/webcrypto.ts +++ b/src/runtime/node/webcrypto.ts @@ -1,4 +1,18 @@ import * as crypto from 'crypto' // @ts-expect-error -export default crypto.webcrypto +const webcrypto = crypto.webcrypto + +export default webcrypto +export function isCryptoKey(key: any): key is CryptoKey { + if (webcrypto !== undefined) { + // @ts-expect-error + return key instanceof webcrypto.CryptoKey + } + + return false +} +export function getKeyObject(key: CryptoKey) { + // @ts-expect-error + return crypto.KeyObject.from(key) +} diff --git a/test/jwe/cookbook.test.mjs b/test/jwe/cookbook.test.mjs index 64b9cf179e..2e991224e2 100644 --- a/test/jwe/cookbook.test.mjs +++ b/test/jwe/cookbook.test.mjs @@ -1,13 +1,23 @@ import test from 'ava'; -const root = !('WEBCRYPTO' in process.env) ? '#dist' : '#dist/webcrypto'; +let root; +let keyRoot; + +if ('WEBCRYPTO' in process.env) { + root = keyRoot = '#dist/webcrypto'; +} else if ('CRYPTOKEY' in process.env) { + root = '#dist'; + keyRoot = '#dist/webcrypto'; +} else { + root = keyRoot = '#dist'; +} Promise.all([ import(`${root}/jwe/flattened/encrypt`), import(`${root}/jwe/flattened/decrypt`), import(`${root}/jwe/compact/encrypt`), import(`${root}/jwe/compact/decrypt`), - import(`${root}/jwk/parse`), + import(`${keyRoot}/jwk/parse`), import(`${root}/util/base64url`), ]).then( ([ @@ -926,7 +936,7 @@ Promise.all([ for (const vector of vectors) { let conditional; - if ('WEBCRYPTO' in process.env && vector.webcrypto === false) { + if (('WEBCRYPTO' in process.env || 'CRYPTOKEY' in process.env) && vector.webcrypto === false) { conditional = test.failing; } else { conditional = test; diff --git a/test/jwe/smoke.test.mjs b/test/jwe/smoke.test.mjs index b41f92bac7..7f7f3df2cc 100644 --- a/test/jwe/smoke.test.mjs +++ b/test/jwe/smoke.test.mjs @@ -5,15 +5,26 @@ import test from 'ava'; -const root = !('WEBCRYPTO' in process.env) ? '#dist' : '#dist/webcrypto'; +let root; +let keyRoot; + +if ('WEBCRYPTO' in process.env) { + root = keyRoot = '#dist/webcrypto'; +} else if ('CRYPTOKEY' in process.env) { + root = '#dist'; + keyRoot = '#dist/webcrypto'; +} else { + root = keyRoot = '#dist'; +} + Promise.all([ import(`${root}/jwe/flattened/encrypt`), import(`${root}/jwe/flattened/decrypt`), import(`${root}/util/random`), import(`${root}/util/base64url`), - import(`${root}/jwk/parse`), - import(`${root}/util/generate_key_pair`), - import(`${root}/util/generate_secret`), + import(`${keyRoot}/jwk/parse`), + import(`${keyRoot}/util/generate_key_pair`), + import(`${keyRoot}/util/generate_secret`), ]).then( ([ { default: FlattenedEncrypt }, @@ -288,7 +299,7 @@ Promise.all([ test('as keyobject (deriveKey)', smoke, 'octAny', ['deriveKey'], ['deriveKey'], true); let conditional; - if ('WEBCRYPTO' in process.env) { + if ('WEBCRYPTO' in process.env || 'CRYPTOKEY' in process.env) { conditional = test.failing; } else { conditional = test; diff --git a/test/jwk/embedded.test.mjs b/test/jwk/embedded.test.mjs index e2072adf43..e645929068 100644 --- a/test/jwk/embedded.test.mjs +++ b/test/jwk/embedded.test.mjs @@ -1,12 +1,23 @@ /* eslint-disable no-param-reassign */ import test from 'ava'; -const root = !('WEBCRYPTO' in process.env) ? '#dist' : '#dist/webcrypto'; +let root; +let keyRoot; + +if ('WEBCRYPTO' in process.env) { + root = keyRoot = '#dist/webcrypto'; +} else if ('CRYPTOKEY' in process.env) { + root = '#dist'; + keyRoot = '#dist/webcrypto'; +} else { + root = keyRoot = '#dist'; +} + Promise.all([ import(`${root}/jws/flattened/sign`), import(`${root}/jws/flattened/verify`), - import(`${root}/jwk/parse`), - import(`${root}/jwk/embedded`), + import(`${keyRoot}/jwk/parse`), + import(`${keyRoot}/jwk/embedded`), ]).then( ([ { default: FlattenedSign }, diff --git a/test/jwks/remote.test.mjs b/test/jwks/remote.test.mjs index bd62c9bf18..7451d4a45c 100644 --- a/test/jwks/remote.test.mjs +++ b/test/jwks/remote.test.mjs @@ -3,12 +3,23 @@ import test from 'ava'; import nock from 'nock'; import timekeeper from 'timekeeper'; -const root = !('WEBCRYPTO' in process.env) ? '#dist' : '#dist/webcrypto'; +let root; +let keyRoot; + +if ('WEBCRYPTO' in process.env) { + root = keyRoot = '#dist/webcrypto'; +} else if ('CRYPTOKEY' in process.env) { + root = '#dist'; + keyRoot = '#dist/webcrypto'; +} else { + root = keyRoot = '#dist'; +} + Promise.all([ import(`${root}/jwt/verify`), import(`${root}/jwt/sign`), - import(`${root}/jwk/parse`), - import(`${root}/jwks/remote`), + import(`${keyRoot}/jwk/parse`), + import(`${keyRoot}/jwks/remote`), ]).then( ([ { default: jwtVerify }, diff --git a/test/jws/cookbook.test.mjs b/test/jws/cookbook.test.mjs index 106b841cee..a0a92f6a9c 100644 --- a/test/jws/cookbook.test.mjs +++ b/test/jws/cookbook.test.mjs @@ -1,13 +1,23 @@ import test from 'ava'; -const root = !('WEBCRYPTO' in process.env) ? '#dist' : '#dist/webcrypto'; +let root; +let keyRoot; + +if ('WEBCRYPTO' in process.env) { + root = keyRoot = '#dist/webcrypto'; +} else if ('CRYPTOKEY' in process.env) { + root = '#dist'; + keyRoot = '#dist/webcrypto'; +} else { + root = keyRoot = '#dist'; +} Promise.all([ import(`${root}/jws/flattened/sign`), import(`${root}/jws/flattened/verify`), import(`${root}/jws/compact/sign`), import(`${root}/jws/compact/verify`), - import(`${root}/jwk/parse`), + import(`${keyRoot}/jwk/parse`), ]).then( ([ { default: FlattenedSign }, @@ -503,7 +513,7 @@ Promise.all([ for (const vector of vectors) { let conditional; - if ('WEBCRYPTO' in process.env && vector.webcrypto === false) { + if (('WEBCRYPTO' in process.env || 'CRYPTOKEY' in process.env) && vector.webcrypto === false) { conditional = test.failing; } else { conditional = test; diff --git a/test/jws/restrictions.test.mjs b/test/jws/restrictions.test.mjs index 461a4bba2e..c47899c3fe 100644 --- a/test/jws/restrictions.test.mjs +++ b/test/jws/restrictions.test.mjs @@ -1,14 +1,25 @@ /* eslint-disable no-param-reassign */ import test from 'ava'; -const root = !('WEBCRYPTO' in process.env) ? '#dist' : '#dist/webcrypto'; +let root; +let keyRoot; + +if ('WEBCRYPTO' in process.env) { + root = keyRoot = '#dist/webcrypto'; +} else if ('CRYPTOKEY' in process.env) { + root = '#dist'; + keyRoot = '#dist/webcrypto'; +} else { + root = keyRoot = '#dist'; +} + Promise.all([ import(`${root}/jws/flattened/sign`), import(`${root}/jws/flattened/verify`), import(`${root}/jwe/flattened/encrypt`), import(`${root}/jwe/flattened/decrypt`), import(`${root}/util/random`), - import(`${root}/jwk/parse`), + import(`${keyRoot}/jwk/parse`), ]).then( ([ { default: FlattenedSign }, @@ -145,7 +156,7 @@ Promise.all([ test(testRSAenc, 'RSA-OAEP-512'); let conditional; - if ('WEBCRYPTO' in process.env) { + if ('WEBCRYPTO' in process.env || 'CRYPTOKEY' in process.env) { conditional = test.failing; } else { conditional = test; diff --git a/test/jws/smoke.test.mjs b/test/jws/smoke.test.mjs index a0bd30488d..84b9618e32 100644 --- a/test/jws/smoke.test.mjs +++ b/test/jws/smoke.test.mjs @@ -5,15 +5,26 @@ import test from 'ava'; -const root = !('WEBCRYPTO' in process.env) ? '#dist' : '#dist/webcrypto'; +let root; +let keyRoot; + +if ('WEBCRYPTO' in process.env) { + root = keyRoot = '#dist/webcrypto'; +} else if ('CRYPTOKEY' in process.env) { + root = '#dist'; + keyRoot = '#dist/webcrypto'; +} else { + root = keyRoot = '#dist'; +} + Promise.all([ import(`${root}/jws/flattened/sign`), import(`${root}/jws/flattened/verify`), import(`${root}/util/random`), import(`${root}/util/base64url`), - import(`${root}/jwk/parse`), - import(`${root}/util/generate_key_pair`), - import(`${root}/util/generate_secret`), + import(`${keyRoot}/jwk/parse`), + import(`${keyRoot}/util/generate_key_pair`), + import(`${keyRoot}/util/generate_secret`), ]).then( ([ { default: FlattenedSign }, @@ -211,7 +222,7 @@ Promise.all([ test('as keyobject', smoke, 'oct512', true); let conditional; - if ('WEBCRYPTO' in process.env) { + if ('WEBCRYPTO' in process.env || 'CRYPTOKEY' in process.env) { conditional = test.failing; } else { conditional = test;