Files

126 lines
5.0 KiB
JavaScript

const test = require('ava')
const { keyObjectSupported } = require('../../lib/help/runtime_support')
const recipes = require('./recipes')
const { JWK: { asKey }, JWKS: { KeyStore } } = require('../..')
const errors = require('../../lib/errors')
test('public EC', t => {
const jwk = recipes.get('3.1')
const key = asKey(jwk)
t.true(key.toPEM().includes('BEGIN PUBLIC KEY'))
t.deepEqual(key.toJWK(), jwk)
t.deepEqual(key.toJWK(false), jwk)
t.throws(() => {
key.toJWK(true)
}, { instanceOf: TypeError, message: 'public key cannot be exported as private' })
t.throws(() => {
key.toPEM(false, { cipher: 'aes-256-cbc' })
}, { instanceOf: TypeError, message: 'cipher and passphrase can only be applied when exporting private keys' })
t.throws(() => {
key.toPEM(false, { passphrase: 'top secret' })
}, { instanceOf: TypeError, message: 'cipher and passphrase can only be applied when exporting private keys' })
t.throws(() => {
key.toPEM(true)
}, { instanceOf: TypeError, message: 'public key cannot be exported as private' })
})
test('private EC', t => {
const jwk = recipes.get('3.2')
const key = asKey(jwk)
t.true(key.toPEM(true, { type: 'sec1' }).includes('BEGIN EC PRIVATE KEY'))
if (keyObjectSupported) {
t.true(key.toPEM(true, { cipher: 'aes-256-cbc', passphrase: 'top secret' }).includes('BEGIN ENCRYPTED PRIVATE KEY'))
t.true(key.toPEM(true, { type: 'sec1', cipher: 'aes-256-cbc', passphrase: 'top secret' }).includes('ENCRYPTED'))
} else {
t.throws(() => {
key.toPEM(true, { cipher: 'aes-256-cbc', passphrase: 'top secret' }).includes('BEGIN ENCRYPTED PRIVATE KEY')
}, { instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: 'encrypted private keys are not supported in your Node.js runtime version' })
}
t.true(key.toPEM(true).includes('BEGIN PRIVATE KEY'))
t.true(key.toPEM().includes('BEGIN PUBLIC KEY'))
t.deepEqual(key.toJWK(true), jwk)
const { d, ...pub } = jwk
t.deepEqual(key.toJWK(), pub)
t.deepEqual(key.toJWK(false), pub)
t.throws(() => {
key.toPEM(false, { cipher: 'aes-256-cbc' })
}, { instanceOf: TypeError, message: 'cipher and passphrase can only be applied when exporting private keys' })
t.throws(() => {
key.toPEM(false, { passphrase: 'top secret' })
}, { instanceOf: TypeError, message: 'cipher and passphrase can only be applied when exporting private keys' })
})
test('public RSA', t => {
const jwk = recipes.get('3.3')
const key = asKey(jwk)
t.true(key.toPEM().includes('BEGIN PUBLIC KEY'))
t.deepEqual(key.toJWK(), jwk)
t.deepEqual(key.toJWK(false), jwk)
t.throws(() => {
key.toJWK(true)
}, { instanceOf: TypeError, message: 'public key cannot be exported as private' })
t.throws(() => {
key.toPEM(true)
}, { instanceOf: TypeError, message: 'public key cannot be exported as private' })
})
test('private RSA', t => {
const jwk = recipes.get('3.4')
const key = asKey(jwk)
t.true(key.toPEM(true, { type: 'pkcs1' }).includes('BEGIN RSA PRIVATE KEY'))
if (keyObjectSupported) {
t.true(key.toPEM(true, { cipher: 'aes-256-cbc', passphrase: 'top secret', type: 'pkcs1' }).includes('ENCRYPTED'))
t.true(key.toPEM(true, { type: 'pkcs1', cipher: 'aes-256-cbc', passphrase: 'top secret' }).includes('BEGIN RSA PRIVATE KEY'))
t.true(key.toPEM(true, { cipher: 'aes-256-cbc', passphrase: 'top secret' }).includes('BEGIN ENCRYPTED PRIVATE KEY'))
} else {
t.throws(() => {
key.toPEM(true, { cipher: 'aes-256-cbc', passphrase: 'top secret' }).includes('BEGIN ENCRYPTED PRIVATE KEY')
}, { instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: 'encrypted private keys are not supported in your Node.js runtime version' })
}
t.true(key.toPEM(true).includes('BEGIN PRIVATE KEY'))
t.true(key.toPEM().includes('BEGIN PUBLIC KEY'))
t.deepEqual(key.toJWK(true), jwk)
const { d, dp, dq, p, q, qi, ...pub } = jwk
t.deepEqual(key.toJWK(), pub)
t.deepEqual(key.toJWK(false), pub)
})
test('oct (1/2)', t => {
const jwk = recipes.get('3.5')
const key = asKey(jwk)
t.throws(() => {
key.toPEM()
}, { instanceOf: TypeError, message: 'symmetric keys cannot be exported as PEM' })
t.deepEqual(key.toJWK(true), jwk)
const { k, ...pub } = jwk
t.deepEqual(key.toJWK(), pub)
t.deepEqual(key.toJWK(false), pub)
})
test('oct (2/2)', t => {
const jwk = recipes.get('3.6')
const key = asKey(jwk)
t.deepEqual(key.toJWK(true), jwk)
const { k, ...pub } = jwk
t.deepEqual(key.toJWK(), pub)
t.deepEqual(key.toJWK(false), pub)
})
test('keystore .toJWKS()', t => {
const ec = recipes.get('3.2')
const { d: throwaway, ...pubEc } = ec
const rsa = recipes.get('3.4')
const { d, dp, dq, p, q, qi, ...pubRsa } = rsa
const oct = recipes.get('3.5')
const { k, ...pubOct } = oct
const ks = new KeyStore(asKey(ec), asKey(rsa), asKey(oct))
t.deepEqual(ks.toJWKS(true), { keys: [ec, rsa, oct] })
t.deepEqual(ks.toJWKS(), { keys: [pubEc, pubRsa, pubOct] })
t.deepEqual(ks.toJWKS(false), { keys: [pubEc, pubRsa, pubOct] })
ks.add(asKey(pubRsa))
t.deepEqual(ks.toJWKS(true), { keys: [ec, rsa, oct, pubRsa] })
})