Skip to content

Commit

Permalink
fix(deno): ignore incomplete webcrypto api type errors
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Aug 20, 2021
1 parent 319d1c0 commit c5f2262
Show file tree
Hide file tree
Showing 12 changed files with 31 additions and 2 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@
"build-fast:node-webcrypto-cjs": "npm run-script runtime-node-webcrypto && npm run-script -s esbuild-find | xargs -0 esbuild --log-level=warning --platform=node --target=esnext --outdir=dist/node/webcrypto/cjs --format=cjs",
"build-fast:node-webcrypto-esm": "npm run-script runtime-node-webcrypto && npm run-script -s esbuild-find | xargs -0 esbuild --log-level=warning --platform=node --target=esnext --outdir=dist/node/webcrypto/esm --format=esm && echo '{\"type\": \"module\"}'> dist/node/webcrypto/esm/package.json",
"build:browser": "run-s runtime-browser 'build -- -p ./tsconfig/browser.json' && echo '{\"type\": \"module\"}'> dist/browser/package.json",
"build:deno": "npm run-script runtime-deno && find dist/deno -name '*.ts' -type f -print0 | xargs -0 sed -i '' -e \"s/\\.js'/.ts'/g\" -e \"s/\\.d'/.d.ts'/g\" && echo 'export class KeyObject extends CryptoKey {}' > dist/deno/types.d.ts && tail -n +5 src/types.d.ts >> dist/deno/types.d.ts",
"build:deno": "npm run-script runtime-deno && find dist/deno -name '*.ts' -type f -print0 | xargs -0 sed -i '' -e \"s/@deno\\-expect\\-error/@ts-ignore/g\" -e \"s/\\.js'/.ts'/g\" -e \"s/\\.d'/.d.ts'/g\" && echo 'export class KeyObject extends CryptoKey {}' > dist/deno/types.d.ts && tail -n +5 src/types.d.ts >> dist/deno/types.d.ts",
"build:types": "npm run-script build -- -p ./tsconfig/types.json && cd src && find . -name '*.d.ts' -maxdepth 2 -type f -exec gcp --parents \"{}\" ../dist/types \\; && cd .. && node ./tools/strip-dts-comments && run-s -s types:find | xargs -0 sed -i '' -e \"s/\\.js'/'/g\" -e \"s/\\.d'/'/g\"",
"build:node-cjs": "run-s runtime-node 'build -- -p ./tsconfig/node-cjs.json'",
"build:node-esm": "run-s runtime-node 'build -- -p ./tsconfig/node-esm.json' && echo '{\"type\": \"module\"}'> dist/node/esm/package.json",
Expand All @@ -357,7 +357,7 @@
"runtime:node:copy": "cp ./src/runtime/node/*.ts ./src/runtime",
"runtime:refs": "run-s -s runtime:find | xargs -0 sed -i '' -e \"s/'\\.\\.\\//'\\.\\//g\" -e \"s/'\\.\\/\\.\\./'../g\"",
"test": "npm run-script test-cjs && ava",
"test-deno": "deno test --jobs --no-check --allow-net test-deno",
"test-deno": "deno test --jobs --allow-net test-deno",
"test-browser": "find test-browser -type f -name '*.js' -print0 | xargs -0 npx esbuild --log-level=warning --outdir=dist-browser-tests --bundle && karma start",
"test-cjs": "rm -rf test/cjs && find test -type f -name '*.mjs' -print0 | xargs -0 npx esbuild --log-level=warning --target=esnext --outdir=test/cjs --format=cjs",
"test-cryptokey": "CRYPTOKEY=true npm test",
Expand Down
4 changes: 4 additions & 0 deletions src/runtime/browser/aeskw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import crypto, { isCryptoKey } from './webcrypto.js'
import invalidKeyInput from './invalid_key_input.js'

function checkKeySize(key: CryptoKey, alg: string) {
// @deno-expect-error
if ((<AesKeyAlgorithm>key.algorithm).length !== parseInt(alg.substr(1, 3), 10)) {
throw new TypeError(`invalid key size for alg: ${alg}`)
}
Expand All @@ -29,6 +30,7 @@ export const wrap: AesKwWrapFunction = async (alg: string, key: unknown, cek: Ui
// we're importing the cek to end up with CryptoKey instance that can be wrapped, the algorithm used is irrelevant
const cryptoKeyCek = await crypto.subtle.importKey('raw', cek, ...bogusWebCrypto)

// @deno-expect-error
return new Uint8Array(await crypto.subtle.wrapKey('raw', cryptoKeyCek, cryptoKey, 'AES-KW'))
}

Expand All @@ -41,6 +43,7 @@ export const unwrap: AesKwUnwrapFunction = async (

checkKeySize(cryptoKey, alg)

// @deno-expect-error
const cryptoKeyCek = await crypto.subtle.unwrapKey(
'raw',
encryptedKey,
Expand All @@ -49,5 +52,6 @@ export const unwrap: AesKwUnwrapFunction = async (
...bogusWebCrypto,
)

// @deno-expect-error
return new Uint8Array(await crypto.subtle.exportKey('raw', cryptoKeyCek))
}
1 change: 1 addition & 0 deletions src/runtime/browser/check_cek_length.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const checkCekLength = (enc: string, cek: Uint8Array | CryptoKey) => {

// CryptoKey
if (isCryptoKey(cek)) {
// @deno-expect-error
const { length } = <AesKeyAlgorithm>cek.algorithm
if (length !== expected) {
throw new JWEInvalid('Invalid Content Encryption Key length')
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/browser/check_key_length.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
export default (alg: string, key: CryptoKey) => {
if (alg.startsWith('HS')) {
const bitlen = parseInt(alg.substr(-3), 10)
// @deno-expect-error
const { length } = <HmacKeyAlgorithm>key.algorithm
if (typeof length !== 'number' || length < bitlen) {
throw new TypeError(`${alg} requires symmetric keys to be ${bitlen} bits or larger`)
}
}

if (alg.startsWith('RS') || alg.startsWith('PS')) {
// @deno-expect-error
const { modulusLength } = <RsaKeyAlgorithm>key.algorithm
if (typeof modulusLength !== 'number' || modulusLength < 2048) {
throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`)
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/browser/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ async function cbcDecrypt(
let plaintext!: Uint8Array
try {
plaintext = new Uint8Array(
// @deno-expect-error
await crypto.subtle.decrypt({ iv, name: 'AES-CBC' }, encKey, ciphertext),
)
} catch {
Expand All @@ -79,6 +80,7 @@ async function gcmDecrypt(

try {
return new Uint8Array(
// @deno-expect-error
await crypto.subtle.decrypt(
{
additionalData: aad,
Expand Down
4 changes: 4 additions & 0 deletions src/runtime/browser/ecdhes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ export const deriveKey: EcdhESDeriveKeyFunction = async (
}

const sharedSecret = new Uint8Array(
// @deno-expect-error
await crypto.subtle.deriveBits(
{
name: 'ECDH',
public: publicKey,
},
privateKey,
// @deno-expect-error
Math.ceil(parseInt((<EcKeyAlgorithm>privateKey.algorithm).namedCurve.substr(-3), 10) / 8) <<
3,
),
Expand All @@ -56,6 +58,7 @@ export const generateEpk: GenerateEpkFunction = async (key: unknown) => {

return (
await crypto.subtle.generateKey(
// @deno-expect-error
{ name: 'ECDH', namedCurve: (<EcKeyAlgorithm>key.algorithm).namedCurve },
true,
['deriveBits'],
Expand All @@ -67,5 +70,6 @@ export const ecdhAllowed: EcdhAllowedFunction = (key: unknown) => {
if (!isCryptoKey(key)) {
throw new TypeError(invalidKeyInput(key, 'CryptoKey'))
}
// @deno-expect-error
return ['P-256', 'P-384', 'P-521'].includes((<EcKeyAlgorithm>key.algorithm).namedCurve)
}
2 changes: 2 additions & 0 deletions src/runtime/browser/encrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ async function cbcEncrypt(
)

const ciphertext = new Uint8Array(
// @deno-expect-error
await crypto.subtle.encrypt(
{
iv,
Expand Down Expand Up @@ -63,6 +64,7 @@ async function gcmEncrypt(
: cek

const encrypted = new Uint8Array(
// @deno-expect-error
await crypto.subtle.encrypt(
{
additionalData: aad,
Expand Down
1 change: 1 addition & 0 deletions src/runtime/browser/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { GenerateSecretOptions } from '../../util/generate_secret.js'

export async function generateSecret(alg: string, options?: GenerateSecretOptions) {
let length: number
// @deno-expect-error
let algorithm: AesKeyGenParams | HmacKeyGenParams
let keyUsages: KeyUsage[]
switch (alg) {
Expand Down
3 changes: 3 additions & 0 deletions src/runtime/browser/jwk_to_key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import type { JWK } from '../../types.d'
import { decode as base64url } from './base64url.js'

function subtleMapping(jwk: JWK): {
// @deno-expect-error
algorithm: RsaHashedImportParams | EcKeyAlgorithm | Algorithm
keyUsages: KeyUsage[]
} {
// @deno-expect-error
let algorithm: RsaHashedImportParams | EcKeyAlgorithm | Algorithm
let keyUsages: KeyUsage[]

Expand Down Expand Up @@ -116,6 +118,7 @@ const parse: JWKParseFunction = async (jwk: JWK): Promise<CryptoKey> => {
keyData = base64url(jwk.k!)
}
return crypto.subtle.importKey(
// @deno-expect-error
format,
keyData,
algorithm,
Expand Down
1 change: 1 addition & 0 deletions src/runtime/browser/key_to_jwk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const keyToJWK: JWKConvertFunction = async (key: unknown): Promise<JWK> => {
if (!key.extractable) {
throw new TypeError('non-extractable CryptoKey cannot be exported as a JWK')
}
// @deno-expect-error
const { ext, key_ops, alg, use, ...jwk } = await crypto.subtle.exportKey('jwk', key)

return <JWK>jwk
Expand Down
4 changes: 4 additions & 0 deletions src/runtime/browser/pbes2kw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ export const encrypt: Pbes2KWEncryptFunction = async (

let derived: CryptoKey | Uint8Array
if (cryptoKey.usages.includes('deriveBits')) {
// @deno-expect-error
derived = new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen))
} else if (cryptoKey.usages.includes('deriveKey')) {
// @deno-expect-error
derived = await crypto.subtle.deriveKey(subtleAlg, cryptoKey, wrapAlg, false, ['wrapKey'])
} else {
throw new TypeError('PBKDF2 key "usages" must include "deriveBits" or "deriveKey"')
Expand Down Expand Up @@ -83,8 +85,10 @@ export const decrypt: Pbes2KWDecryptFunction = async (

let derived: CryptoKey | Uint8Array
if (cryptoKey.usages.includes('deriveBits')) {
// @deno-expect-error
derived = new Uint8Array(await crypto.subtle.deriveBits(subtleAlg, cryptoKey, keylen))
} else if (cryptoKey.usages.includes('deriveKey')) {
// @deno-expect-error
derived = await crypto.subtle.deriveKey(subtleAlg, cryptoKey, wrapAlg, false, ['unwrapKey'])
} else {
throw new TypeError('PBKDF2 key "usages" must include "deriveBits" or "deriveKey"')
Expand Down
5 changes: 5 additions & 0 deletions src/runtime/browser/rsaes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ export const encrypt: RsaEsEncryptFunction = async (alg: string, key: unknown, c
checkKeyLength(alg, key)

if (key.usages.includes('encrypt')) {
// @deno-expect-error
return new Uint8Array(await crypto.subtle.encrypt(subtleAlgorithm(alg), key, cek))
}

if (key.usages.includes('wrapKey')) {
// we're importing the cek to end up with CryptoKey instance that can be wrapped, the algorithm used is irrelevant
const cryptoKeyCek = await crypto.subtle.importKey('raw', cek, ...bogusWebCrypto)
return new Uint8Array(
// @deno-expect-error
await crypto.subtle.wrapKey('raw', cryptoKeyCek, key, subtleAlgorithm(alg)),
)
}
Expand All @@ -39,10 +41,12 @@ export const decrypt: RsaEsDecryptFunction = async (
checkKeyLength(alg, key)

if (key.usages.includes('decrypt')) {
// @deno-expect-error
return new Uint8Array(await crypto.subtle.decrypt(subtleAlgorithm(alg), key, encryptedKey))
}

if (key.usages.includes('unwrapKey')) {
// @deno-expect-error
const cryptoKeyCek = await crypto.subtle.unwrapKey(
'raw',
encryptedKey,
Expand All @@ -51,6 +55,7 @@ export const decrypt: RsaEsDecryptFunction = async (
...bogusWebCrypto,
)

// @deno-expect-error
return new Uint8Array(await crypto.subtle.exportKey('raw', cryptoKeyCek))
}

Expand Down

0 comments on commit c5f2262

Please sign in to comment.