mirror of
https://github.com/danbulant/jose
synced 2026-05-21 05:18:59 +00:00
refactor: key instance detection refactor
This commit is contained in:
parent
26bdb732a5
commit
34d7f3fee7
12 changed files with 34 additions and 17 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
}
|
||||
|
||||
|
|
|
|||
5
src/runtime/node/is_key_object.ts
Normal file
5
src/runtime/node/is_key_object.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { KeyObject } from 'crypto'
|
||||
|
||||
export default function isKeyObject(obj: unknown): obj is KeyObject {
|
||||
return obj != null && obj instanceof KeyObject
|
||||
}
|
||||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue