refactor: key instance detection refactor

This commit is contained in:
Filip Skokan 2021-05-11 13:40:47 +02:00
parent 26bdb732a5
commit 34d7f3fee7
12 changed files with 34 additions and 17 deletions

View file

@ -3,5 +3,8 @@ import globalThis from './global.js'
export default globalThis.crypto
export function isCryptoKey(key: unknown): key is CryptoKey {
return key instanceof globalThis.CryptoKey
if (typeof globalThis.CryptoKey === 'undefined') {
return false
}
return key != null && key instanceof globalThis.CryptoKey
}

View file

@ -4,6 +4,7 @@ import type { AesKwUnwrapFunction, AesKwWrapFunction } from '../interfaces.d'
import { concat } from '../../lib/buffer_utils.js'
import getSecretKey from './secret_key.js'
import { isCryptoKey, getKeyObject } from './webcrypto.js'
import isKeyObject from './is_key_object.js'
function checkKeySize(key: KeyObject, alg: string) {
if (key.symmetricKeySize! << 3 !== parseInt(alg.substr(1, 3), 10)) {
@ -12,7 +13,7 @@ function checkKeySize(key: KeyObject, alg: string) {
}
function ensureKeyObject(key: unknown, alg: string, usage: KeyUsage) {
if (key instanceof KeyObject) {
if (isKeyObject(key)) {
return key
}
if (key instanceof Uint8Array) {

View file

@ -1,5 +1,6 @@
import { KeyObject } from 'crypto'
import { JWEInvalid, JOSENotSupported } from '../../util/errors.js'
import isKeyObject from './is_key_object.js'
const checkCekLength = (enc: string, cek: KeyObject | Uint8Array) => {
let expected: number
@ -27,7 +28,7 @@ const checkCekLength = (enc: string, cek: KeyObject | Uint8Array) => {
return
}
if (cek instanceof KeyObject && cek.type === 'secret') {
if (isKeyObject(cek) && cek.type === 'secret') {
if (cek.symmetricKeySize! << 3 !== expected) {
throw new JWEInvalid('Invalid Content Encryption Key length')
}

View file

@ -10,6 +10,7 @@ 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'
import isKeyObject from './is_key_object.js'
async function cbcDecrypt(
enc: string,
@ -21,7 +22,7 @@ async function cbcDecrypt(
) {
const keySize = parseInt(enc.substr(1, 3), 10)
if (cek instanceof KeyObject) {
if (isKeyObject(cek)) {
// eslint-disable-next-line no-param-reassign
cek = cek.export()
}
@ -99,7 +100,7 @@ const decrypt: DecryptFunction = async (
if (isCryptoKey(cek)) {
// eslint-disable-next-line no-param-reassign
key = getKeyObject(cek, enc, new Set(['decrypt']))
} else if (cek instanceof Uint8Array || cek instanceof KeyObject) {
} else if (cek instanceof Uint8Array || isKeyObject(cek)) {
key = cek
} else {
throw new TypeError('invalid key input')

View file

@ -1,4 +1,4 @@
import { KeyObject, diffieHellman, generateKeyPair as generateKeyPairCb } from 'crypto'
import { diffieHellman, generateKeyPair as generateKeyPairCb } from 'crypto'
import { promisify } from 'util'
import type {
@ -11,6 +11,7 @@ import { encoder, concat, uint32be, lengthAndInput, concatKdf } from '../../lib/
import digest from './digest.js'
import { JOSENotSupported } from '../../util/errors.js'
import { isCryptoKey, getKeyObject } from './webcrypto.js'
import isKeyObject from './is_key_object.js'
const generateKeyPair = promisify(generateKeyPairCb)
@ -33,7 +34,7 @@ export const deriveKey: EcdhESDeriveKeyFunction = async (
// eslint-disable-next-line no-param-reassign
publicKey = getKeyObject(publicKey, 'ECDH-ES')
}
if (!(publicKey instanceof KeyObject)) {
if (!isKeyObject(publicKey)) {
throw new TypeError('invalid key input')
}
@ -41,7 +42,7 @@ export const deriveKey: EcdhESDeriveKeyFunction = async (
// eslint-disable-next-line no-param-reassign
privateKey = getKeyObject(privateKey, 'ECDH-ES', new Set(['deriveBits', 'deriveKey']))
}
if (!(privateKey instanceof KeyObject)) {
if (!isKeyObject(privateKey)) {
throw new TypeError('invalid key input')
}
@ -54,7 +55,7 @@ export const generateEpk: GenerateEpkFunction = async (key: unknown) => {
// eslint-disable-next-line no-param-reassign
key = getKeyObject(key)
}
if (!(key instanceof KeyObject)) {
if (!isKeyObject(key)) {
throw new TypeError('invalid key input')
}

View file

@ -8,6 +8,7 @@ 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'
import isKeyObject from './is_key_object.js'
async function cbcEncrypt(
enc: string,
@ -18,7 +19,7 @@ async function cbcEncrypt(
) {
const keySize = parseInt(enc.substr(1, 3), 10)
if (cek instanceof KeyObject) {
if (isKeyObject(cek)) {
// eslint-disable-next-line no-param-reassign
cek = cek.export()
}
@ -67,7 +68,7 @@ const encrypt: EncryptFunction = async (
if (isCryptoKey(cek)) {
// eslint-disable-next-line no-param-reassign
key = getKeyObject(cek, enc, new Set(['encrypt']))
} else if (cek instanceof Uint8Array || cek instanceof KeyObject) {
} else if (cek instanceof Uint8Array || isKeyObject(cek)) {
key = cek
} else {
throw new TypeError('invalid key input')

View file

@ -1,6 +1,7 @@
import { KeyObject, createPublicKey } from 'crypto'
import { JOSENotSupported } from '../../util/errors.js'
import { isCryptoKey, getKeyObject } from './webcrypto.js'
import isKeyObject from './is_key_object.js'
const p256 = Buffer.from([42, 134, 72, 206, 61, 3, 1, 7])
const p384 = Buffer.from([43, 129, 4, 0, 34])
@ -29,7 +30,7 @@ const getNamedCurve = (key: unknown, raw?: boolean): string => {
// eslint-disable-next-line no-param-reassign
key = getKeyObject(key)
}
if (!(key instanceof KeyObject)) {
if (!isKeyObject(key)) {
throw new TypeError('invalid key input')
}

View file

@ -0,0 +1,5 @@
import { KeyObject } from 'crypto'
export default function isKeyObject(obj: unknown): obj is KeyObject {
return obj != null && obj instanceof KeyObject
}

View file

@ -6,6 +6,7 @@ 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'
import isKeyObject from './is_key_object.js'
const [major, minor] = process.version
.substr(1)
@ -21,7 +22,7 @@ const keyToJWK: JWKConvertFunction = (key: unknown): JWK => {
throw new TypeError('CryptoKey is not extractable')
}
keyObject = getKeyObject(key)
} else if (key instanceof KeyObject) {
} else if (isKeyObject(key)) {
keyObject = key
} else {
throw new TypeError('invalid key input')

View file

@ -1,5 +1,5 @@
import { promisify } from 'util'
import { KeyObject, pbkdf2 as pbkdf2cb } from 'crypto'
import { 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'
@ -7,11 +7,12 @@ 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'
import isKeyObject from './is_key_object.js'
const pbkdf2 = promisify(pbkdf2cb)
function getPassword(key: unknown, alg: string) {
if (key instanceof KeyObject) {
if (isKeyObject(key)) {
return key.export()
}
if (key instanceof Uint8Array) {

View file

@ -2,6 +2,7 @@ import { KeyObject, 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'
import isKeyObject from './is_key_object.js'
const checkKey = (key: KeyObject, alg: string) => {
if (key.type === 'secret' || key.asymmetricKeyType !== 'rsa') {
@ -40,7 +41,7 @@ const resolveOaepHash = (alg: string) => {
}
function ensureKeyObject(key: unknown, alg: string, ...usages: KeyUsage[]) {
if (key instanceof KeyObject) {
if (isKeyObject(key)) {
return key
}
if (isCryptoKey(key)) {

View file

@ -7,7 +7,7 @@ export default webcrypto
export function isCryptoKey(key: unknown): key is CryptoKey {
if (webcrypto !== undefined) {
// @ts-expect-error
return key instanceof webcrypto.CryptoKey
return key != null && key instanceof webcrypto.CryptoKey
}
return false