Skip to content

Commit

Permalink
refactor: use import rather then new
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Mar 11, 2019
1 parent d6923bd commit 2ad4418
Show file tree
Hide file tree
Showing 19 changed files with 85 additions and 83 deletions.
4 changes: 3 additions & 1 deletion lib/help/key_utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const keyto = require('@trust/keyto')

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

const SUPPORTED = new Set(['EC', 'RSA'])

module.exports.keyObjectToJWK = (keyObject) => {
Expand All @@ -13,7 +15,7 @@ module.exports.keyObjectToJWK = (keyObject) => {

module.exports.jwkToPem = (jwk) => {
if (!SUPPORTED.has(jwk.kty)) {
throw new TypeError('unsupported kty')
throw new errors.JOSENotSupported(`unsupported key type: ${jwk.kty}`)
}

return keyto.from(jwk, 'jwk').toString('pem', jwk.d ? 'private_pkcs8' : 'public_pkcs8')
Expand Down
4 changes: 2 additions & 2 deletions lib/jwa/ecdh/dir.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const { strict: assert } = require('assert')

const KEYLENGTHS = require('../../help/key_lengths')
const ECKey = require('../../jwk/key/ec')
const { generateSync } = require('../../jwk/generate')

const derive = require('./derive')

const wrapKey = (key, payload, { enc }) => {
const epk = ECKey.generateSync(key.crv)
const epk = generateSync('EC', key.crv)

const derivedKey = derive(enc, KEYLENGTHS[enc], epk, key)

Expand Down
4 changes: 2 additions & 2 deletions lib/jwa/ecdh/kw.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const { strict: assert } = require('assert')

const { KEYOBJECT } = require('../../help/symbols')
const ECKey = require('../../jwk/key/ec')
const { generateSync } = require('../../jwk/generate')

const derive = require('./derive')

const wrapKey = (wrap, derive, key, payload) => {
const epk = ECKey.generateSync(key.crv)
const epk = generateSync('EC', key.crv)

const derivedKey = derive(epk, key, payload)

Expand Down
6 changes: 3 additions & 3 deletions lib/jwe/encrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const base64url = require('../help/base64url')
const isObject = require('../help/is_object')
const deepClone = require('../help/deep_clone')
const Key = require('../jwk/key/base')
const OctKey = require('../jwk/key/oct')
const importKey = require('../jwk/import')
const { JWEInvalid } = require('../errors')
const { check, wrapKey, encrypt } = require('../jwa')

Expand Down Expand Up @@ -123,12 +123,12 @@ class Encrypt {
let direct

if (key.kty === 'oct' && alg === 'dir') {
this[CEK] = new OctKey(key[KEYOBJECT], { use: 'enc', alg: enc })
this[CEK] = importKey(key[KEYOBJECT], { use: 'enc', alg: enc })
wrapped = ''
} else {
({ wrapped, header: generatedHeader, direct } = wrapKey(alg, key, this[CEK][KEYOBJECT].export(), { enc, alg }))
if (direct) {
this[CEK] = new OctKey(createSecretKey(wrapped), { use: 'enc', alg: enc })
this[CEK] = importKey(createSecretKey(wrapped), { use: 'enc', alg: enc })
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/jwe/generate_cek.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { randomBytes, createSecretKey } = require('crypto')

const KEYLENGTHS = require('../help/key_lengths')
const OctKey = require('../jwk/key/oct')
const importKey = require('../jwk/import')

module.exports = alg => new OctKey(createSecretKey(randomBytes(KEYLENGTHS[alg] / 8)), { use: 'enc', alg })
module.exports = alg => importKey(createSecretKey(randomBytes(KEYLENGTHS[alg] / 8)), { use: 'enc', alg })
10 changes: 4 additions & 6 deletions lib/jwk/generate.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
const errors = require('../errors')

const RSAKey = require('./key/rsa')
const ECKey = require('./key/ec')
const OctKey = require('./key/oct')

const generate = async (kty, ...args) => {
switch (kty) {
case 'rsa':
case 'RSA':
return RSAKey.generate(...args)
case 'ec':
case 'EC':
return ECKey.generate(...args)
case 'oct':
return OctKey.generate(...args)
default:
throw new TypeError('invalid key type')
throw new errors.JOSENotSupported(`unsupported key type: ${kty}`)
}
}

const generateSync = (kty, ...args) => {
switch (kty) {
case 'rsa':
case 'RSA':
return RSAKey.generateSync(...args)
case 'ec':
case 'EC':
return ECKey.generateSync(...args)
case 'oct':
return OctKey.generateSync(...args)
default:
throw new TypeError('invalid key type')
throw new errors.JOSENotSupported(`unsupported key type: ${kty}`)
}
}

Expand Down
14 changes: 7 additions & 7 deletions lib/jwk/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ const importKey = (key, parameters) => {
}
parameters = mergedParameters(parameters, key)
} else if (typeof key === 'object' && 'kty' in key) { // assume JWK formatted asymmetric key <Object>
let parsedJWK
let pem
try {
parsedJWK = jwkToPem(key)
pem = jwkToPem(key)
} catch (err) {}
if (parsedJWK && key.d) {
privateKey = createPrivateKey(parsedJWK)
} else if (parsedJWK) {
publicKey = createPublicKey(parsedJWK)
if (pem && key.d) {
privateKey = createPrivateKey(pem)
} else if (pem) {
publicKey = createPublicKey(pem)
}
parameters = mergedParameters(parameters, key)
} else { // <Object> | <string> | <Buffer> passed to crypto.createPrivateKey or crypto.createPublicKey or <Buffer> passed to crypto.createSecretKey
Expand All @@ -82,7 +82,7 @@ const importKey = (key, parameters) => {
return new ECKey(keyObject, parameters)
default:
// TODO: test this branch once https://github.com/nodejs/node/pull/26319 is released
throw new errors.JOSENotSupported('only RSA ane EC asymmetric keys are supported')
throw new errors.JOSENotSupported('only RSA and EC asymmetric keys are supported')
}
} else if (secret) {
return new OctKey(keyObject, parameters)
Expand Down
1 change: 1 addition & 0 deletions lib/jwk/key/ec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Object.freeze(EC_PUBLIC)
const EC_PRIVATE = new Set([...EC_PUBLIC, 'd'])
Object.freeze(EC_PRIVATE)

// Elliptic Curve Key Type
class ECKey extends Key {
constructor (...args) {
super(...args)
Expand Down
1 change: 1 addition & 0 deletions lib/jwk/key/oct.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Object.freeze(OCT_PUBLIC)
const OCT_PRIVATE = new Set(['k'])
Object.freeze(OCT_PRIVATE)

// Octet sequence Key Type
class OctKey extends Key {
constructor (...args) {
super(...args)
Expand Down
1 change: 1 addition & 0 deletions lib/jwk/key/rsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Object.freeze(RSA_PUBLIC)
const RSA_PRIVATE = new Set([...RSA_PUBLIC, 'd', 'p', 'q', 'dp', 'dq', 'qi'])
Object.freeze(RSA_PRIVATE)

// RSA Key Type
class RSAKey extends Key {
constructor (...args) {
super(...args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const key = importKey(Buffer.from(pwd))
const keystoreEmpty = new KeyStore()
const keystoreMatchOne = new KeyStore(generateSync(key.kty, key.length, { alg: key.alg, use: key.use }), key)
const keystoreMatchMore = new KeyStore(generateSync(key.kty, key.length, { alg: key.alg, use: key.use, kid: key.kid }), key, importKey(key))
const keystoreMatchNone = new KeyStore(generateSync('ec'), generateSync('rsa'))
const keystoreMatchNone = new KeyStore(generateSync('EC'), generateSync('RSA'))

test(`${recipe.title} - compact encrypt`, t => {
const res = JWE.encrypt(plaintext, key, prot)
Expand Down
2 changes: 1 addition & 1 deletion test/cookbook/rfc7797.4_1.hmac-sha2_b64_false.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const key = importKey(jwk)
const keystoreEmpty = new KeyStore()
const keystoreMatchOne = new KeyStore(generateSync(key.kty, key.length, { alg: key.alg, use: key.use }), key)
const keystoreMatchMore = new KeyStore(generateSync(key.kty, key.length, { alg: key.alg, use: key.use, kid: key.kid }), key, importKey(key))
const keystoreMatchNone = new KeyStore(generateSync('ec'), generateSync('rsa'))
const keystoreMatchNone = new KeyStore(generateSync('EC'), generateSync('RSA'))

test(`${recipe.title} - compact sign`, t => {
t.is(JWS.sign(payload, key, header), recipe.output.compact)
Expand Down
5 changes: 3 additions & 2 deletions test/help/key_utils.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
const test = require('ava')
const { createPublicKey, createPrivateKey } = require('crypto')

const { errors } = require('../..')
const { keyObjectToJWK, jwkToPem } = require('../../lib/help/key_utils')
const { JWK: fixtures } = require('../fixtures')
const clone = obj => JSON.parse(JSON.stringify(obj))

test('jwkToPem only works for EC and RSA', t => {
t.throws(() => {
jwkToPem({ kty: 'oct' })
}, { instanceOf: TypeError, message: 'unsupported kty' })
jwkToPem({ kty: 'OKP' })
}, { instanceOf: errors.JOSENotSupported, message: 'unsupported key type: OKP' })
})

test('RSA Public key', t => {
Expand Down
2 changes: 1 addition & 1 deletion test/jwe/complete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const isObject = require('../../lib/help/is_object')
const Key = require('../../lib/jwk/key/base')
const { JWKS, JWK: { generateSync }, JWE } = require('../..')
const key = generateSync('oct')
const ks = new JWKS.KeyStore(generateSync('ec'), key)
const ks = new JWKS.KeyStore(generateSync('EC'), key)

const complete = (t, jwe, k, ...keys) => {
if (typeof k === 'string') {
Expand Down
38 changes: 19 additions & 19 deletions test/jwe/sanity.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ test('verify key or store argument', t => {
})

test('JWE no alg specified but cannot resolve', t => {
const k1 = generateSync('rsa', undefined, { alg: 'foo' })
const k1 = generateSync('RSA', undefined, { alg: 'foo' })
t.throws(() => {
JWE.encrypt('foo', k1)
}, { instanceOf: errors.JWEInvalid, code: 'ERR_JWE_INVALID', message: 'could not resolve a usable "alg" for a recipient' })
})

test('JWE no alg/enc specified (multi recipient)', t => {
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(generateSync('rsa'))
encrypt.recipient(generateSync('ec'))
encrypt.recipient(generateSync('RSA'))
encrypt.recipient(generateSync('EC'))
encrypt.recipient(generateSync('oct', 256))

const jwe = encrypt.encrypt('general')
Expand All @@ -66,9 +66,9 @@ test('JWE no alg/enc specified (multi recipient)', t => {

test('JWE no alg/enc specified (multi recipient) with per-recipient headers', t => {
const encrypt = new JWE.Encrypt('foo')
let k1 = generateSync('rsa', undefined, { kid: 'kid_1' })
let k1 = generateSync('RSA', undefined, { kid: 'kid_1' })
encrypt.recipient(k1, { kid: k1.kid })
let k2 = generateSync('ec', undefined, { kid: 'kid_2' })
let k2 = generateSync('EC', undefined, { kid: 'kid_2' })
encrypt.recipient(k2, { kid: k2.kid })
let k3 = generateSync('oct', 256, { kid: 'kid_3' })
encrypt.recipient(k3, { kid: k3.kid })
Expand All @@ -84,7 +84,7 @@ test('JWE no alg/enc specified (multi recipient) with per-recipient headers', t

test('JWE no alg/enc specified (single rsa), no protected header', t => {
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(generateSync('rsa'))
encrypt.recipient(generateSync('RSA'))

const jwe = encrypt.encrypt('flattened')
t.is(jwe.unprotected, undefined)
Expand All @@ -93,7 +93,7 @@ test('JWE no alg/enc specified (single rsa), no protected header', t => {
})

test('JWE no alg/enc specified (single rsa), with protected header', t => {
const k = generateSync('rsa', undefined, { kid: 'jwk key id' })
const k = generateSync('RSA', undefined, { kid: 'jwk key id' })
const encrypt = new JWE.Encrypt('foo', { kid: k.kid })
encrypt.recipient(k)

Expand All @@ -104,7 +104,7 @@ test('JWE no alg/enc specified (single rsa), with protected header', t => {
})

test('JWE no alg specified (single rsa), with protected header', t => {
const k = generateSync('rsa')
const k = generateSync('RSA')
const encrypt = new JWE.Encrypt('foo', { enc: 'A256CBC-HS512' })
encrypt.recipient(k)

Expand All @@ -115,7 +115,7 @@ test('JWE no alg specified (single rsa), with protected header', t => {
})

test('JWE no alg specified (single rsa), with unprotected header', t => {
const k = generateSync('rsa')
const k = generateSync('RSA')
const encrypt = new JWE.Encrypt('foo', undefined, { enc: 'A256CBC-HS512' })
encrypt.recipient(k)

Expand All @@ -137,7 +137,7 @@ test('JWE no alg/enc specified (single oct)', t => {

test('JWE no alg/enc specified (single ec)', t => {
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(generateSync('ec'))
encrypt.recipient(generateSync('EC'))

const jwe = encrypt.encrypt('flattened')
t.is(jwe.unprotected, undefined)
Expand All @@ -148,7 +148,7 @@ test('JWE no alg/enc specified (single ec)', t => {

test('JWE no alg/enc specified (only on a key)', t => {
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(generateSync('rsa', undefined, { alg: 'RSA1_5', use: 'enc' }))
encrypt.recipient(generateSync('RSA', undefined, { alg: 'RSA1_5', use: 'enc' }))

const jwe = encrypt.encrypt('flattened')
t.is(jwe.unprotected, undefined)
Expand Down Expand Up @@ -310,7 +310,7 @@ test('JWE valid serialization must be provided', t => {

test('JWE compact does not support multiple recipients', t => {
const k = generateSync('oct')
const k2 = generateSync('ec')
const k2 = generateSync('EC')
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(k)
encrypt.recipient(k2)
Expand All @@ -335,7 +335,7 @@ test('JWE compact does not support aad', t => {

test('JWE flattened does not support multiple recipients', t => {
const k = generateSync('oct')
const k2 = generateSync('ec')
const k2 = generateSync('EC')
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(k)
encrypt.recipient(k2)
Expand All @@ -346,7 +346,7 @@ test('JWE flattened does not support multiple recipients', t => {

test('JWE must only have one Content Encryption algorithm (encrypt)', t => {
const k = generateSync('oct')
const k2 = generateSync('rsa')
const k2 = generateSync('RSA')
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(k, { enc: 'A128CBC-HS256' })
encrypt.recipient(k2, { enc: 'A128GCM' })
Expand All @@ -357,7 +357,7 @@ test('JWE must only have one Content Encryption algorithm (encrypt)', t => {

test('JWE must only have one Content Encryption algorithm (decrypt)', t => {
const k = generateSync('oct')
const k2 = generateSync('rsa')
const k2 = generateSync('RSA')
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(k, { enc: 'A128GCM' })
encrypt.recipient(k2, { enc: 'A128GCM' })
Expand All @@ -370,7 +370,7 @@ test('JWE must only have one Content Encryption algorithm (decrypt)', t => {

test('JWE must have a Content Encryption algorithm (decrypt)', t => {
const k = generateSync('oct')
const k2 = generateSync('rsa')
const k2 = generateSync('RSA')
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(k, { enc: 'A128GCM' })
encrypt.recipient(k2, { enc: 'A128GCM' })
Expand All @@ -384,7 +384,7 @@ test('JWE must have a Content Encryption algorithm (decrypt)', t => {

test('JWE oct dir is only usable with a single recipient', t => {
const k = generateSync('oct', undefined, { alg: 'A128CBC-HS256', use: 'enc' })
const k2 = generateSync('rsa')
const k2 = generateSync('RSA')
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(k, { alg: 'dir' })
encrypt.recipient(k2)
Expand All @@ -394,8 +394,8 @@ test('JWE oct dir is only usable with a single recipient', t => {
})

test('JWE EC ECDH-ES is only usable with a single recipient', t => {
const k = generateSync('ec', undefined, { alg: 'ECDH-ES', use: 'enc' })
const k2 = generateSync('rsa')
const k = generateSync('EC', undefined, { alg: 'ECDH-ES', use: 'enc' })
const k2 = generateSync('RSA')
const encrypt = new JWE.Encrypt('foo')
encrypt.recipient(k, { alg: 'ECDH-ES' })
encrypt.recipient(k2)
Expand Down
Loading

0 comments on commit 2ad4418

Please sign in to comment.