mirror of
https://github.com/danbulant/jose
synced 2026-05-21 13:28:45 +00:00
fix: expose JOSENotSupported key import errors on unsupported runtimes
This commit is contained in:
parent
bb58c9ce52
commit
bc81e5dec2
4 changed files with 79 additions and 12 deletions
|
|
@ -32,6 +32,26 @@ if (!keyObjectSupported) {
|
|||
|
||||
const pemToDer = pem => Buffer.from(pem.replace(/(?:-----(?:BEGIN|END)(?: (?:RSA|EC))? (?:PRIVATE|PUBLIC) KEY-----|\s)/g, ''), 'base64')
|
||||
const derToPem = (der, label) => `-----BEGIN ${label}-----${EOL}${der.toString('base64').match(/.{1,64}/g).join(EOL)}${EOL}-----END ${label}-----`
|
||||
const unsupported = (label) => {
|
||||
switch (label) {
|
||||
case '1.3.101.110':
|
||||
label = 'X25519'
|
||||
break
|
||||
case '1.3.101.111':
|
||||
label = 'X448'
|
||||
break
|
||||
case '1.3.101.112':
|
||||
label = 'Ed25519'
|
||||
break
|
||||
case '1.3.101.113':
|
||||
label = 'Ed448'
|
||||
break
|
||||
default:
|
||||
label = `OID ${label}`
|
||||
}
|
||||
|
||||
throw new errors.JOSENotSupported(`${label} is not supported in your Node.js runtime version`)
|
||||
}
|
||||
|
||||
KeyObject = class KeyObject {
|
||||
export ({ cipher, passphrase, type, format } = {}) {
|
||||
|
|
@ -286,7 +306,8 @@ if (!keyObjectSupported) {
|
|||
const parsed = PublicKeyInfo.decode(key, format, { label })
|
||||
|
||||
let type, keyObject
|
||||
switch (parsed.algorithm.algorithm.join('.')) {
|
||||
const oid = parsed.algorithm.algorithm.join('.')
|
||||
switch (oid) {
|
||||
case '1.2.840.10045.2.1': {
|
||||
keyObject = new KeyObject()
|
||||
i(keyObject).asn1 = parsed
|
||||
|
|
@ -302,7 +323,7 @@ if (!keyObjectSupported) {
|
|||
break
|
||||
}
|
||||
default:
|
||||
throw new errors.JOSENotSupported(`OID ${parsed.algorithm.algorithm.join('.')} is not supported in your Node.js runtime version`)
|
||||
unsupported(oid)
|
||||
}
|
||||
|
||||
return keyObject
|
||||
|
|
@ -375,7 +396,8 @@ if (!keyObjectSupported) {
|
|||
const parsed = PrivateKeyInfo.decode(key, format, { label })
|
||||
|
||||
let type, keyObject
|
||||
switch (parsed.algorithm.algorithm.join('.')) {
|
||||
const oid = parsed.algorithm.algorithm.join('.')
|
||||
switch (oid) {
|
||||
case '1.2.840.10045.2.1': {
|
||||
const OID = asn1.get('OID')
|
||||
type = 'sec1'
|
||||
|
|
@ -388,7 +410,7 @@ if (!keyObjectSupported) {
|
|||
break
|
||||
}
|
||||
default:
|
||||
throw new errors.JOSENotSupported(`OID ${parsed.algorithm.algorithm.join('.')} is not supported in your Node.js runtime version`)
|
||||
unsupported(oid)
|
||||
}
|
||||
|
||||
i(keyObject).pkcs8 = key
|
||||
|
|
|
|||
|
|
@ -86,7 +86,11 @@ const asKey = (key, parameters, { calculateMissingRSAPrimes = false } = {}) => {
|
|||
} else if (key && (typeof key === 'object' || typeof key === 'string')) { // <Object> | <string> | <Buffer> passed to crypto.createPrivateKey or crypto.createPublicKey or <Buffer> passed to crypto.createSecretKey
|
||||
try {
|
||||
privateKey = createPrivateKey(key)
|
||||
} catch (err) {}
|
||||
} catch (err) {
|
||||
if (err instanceof errors.JOSEError) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
publicKey = createPublicKey(key)
|
||||
|
|
@ -95,7 +99,11 @@ const asKey = (key, parameters, { calculateMissingRSAPrimes = false } = {}) => {
|
|||
x5c: [key.replace(/(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g, '')]
|
||||
})
|
||||
}
|
||||
} catch (err) {}
|
||||
} catch (err) {
|
||||
if (err instanceof errors.JOSEError) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// this is to filter out invalid PEM keys and certs, i'll rather have them fail import then
|
||||
|
|
|
|||
|
|
@ -165,9 +165,7 @@ test('invalid encoded oct jwk import', async t => {
|
|||
}, { instanceOf: errors.JOSEInvalidEncoding, code: 'ERR_JOSE_INVALID_ENCODING', message: 'input is not a valid base64url encoded string' })
|
||||
})
|
||||
|
||||
if (keyObjectSupported) {
|
||||
test('importing a certificate file populates the certificate properties', t => {
|
||||
const key = asKey(`-----BEGIN CERTIFICATE-----
|
||||
const cert = `-----BEGIN CERTIFICATE-----
|
||||
MIIC4DCCAcgCCQDO8JBSH914NDANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJD
|
||||
WjEPMA0GA1UEBwwGUHJhZ3VlMRIwEAYDVQQDDAlwa210bHN0d28wHhcNMTkwNjE4
|
||||
MTIzMjAxWhcNMjAwNjE3MTIzMjAxWjAyMQswCQYDVQQGEwJDWjEPMA0GA1UEBwwG
|
||||
|
|
@ -184,9 +182,19 @@ KwwOdRu7VJpAxvweA/3woKl6Cjfy20ZupPH9mxr1R78BMKgEtdFsiLwbB7MOdDbT
|
|||
LsrUcEcupXv+gZek22upQKrAk/XFP067KIqKmCEhDidxhP251SloUaruv9cHEx0a
|
||||
DKol9eR465FAiBLvg2N7qJHCKlWdn99SgN4Y3kINsuFR7Tj4QIJZNubOjV0YeOgn
|
||||
AWzRJlZD89KZAQgjj4Z215QeLxA=
|
||||
-----END CERTIFICATE-----`)
|
||||
-----END CERTIFICATE-----`
|
||||
|
||||
if (keyObjectSupported) {
|
||||
test('importing a certificate file populates the certificate properties', t => {
|
||||
const key = asKey(cert)
|
||||
t.truthy(key.x5c)
|
||||
t.truthy(key.x5t)
|
||||
t.truthy(key['x5t#S256'])
|
||||
})
|
||||
} else {
|
||||
test('cannot import a certificate', t => {
|
||||
t.throws(() => {
|
||||
asKey(cert)
|
||||
}, { instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: 'X.509 certificates are not supported in your Node.js runtime version' })
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,41 @@
|
|||
const test = require('ava')
|
||||
|
||||
const { keyObjectSupported } = require('../../lib/help/runtime_support')
|
||||
const errors = require('../../lib/errors')
|
||||
|
||||
if (!keyObjectSupported) return
|
||||
const fixtures = require('../fixtures')
|
||||
|
||||
if (!keyObjectSupported) {
|
||||
const JWK = require('../../lib/jwk')
|
||||
;[
|
||||
[fixtures.PEM.Ed25519.public, 'Ed25519'],
|
||||
[fixtures.PEM.Ed25519.private, 'Ed25519'],
|
||||
[fixtures.PEM.Ed448.public, 'Ed448'],
|
||||
[fixtures.PEM.Ed448.private, 'Ed448'],
|
||||
[fixtures.PEM.X25519.public, 'X25519'],
|
||||
[fixtures.PEM.X25519.private, 'X25519'],
|
||||
[fixtures.PEM.X448.public, 'X448'],
|
||||
[fixtures.PEM.X448.private, 'X448'],
|
||||
[fixtures.JWK.Ed25519, 'Ed25519'],
|
||||
[fixtures.JWK.Ed448, 'Ed448'],
|
||||
[fixtures.JWK.X25519, 'X25519'],
|
||||
[fixtures.JWK.X448, 'X448'],
|
||||
[{ ...fixtures.JWK.Ed25519, d: undefined }, 'Ed25519'],
|
||||
[{ ...fixtures.JWK.Ed448, d: undefined }, 'Ed448'],
|
||||
[{ ...fixtures.JWK.X25519, d: undefined }, 'X25519'],
|
||||
[{ ...fixtures.JWK.X448, d: undefined }, 'X448']
|
||||
].forEach(([input, label], i, { length }) => {
|
||||
test(`OKP ${i + 1} / ${length}`, t => {
|
||||
t.throws(() => {
|
||||
JWK.asKey(input)
|
||||
}, { instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: `${label} is not supported in your Node.js runtime version` })
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const { createPrivateKey, createPublicKey } = require('crypto')
|
||||
const { hasProperty, hasNoProperties, hasProperties } = require('../macros')
|
||||
const fixtures = require('../fixtures')
|
||||
|
||||
const OKPKey = require('../../lib/jwk/key/okp')
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue