Skip to content

Commit

Permalink
refactor: runtime import reorder, node predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Sep 9, 2021
1 parent 244a9f8 commit 82fa773
Show file tree
Hide file tree
Showing 18 changed files with 87 additions and 95 deletions.
11 changes: 5 additions & 6 deletions src/jwe/flattened/decrypt.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js'
import isDisjoint from '../../lib/is_disjoint.js'
import isObject from '../../lib/is_object.js'

import { decode as base64url } from '../../runtime/base64url.js'
import decrypt from '../../runtime/decrypt.js'
import { inflate } from '../../runtime/zlib.js'
import decryptKeyManagement from '../../lib/decrypt_key_management.js'
import random from '../../runtime/random.js'

import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js'
import isDisjoint from '../../lib/is_disjoint.js'
import isObject from '../../lib/is_object.js'
import decryptKeyManagement from '../../lib/decrypt_key_management.js'
import type {
FlattenedDecryptResult,
KeyLike,
Expand All @@ -17,7 +17,6 @@ import type {
} from '../../types.d'
import { encoder, decoder, concat } from '../../lib/buffer_utils.js'
import cekFactory from '../../lib/cek.js'
import random from '../../runtime/random.js'
import validateCrit from '../../lib/validate_crit.js'
import validateAlgorithms from '../../lib/validate_algorithms.js'

Expand Down
10 changes: 5 additions & 5 deletions src/jwe/flattened/encrypt.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { encode as base64url } from '../../runtime/base64url.js'
import random from '../../runtime/random.js'
import encrypt from '../../runtime/encrypt.js'
import { deflate } from '../../runtime/zlib.js'

import type {
KeyLike,
FlattenedJWE,
Expand All @@ -7,12 +12,7 @@ import type {
} from '../../types.d'
import type { JWEKeyManagementHeaderResults } from '../../types.i.d'
import ivFactory from '../../lib/iv.js'
import { encode as base64url } from '../../runtime/base64url.js'
import random from '../../runtime/random.js'
import encrypt from '../../runtime/encrypt.js'
import { deflate } from '../../runtime/zlib.js'
import encryptKeyManagement from '../../lib/encrypt_key_management.js'

import { JOSENotSupported, JWEInvalid } from '../../util/errors.js'
import isDisjoint from '../../lib/is_disjoint.js'
import { encoder, decoder, concat } from '../../lib/buffer_utils.js'
Expand Down
3 changes: 2 additions & 1 deletion src/jwk/from_key_like.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { JWK, KeyLike } from '../types.d'
import asJWK from '../runtime/key_to_jwk.js'

import type { JWK, KeyLike } from '../types.d'

/**
* Converts a runtime-specific key representation (KeyLike) to a JWK.
*
Expand Down
1 change: 1 addition & 0 deletions src/jwk/parse.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { decode as base64url } from '../runtime/base64url.js'
import asKeyObject from '../runtime/jwk_to_key.js'

import { JOSENotSupported } from '../util/errors.js'
import isObject from '../lib/is_object.js'
import type { JWK, KeyLike } from '../types.d'
Expand Down
4 changes: 2 additions & 2 deletions src/jwk/thumbprint.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { JOSENotSupported, JWKInvalid } from '../util/errors.js'

import digest from '../runtime/digest.js'
import { encode as base64url } from '../runtime/base64url.js'

import { JOSENotSupported, JWKInvalid } from '../util/errors.js'
import { encoder } from '../lib/buffer_utils.js'
import type { JWK } from '../types.d'
import isObject from '../lib/is_object.js'
Expand Down
3 changes: 2 additions & 1 deletion src/jwks/remote.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import fetchJwks from '../runtime/fetch_jwks.js'

import type {
KeyObject,
JWSHeaderParameters,
Expand All @@ -12,7 +14,6 @@ import {
JWKSNoMatchingKey,
JWKSMultipleMatchingKeys,
} from '../util/errors.js'
import fetchJwks from '../runtime/fetch_jwks.js'
import isObject from '../lib/is_object.js'

function getKtyFromAlg(alg: string) {
Expand Down
6 changes: 3 additions & 3 deletions src/jws/flattened/sign.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { encode as base64url } from '../../runtime/base64url.js'
import sign from '../../runtime/sign.js'

import isDisjoint from '../../lib/is_disjoint.js'
import { JWSInvalid } from '../../util/errors.js'
import { encoder, decoder, concat } from '../../lib/buffer_utils.js'

import { encode as base64url } from '../../runtime/base64url.js'
import sign from '../../runtime/sign.js'
import type { KeyLike, FlattenedJWS, JWSHeaderParameters, SignOptions } from '../../types.d'
import checkKeyType from '../../lib/check_key_type.js'
import validateCrit from '../../lib/validate_crit.js'
Expand Down
6 changes: 3 additions & 3 deletions src/jws/flattened/verify.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { decode as base64url } from '../../runtime/base64url.js'
import verify from '../../runtime/verify.js'

import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js'
import { concat, encoder, decoder } from '../../lib/buffer_utils.js'
import isDisjoint from '../../lib/is_disjoint.js'
import isObject from '../../lib/is_object.js'
import checkKeyType from '../../lib/check_key_type.js'

import { decode as base64url } from '../../runtime/base64url.js'
import verify from '../../runtime/verify.js'
import validateCrit from '../../lib/validate_crit.js'
import validateAlgorithms from '../../lib/validate_algorithms.js'

Expand Down
3 changes: 2 additions & 1 deletion src/jwt/unsecured.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as base64url from '../runtime/base64url.js'

import type { JWSHeaderParameters, JWTClaimVerificationOptions, JWTPayload } from '../types.d'
import { decoder } from '../lib/buffer_utils.js'
import * as base64url from '../runtime/base64url.js'
import { JWTInvalid } from '../util/errors.js'
import jwtPayload from '../lib/jwt_claims_set.js'
import ProduceJWT from '../lib/jwt_producer.js'
Expand Down
3 changes: 2 additions & 1 deletion src/lib/check_key_type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { KeyLike } from '../types.d'
import invalidKeyInput from '../runtime/invalid_key_input.js'

import type { KeyLike } from '../types.d'

const checkKeyType = (
alg: string,
key: KeyLike,
Expand Down
7 changes: 4 additions & 3 deletions src/lib/decrypt_key_management.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { JWEHeaderParameters, KeyLike } from '../types.d'
import type { JWEKeyManagementHeaderResults } from '../types.i.d'
import { JOSENotSupported, JWEInvalid } from '../util/errors.js'
import { unwrap as aesKw } from '../runtime/aeskw.js'
import * as ECDH from '../runtime/ecdhes.js'
import { decrypt as pbes2Kw } from '../runtime/pbes2kw.js'
import { decrypt as rsaEs } from '../runtime/rsaes.js'
import { unwrap as aesGcmKw } from '../runtime/aesgcmkw.js'
import { decode as base64url } from '../runtime/base64url.js'

import type { JWEHeaderParameters, KeyLike } from '../types.d'
import type { JWEKeyManagementHeaderResults } from '../types.i.d'
import { JOSENotSupported, JWEInvalid } from '../util/errors.js'
import { bitLengths as cekLengths } from '../lib/cek.js'
import { parseJwk } from '../jwk/parse.js'
import checkKeyType from './check_key_type.js'
Expand Down
9 changes: 5 additions & 4 deletions src/lib/encrypt_key_management.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import type { KeyLike, JWEKeyManagementHeaderParameters } from '../types.d'
import type { JWEKeyManagementHeaderResults } from '../types.i.d'
import cekFactory, { bitLengths as cekLengths } from '../lib/cek.js'
import { JOSENotSupported } from '../util/errors.js'
import random from '../runtime/random.js'
import { wrap as aesKw } from '../runtime/aeskw.js'
import * as ECDH from '../runtime/ecdhes.js'
import { encrypt as pbes2Kw } from '../runtime/pbes2kw.js'
import { encrypt as rsaEs } from '../runtime/rsaes.js'
import { wrap as aesGcmKw } from '../runtime/aesgcmkw.js'
import { encode as base64url } from '../runtime/base64url.js'

import type { KeyLike, JWEKeyManagementHeaderParameters } from '../types.d'
import type { JWEKeyManagementHeaderResults } from '../types.i.d'
import cekFactory, { bitLengths as cekLengths } from '../lib/cek.js'
import { JOSENotSupported } from '../util/errors.js'
import { fromKeyLike } from '../jwk/from_key_like.js'
import checkKeyType from './check_key_type.js'

Expand Down
51 changes: 29 additions & 22 deletions src/runtime/node/ecdhes.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { KeyObject } from 'crypto'
import { diffieHellman, generateKeyPair as generateKeyPairCb } from 'crypto'
import { promisify } from 'util'

Expand All @@ -17,44 +18,50 @@ import invalidKeyInput from './invalid_key_input.js'
const generateKeyPair = promisify(generateKeyPairCb)

export const deriveKey: EcdhESDeriveKeyFunction = async (
publicKey: unknown,
privateKey: unknown,
publicKee: unknown,
privateKee: unknown,
algorithm: string,
keyLength: number,
apu: Uint8Array = new Uint8Array(0),
apv: Uint8Array = new Uint8Array(0),
) => {
let publicKey: KeyObject
if (isCryptoKey(publicKee)) {
publicKey = getKeyObject(publicKee, 'ECDH-ES')
} else if (isKeyObject(publicKee)) {
publicKey = publicKee
} else {
throw new TypeError(invalidKeyInput(publicKee, 'KeyObject', 'CryptoKey'))
}

let privateKey: KeyObject
if (isCryptoKey(privateKee)) {
privateKey = getKeyObject(privateKee, 'ECDH-ES', new Set(['deriveBits', 'deriveKey']))
} else if (isKeyObject(privateKee)) {
privateKey = privateKee
} else {
throw new TypeError(invalidKeyInput(privateKee, 'KeyObject', 'CryptoKey'))
}

const value = concat(
lengthAndInput(encoder.encode(algorithm)),
lengthAndInput(apu),
lengthAndInput(apv),
uint32be(keyLength),
)

if (isCryptoKey(publicKey)) {
publicKey = getKeyObject(publicKey, 'ECDH-ES')
}
if (!isKeyObject(publicKey)) {
throw new TypeError(invalidKeyInput(publicKey, 'KeyObject', 'CryptoKey'))
}

if (isCryptoKey(privateKey)) {
privateKey = getKeyObject(privateKey, 'ECDH-ES', new Set(['deriveBits', 'deriveKey']))
}
if (!isKeyObject(privateKey)) {
throw new TypeError(invalidKeyInput(privateKey, 'KeyObject', 'CryptoKey'))
}

const sharedSecret = diffieHellman({ privateKey, publicKey })
return concatKdf(digest, sharedSecret, keyLength, value)
}

export const generateEpk: GenerateEpkFunction = async (key: unknown) => {
if (isCryptoKey(key)) {
key = getKeyObject(key)
}
if (!isKeyObject(key)) {
throw new TypeError(invalidKeyInput(key, 'KeyObject', 'CryptoKey'))
export const generateEpk: GenerateEpkFunction = async (kee: unknown) => {
let key: KeyObject
if (isCryptoKey(kee)) {
key = getKeyObject(kee)
} else if (isKeyObject(kee)) {
key = kee
} else {
throw new TypeError(invalidKeyInput(kee, 'KeyObject', 'CryptoKey'))
}

switch (key.asymmetricKeyType) {
Expand Down
19 changes: 11 additions & 8 deletions src/runtime/node/get_named_curve.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { KeyObject, createPublicKey } from 'crypto'
import type { KeyObject } from 'crypto'
import { createPublicKey } from 'crypto'
import { JOSENotSupported } from '../../util/errors.js'
import { isCryptoKey, getKeyObject } from './webcrypto.js'
import isKeyObject from './is_key_object.js'
Expand All @@ -20,18 +21,20 @@ const namedCurveToJOSE = (namedCurve: string) => {
case 'secp521r1':
return 'P-521'
case 'secp256k1':
return namedCurve
return 'secp256k1'
default:
throw new JOSENotSupported('unsupported key curve for this operation')
}
}

const getNamedCurve = (key: unknown, raw?: boolean): string => {
if (isCryptoKey(key)) {
key = getKeyObject(key)
}
if (!isKeyObject(key)) {
throw new TypeError(invalidKeyInput(key, 'KeyObject', 'CryptoKey'))
const getNamedCurve = (kee: unknown, raw?: boolean): string => {
let key: KeyObject
if (isCryptoKey(kee)) {
key = getKeyObject(kee)
} else if (isKeyObject(kee)) {
key = kee
} else {
throw new TypeError(invalidKeyInput(kee, 'KeyObject', 'CryptoKey'))
}

if (key.type === 'secret') {
Expand Down
16 changes: 3 additions & 13 deletions src/runtime/node/is_key_object.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import { KeyObject } from 'crypto'
import * as util from 'util'

let impl: (obj: unknown) => obj is KeyObject

if (util.types.isKeyObject) {
impl = function isKeyObject(obj): obj is KeyObject {
return util.types.isKeyObject(obj)
}
} else {
impl = function isKeyObject(obj): obj is KeyObject {
return obj != null && obj instanceof KeyObject
}
}

export default impl
export default util.types.isKeyObject
? (obj: unknown): obj is KeyObject => util.types.isKeyObject(obj)
: (obj: unknown): obj is KeyObject => obj != null && obj instanceof KeyObject
28 changes: 6 additions & 22 deletions src/runtime/node/webcrypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,10 @@ const webcrypto = <Crypto>crypto.webcrypto

export default webcrypto

let impl: (obj: unknown) => obj is CryptoKey

if (util.types.isCryptoKey) {
impl = function isCryptoKey(obj): obj is CryptoKey {
return util.types.isCryptoKey(obj)
}
} else if (webcrypto) {
impl = function isCryptoKey(obj): obj is CryptoKey {
//@ts-expect-error
return obj != null && obj instanceof webcrypto.CryptoKey
}
} else {
// @ts-expect-error
impl = (obj): obj is CryptoKey => false
}

export { impl as isCryptoKey }
export const isCryptoKey = util.types.isCryptoKey
? (obj: unknown): obj is CryptoKey => util.types.isCryptoKey(obj)
: // @ts-expect-error
(obj: unknown): obj is CryptoKey => false

function getHashLength(hash: KeyAlgorithm) {
return parseInt(hash?.name.substr(4), 10)
Expand All @@ -40,12 +27,9 @@ function getNamedCurve(alg: string) {
}

export function getKeyObject(key: CryptoKey, alg?: string, usage?: Set<KeyUsage>) {
if (!alg) {
// @ts-expect-error
return <crypto.KeyObject>crypto.KeyObject.from(key)
}

switch (alg) {
case undefined:
break
case 'HS256':
case 'HS384':
case 'HS512': {
Expand Down
1 change: 1 addition & 0 deletions src/util/generate_key_pair.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { generateKeyPair as generate } from '../runtime/generate.js'

import type { KeyLike } from '../types.d'

export interface GenerateKeyPairResult {
Expand Down
1 change: 1 addition & 0 deletions src/util/generate_secret.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { generateSecret as generate } from '../runtime/generate.js'

import type { KeyLike } from '../types.d'

export interface GenerateSecretOptions {
Expand Down

0 comments on commit 82fa773

Please sign in to comment.