Skip to content

Commit

Permalink
fix: handle private EC keys without public component (#86)
Browse files Browse the repository at this point in the history
Only possible to handle when KeyObject API is available in the runtime.

closes #85
  • Loading branch information
panva committed Jul 1, 2020
1 parent 899d601 commit e8ad389
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
18 changes: 15 additions & 3 deletions lib/help/key_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { EOL } = require('os')

const errors = require('../errors')

const { keyObjectSupported } = require('./runtime_support')
const { createPublicKey } = require('./key_object')
const base64url = require('./base64url')
const asn1 = require('./asn1')
Expand Down Expand Up @@ -89,10 +90,21 @@ const keyObjectToJWK = {
const ECPrivateKey = asn1.get('ECPrivateKey')

const { privateKey, algorithm: { parameters: { value: crv } } } = PrivateKeyInfo.decode(der)
const { privateKey: d, publicKey: { data: publicKey } } = ECPrivateKey.decode(privateKey)
const { privateKey: d, publicKey } = ECPrivateKey.decode(privateKey)

if (typeof publicKey === 'undefined') {
if (keyObjectSupported) {
return {
...keyObjectToJWK.ec.public(createPublicKey(keyObject)),
d: base64url.encodeBuffer(d)
}
}

const x = publicKey.slice(1, ((publicKey.length - 1) / 2) + 1)
const y = publicKey.slice(((publicKey.length - 1) / 2) + 1)
throw new errors.JOSENotSupported('Private EC keys without the public key embedded are not supported in your Node.js runtime version')
}

const x = publicKey.data.slice(1, ((publicKey.data.length - 1) / 2) + 1)
const y = publicKey.data.slice(((publicKey.data.length - 1) / 2) + 1)

return {
kty: 'EC',
Expand Down
27 changes: 26 additions & 1 deletion test/jwk/import.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const test = require('ava')
const { JWS, JWE, JWK: { asKey, importKey, generate }, errors } = require('../..')

const { edDSASupported, keyObjectSupported } = require('../../lib/help/runtime_support')
const { createSecretKey } = require('../../lib/help/key_object')
const { createSecretKey, createPrivateKey } = require('../../lib/help/key_object')
const { generateKeyPairSync } = require('../macros/generate')
const fixtures = require('../fixtures')

Expand Down Expand Up @@ -177,3 +177,28 @@ if (keyObjectSupported) {
}, { instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: 'X.509 certificates are not supported in your Node.js runtime version' })
})
}

// https://github.com/panva/jose/issues/85
{
const pem = `-----BEGIN PRIVATE KEY-----
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCXpUVoM4DfOtMyRVtC
eGSpVL+1tMBirnUGJHY6Y7mSHg==
-----END PRIVATE KEY-----`

if (keyObjectSupported) {
test('EC private keys without public one', t => {
asKey(createPrivateKey(pem))
asKey(pem)
t.pass()
})
} else {
test('EC private keys without public one', t => {
t.throws(() => {
asKey(createPrivateKey(pem))
}, { instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: 'Private EC keys without the public key embedded are not supported in your Node.js runtime version' })
t.throws(() => {
asKey(pem)
}, { instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: 'Private EC keys without the public key embedded are not supported in your Node.js runtime version' })
})
}
}

0 comments on commit e8ad389

Please sign in to comment.