Skip to content

Commit

Permalink
refactor: clarify when alg is used and required on key imports
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Feb 27, 2023
1 parent 018dfab commit 19e525f
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/key/generate_key_pair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface GenerateKeyPairOptions {
modulusLength?: number

/**
* (Web Cryptography API specific) The value to use as
* (Only effective in Web Crypto API runtimes) The value to use as
* [SubtleCrypto.generateKey()](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey)
* `extractable` argument. Default is false.
*/
Expand All @@ -35,7 +35,7 @@ export interface GenerateKeyPairOptions {
* Generates a private and a public key for a given JWA algorithm identifier. This can only generate
* asymmetric key pairs. For symmetric secrets use the `generateSecret` function.
*
* Note: Under Web Cryptography API runtime the `privateKey` is generated with `extractable` set to
* Note: Under Web Crypto API runtime the `privateKey` is generated with `extractable` set to
* `false` by default.
*
* @example Usage
Expand Down
6 changes: 3 additions & 3 deletions src/key/generate_secret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { KeyLike } from '../types.d'

export interface GenerateSecretOptions {
/**
* (Web Cryptography API specific) The value to use as
* (Only effective in Web Crypto API runtimes) The value to use as
* [SubtleCrypto.generateKey()](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey)
* `extractable` argument. Default is false.
*/
Expand All @@ -14,8 +14,8 @@ export interface GenerateSecretOptions {
/**
* Generates a symmetric secret key for a given JWA algorithm identifier.
*
* Note: Under Web Cryptography API runtime the secret key is generated with `extractable` set to
* `false` by default.
* Note: Under Web Crypto API runtime the secret key is generated with `extractable` set to `false`
* by default.
*
* @example Usage
*
Expand Down
20 changes: 10 additions & 10 deletions src/key/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { JWK, KeyLike } from '../types.d'

export interface PEMImportOptions {
/**
* (Web Cryptography API specific) The value to use as
* (Only effective in Web Crypto API runtimes) The value to use as
* [SubtleCrypto.importKey()](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey)
* `extractable` argument. Default is false.
*/
Expand All @@ -32,7 +32,8 @@ export interface PEMImportOptions {
* ```
*
* @param pem PEM-encoded SPKI string
* @param alg JSON Web Algorithm identifier to be used with the imported key.
* @param alg (Only effective in Web Crypto API runtimes) JSON Web Algorithm identifier to be used
* with the imported key, its presence is only enforced in Web Crypto API runtimes.
*/
export async function importSPKI(
spki: string,
Expand Down Expand Up @@ -69,7 +70,8 @@ export async function importSPKI(
* ```
*
* @param pem X.509 certificate string
* @param alg JSON Web Algorithm identifier to be used with the imported key.
* @param alg (Only effective in Web Crypto API runtimes) JSON Web Algorithm identifier to be used
* with the imported key, its presence is only enforced in Web Crypto API runtimes.
*/
export async function importX509(
x509: string,
Expand Down Expand Up @@ -100,7 +102,8 @@ export async function importX509(
* ```
*
* @param pem PEM-encoded PKCS#8 string
* @param alg JSON Web Algorithm identifier to be used with the imported key.
* @param alg (Only effective in Web Crypto API runtimes) JSON Web Algorithm identifier to be used
* with the imported key, its presence is only enforced in Web Crypto API runtimes.
*/
export async function importPKCS8(
pkcs8: string,
Expand Down Expand Up @@ -145,8 +148,9 @@ export async function importPKCS8(
* ```
*
* @param jwk JSON Web Key.
* @param alg JSON Web Algorithm identifier to be used with the imported key. Default is the "alg"
* property on the JWK.
* @param alg (Only effective in Web Crypto API runtimes) JSON Web Algorithm identifier to be used
* with the imported key. Default is the "alg" property on the JWK, its presence is only enforced
* in Web Crypto API runtimes.
* @param octAsKeyObject Forces a symmetric key to be imported to a KeyObject or CryptoKey. Default
* is true unless JWK "ext" (Extractable) is true.
*/
Expand All @@ -161,10 +165,6 @@ export async function importJWK(

alg ||= jwk.alg

if (typeof alg !== 'string' || !alg) {
throw new TypeError('"alg" argument is required when "jwk.alg" is not present')
}

switch (jwk.kty) {
case 'oct':
if (typeof jwk.k !== 'string' || !jwk.k) {
Expand Down
4 changes: 4 additions & 0 deletions src/runtime/browser/jwk_to_key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ function subtleMapping(jwk: JWK): {
}

const parse: JWKImportFunction = async (jwk: JWK): Promise<CryptoKey> => {
if (!jwk.alg) {
throw new TypeError('"alg" argument is required when "jwk.alg" is not present')
}

const { algorithm, keyUsages } = subtleMapping(jwk)
const rest: [RsaHashedImportParams | EcKeyAlgorithm | Algorithm, boolean, KeyUsage[]] = [
algorithm,
Expand Down
24 changes: 24 additions & 0 deletions tap/jwk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,28 @@ export default (QUnit: QUnit, lib: typeof jose) => {
})
}
}

if (env.isNodeCrypto || env.isElectron) {
test('alg argument and jwk.alg is ignored', async (t) => {
const oct = {
k: 'FyCq1CKBflh3I5gikEjpYrdOXllzxB_yc02za8ERknI',
kty: 'oct',
}
await lib.importJWK(oct)
t.ok(1)
})
} else {
test('alg argument must be present if jwk does not have alg', async (t) => {
const oct = {
k: 'FyCq1CKBflh3I5gikEjpYrdOXllzxB_yc02za8ERknI',
kty: 'oct',
}
await t.rejects(
lib.importJWK(oct),
'"alg" argument is required when "jwk.alg" is not present',
)
await lib.importJWK(oct, 'HS256')
await lib.importJWK({ ...oct, alg: 'HS256' })
})
}
}
13 changes: 0 additions & 13 deletions test/jwk/jwk2key.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,6 @@ test('JWK kty must be recognized', async (t) => {
})
})

test('alg argument must be present if jwk does not have alg', async (t) => {
const oct = {
k: 'FyCq1CKBflh3I5gikEjpYrdOXllzxB_yc02za8ERknI',
kty: 'oct',
}
await t.throwsAsync(importJWK(oct), {
instanceOf: TypeError,
message: '"alg" argument is required when "jwk.alg" is not present',
})
await t.notThrowsAsync(importJWK(oct, 'HS256'))
await t.notThrowsAsync(importJWK({ ...oct, alg: 'HS256' }))
})

test('oct JWK must have "k"', async (t) => {
await t.throwsAsync(importJWK({ kty: 'oct' }, 'HS256'), {
instanceOf: TypeError,
Expand Down

0 comments on commit 19e525f

Please sign in to comment.