fix: reject rsa keys without all factors and exponents with a specific message

This commit is contained in:
Filip Skokan 2019-05-23 19:20:30 +02:00
parent 6b7c92ab69
commit b0ff436daf
4 changed files with 43 additions and 4 deletions

View file

@ -1,6 +1,6 @@
module.exports = function () {
this.seq().obj(
this.key('version').int(),
this.key('version').int({ 0: 'two-prime', 1: 'multi' }),
this.key('n').int(),
this.key('e').int(),
this.key('d').int(),

View file

@ -59,7 +59,11 @@ const keyObjectToJWK = {
const RSAPrivateKey = asn1.get('RSAPrivateKey')
const { privateKey } = PrivateKeyInfo.decode(der)
const { n, e, d, p, q, dp, dq, qi } = RSAPrivateKey.decode(privateKey)
const { version, n, e, d, p, q, dp, dq, qi } = RSAPrivateKey.decode(privateKey)
if (version !== 'two-prime') {
throw new errors.JOSENotSupported('Private RSA keys with more than two primes are not supported')
}
return {
kty: 'RSA',
@ -186,6 +190,16 @@ const jwkToPem = {
private (jwk) {
const RSAPrivateKey = asn1.get('RSAPrivateKey')
if ('oth' in jwk) {
throw new errors.JOSENotSupported('Private RSA keys with more than two primes are not supported')
}
if (jwk.p || jwk.q || jwk.dp || jwk.dq || jwk.qi) {
if (!(jwk.p && jwk.q && jwk.dp && jwk.dq && jwk.qi)) {
throw new errors.JWKImportFailed('all other private key parameters must be present when any one of them is present')
}
}
return RSAPrivateKey.encode({
version: 0,
n: base64url.decodeToBuffer(jwk.n),

View file

@ -52,7 +52,11 @@ const importKey = (key, parameters) => {
let pem
try {
pem = jwkToPem(key)
} catch (err) {}
} catch (err) {
if (err instanceof errors.JOSEError) {
throw err
}
}
if (pem && key.d) {
privateKey = createPrivateKey(pem)
} else if (pem) {

View file

@ -1,7 +1,7 @@
const test = require('ava')
const crypto = require('crypto')
const { JWK: { importKey }, errors } = require('../..')
const { JWK: { importKey, generate }, errors } = require('../..')
const fixtures = require('../fixtures')
@ -85,3 +85,24 @@ test('failed to import throws an error', t => {
}, { instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: 'only RSA, EC and OKP asymmetric keys are supported' })
})
})
test('fails to import RSA without all optimization parameters', async t => {
const full = (await generate('RSA')).toJWK(true)
for (const param of ['p', 'q', 'dp', 'dq', 'qi']) {
const { [param]: omit, ...jwk } = full
t.throws(() => {
importKey(jwk)
}, { instanceOf: errors.JWKImportFailed, code: 'ERR_JWK_IMPORT_FAILED', message: 'all other private key parameters must be present when any one of them is present' })
}
})
test('fails to import JWK RSA with oth', async t => {
const jwk = (await generate('RSA')).toJWK(true)
t.throws(() => {
importKey({
...jwk,
oth: []
})
}, { instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: 'Private RSA keys with more than two primes are not supported' })
})