import { KeySet, calculateThumbprint, KeyObjects, RSAKey, ECKey, OKP, ERRORS } from './../src/core/jwk-utils'; import { KEY_FORMATS, KTYS, ALGORITHMS } from './../src/core/globals'; import { TD_KEY_PAIRS } from './data/key-pairs.testdata'; import nock from 'nock'; describe('JWK functions', function () { test('RSAKey functions', async () => { let kid: string = 'key_1'; let publicJWK: KeyObjects.RSAPublicKeyObject = TD_KEY_PAIRS.rsa_1.publicJWK; let publicMinimalJWK = TD_KEY_PAIRS.rsa_1.publicMinimalJWK; let publicJWKThumbprint = TD_KEY_PAIRS.rsa_1.publicJWKThumbprint; let privateJWK: KeyObjects.RSAPrivateKeyObject = TD_KEY_PAIRS.rsa_1.privateJWK; let privateMinimalJWK = TD_KEY_PAIRS.rsa_1.privateMinimalJWK; let privatePem = TD_KEY_PAIRS.rsa_1.privatePem; let publicPem = TD_KEY_PAIRS.rsa_1.publicPem; let key = RSAKey.fromKey({ key: publicPem, kid: kid, use: 'enc', alg: ALGORITHMS[ALGORITHMS.RS256], kty: KTYS[KTYS.RSA], format: KEY_FORMATS.PKCS8_PEM, isPrivate: false }); expect(key.toJWK()).toMatchObject(publicJWK); let pem = key.exportKey(KEY_FORMATS.PKCS8_PEM); expect(pem.split('\n').join('')).toEqual(publicPem.split('\n').join('')); let minimalJWK = key.getMinimalJWK(false); expect(minimalJWK).toMatchObject(publicMinimalJWK); let thumbprint = calculateThumbprint(minimalJWK); expect(thumbprint).toEqual(publicJWKThumbprint); key = RSAKey.fromKey({ key: privatePem, kid: kid, use: 'enc', alg: ALGORITHMS[ALGORITHMS.RS256], kty: KTYS[KTYS.RSA], format: KEY_FORMATS.PKCS1_PEM, isPrivate: true }); expect(key.toJWK(true)).toMatchObject(privateJWK); pem = key.exportKey(KEY_FORMATS.PKCS1_PEM); expect(pem.split('\n').join('')).toEqual(privatePem.split('\n').join('')); minimalJWK = key.getMinimalJWK(true); expect(minimalJWK).toMatchObject(privateMinimalJWK); }); test('ECKey functions', async () => { let kid: string = 'key_1'; let publicJWK: KeyObjects.ECPublicKeyObject = TD_KEY_PAIRS.ec_1.publicJWK; let publicMinimalJWK = TD_KEY_PAIRS.ec_1.publicMinimalJWK; let publicJWKThumbprint = TD_KEY_PAIRS.ec_1.publicJWKThumbprint; let privateJWK: KeyObjects.ECPrivateKeyObject = TD_KEY_PAIRS.ec_1.privateJWK; let privateMinimalJWK = TD_KEY_PAIRS.ec_1.privateMinimalJWK; let key = ECKey.fromKey(privateJWK); let privateHex = key.exportKey(KEY_FORMATS.HEX); let retrievedJWK = ECKey.fromKey({ key: privateHex, kid: kid, use: 'enc', alg: ALGORITHMS[ALGORITHMS.ES256K], kty: KTYS[KTYS.EC], format: KEY_FORMATS.HEX, isPrivate: true }).toJWK(true); expect(retrievedJWK).toMatchObject(privateJWK); let minimalJWK = key.getMinimalJWK(true); expect(minimalJWK).toMatchObject(privateMinimalJWK); key = ECKey.fromKey(publicJWK); let publicHex = key.exportKey(KEY_FORMATS.HEX); retrievedJWK = ECKey.fromKey({ key: publicHex, kid: kid, use: 'enc', alg: ALGORITHMS[ALGORITHMS.ES256K], kty: KTYS[KTYS.EC], format: KEY_FORMATS.HEX, isPrivate: false }).toJWK(); expect(retrievedJWK).toMatchObject(publicJWK); minimalJWK = key.getMinimalJWK(false); expect(minimalJWK).toMatchObject(publicMinimalJWK); let thumbprint = calculateThumbprint(minimalJWK); expect(thumbprint).toEqual(publicJWKThumbprint); }); test('OKP functions', async () => { let kid: string = 'key_1'; let publicJWK: KeyObjects.OKPPublicKeyObject = TD_KEY_PAIRS.okp_1.publicJWK; let publicMinimalJWK = TD_KEY_PAIRS.okp_1.publicMinimalJWK; let publicJWKThumbprint = TD_KEY_PAIRS.okp_1.publicJWKThumbprint; let privateJWK: KeyObjects.OKPPrivateKeyObject = TD_KEY_PAIRS.okp_1.privateJWK; let privateMinimalJWK = TD_KEY_PAIRS.okp_1.privateMinimalJWK; let key = OKP.fromKey(privateJWK); let privateBase58 = key.exportKey(KEY_FORMATS.BASE58); let retrievedJWK = OKP.fromKey({ key: privateBase58, kid: kid, use: 'enc', alg: ALGORITHMS[ALGORITHMS.EdDSA], kty: KTYS[KTYS.OKP], format: KEY_FORMATS.BASE58, isPrivate: true }).toJWK(true); expect(retrievedJWK).toMatchObject(privateJWK); let minimalJWK = key.getMinimalJWK(true); expect(minimalJWK).toMatchObject(privateMinimalJWK); key = OKP.fromKey(publicJWK); let publicBase58 = key.exportKey(KEY_FORMATS.BASE58); retrievedJWK = OKP.fromKey({ key: publicBase58, kid: kid, use: 'enc', alg: ALGORITHMS[ALGORITHMS.EdDSA], kty: KTYS[KTYS.OKP], format: KEY_FORMATS.BASE58, isPrivate: false }).toJWK(); expect(retrievedJWK).toMatchObject(publicJWK); minimalJWK = key.getMinimalJWK(false); expect(minimalJWK).toMatchObject(publicMinimalJWK); let thumbprint = calculateThumbprint(minimalJWK); expect(thumbprint).toEqual(publicJWKThumbprint); }); }); describe('JWKS', function () { test('KeySet functions', async () => { let jwks = new KeySet(); expect(jwks.size()).toEqual(0); const rsa1 = TD_KEY_PAIRS.rsa_2.publicJWK; const rsa2 = TD_KEY_PAIRS.rsa_3.publicJWK; const ec1 = TD_KEY_PAIRS.ec_2.publicJWK; const ec2 = TD_KEY_PAIRS.ec_3.publicJWK; const okp1 = TD_KEY_PAIRS.okp_2.publicJWK; const okp2 = TD_KEY_PAIRS.okp_3.publicJWK; const set = { keys: [rsa1, ec1, ec2, okp1] }; jwks.setKeys(set.keys); expect(jwks.size()).toEqual(set.keys.length); jwks.addKey(rsa2); expect(jwks.size()).toEqual(5); jwks.addKey(okp2); expect(jwks.size()).toEqual(6); jwks.removeKey('rsa1'); expect(jwks.size()).toEqual(5); let retrieved = jwks.getKey('ec1'); expect(retrieved[0].toJWK(true)).toEqual(ec1); nock('http://localhost') .get('/keys') .reply(200, set) .get('/invalidUri') .reply(404, 'Not found'); jwks = new KeySet(); await jwks.setURI('http://localhost/keys'); expect(jwks.size()).toEqual(set.keys.length); jwks = new KeySet(); let jwksResolvePromise = jwks.setURI('http://localhost/invalidUri'); await expect(jwksResolvePromise).rejects.toEqual(new Error(ERRORS.URI_ERROR)); }); });