Skip to content

Commit

Permalink
fix: reject rsa keys without all factors and exponents with a specifi…
Browse files Browse the repository at this point in the history
…c message
  • Loading branch information
panva committed May 23, 2019
1 parent 6b7c92a commit b0ff436
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
2 changes: 1 addition & 1 deletion lib/help/asn1/rsa_private_key.js
Original file line number Diff line number Diff line change
@@ -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(),
Expand Down
16 changes: 15 additions & 1 deletion lib/help/key_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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),
Expand Down
6 changes: 5 additions & 1 deletion lib/jwk/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
23 changes: 22 additions & 1 deletion test/jwk/import.test.js
Original file line number Diff line number Diff line change
@@ -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')

Expand Down Expand Up @@ -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' })
})

0 comments on commit b0ff436

Please sign in to comment.