Skip to content

Commit

Permalink
test: Refactor functional tests (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
gnarea authored Apr 4, 2023
1 parent b8766de commit b182cb6
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 76 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ async function init(): Promise<KmsRsaPssProvider> {
The following environment variables must be defined depending on the adapter:

- AWS adapter:
- `AWS_KMS_ENDPOINT` (optional).
- `AWS_KMS_REGION` (optional).
- [`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html) (optional when running on AWS infrastructure).
- `AWS_KMS_ENDPOINT` (optional when running on AWS infrastructure).
- `AWS_KMS_REGION` (optional when running on AWS infrastructure).
- GCP adapter:
- [`GOOGLE_APPLICATION_CREDENTIALS`](https://cloud.google.com/docs/authentication/getting-started) (optional when running on GCP infrastructure).
- `GCP_KMS_KEYRING` (required).
Expand Down
40 changes: 18 additions & 22 deletions src/functional_tests/aws.test.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
import { KMSClient } from '@aws-sdk/client-kms';
import { initKmsProviderFromEnv, KmsRsaPssProvider } from '../index';
import { RSA_PSS_CREATION_ALGORITHM, RSA_PSS_SIGN_ALGORITHM } from '../testUtils/webcrypto';
import { PLAINTEXT, verifyAsymmetricSignature } from './utils';

import { AwsKmsRsaPssProvider } from '../lib/aws/AwsKmsRsaPssProvider';
import { PLAINTEXT } from '../testUtils/stubs';
import {
NODEJS_CRYPTO,
RSA_PSS_CREATION_ALGORITHM,
RSA_PSS_SIGN_ALGORITHM,
} from '../testUtils/webcrypto';

const CLIENT = new KMSClient({
credentials: { accessKeyId: 'accessKeyId', secretAccessKey: 'secretAccessKey' },
endpoint: 'http://localhost:8080',
region: 'eu-west-2',
let provider: KmsRsaPssProvider;
let keyPair: CryptoKeyPair;
beforeAll(async () => {
provider = await initKmsProviderFromEnv('AWS');
keyPair = await provider.generateKey(RSA_PSS_CREATION_ALGORITHM, true, ['sign', 'verify']);
});
afterAll(async () => {
if (keyPair) {
await provider?.destroyKey(keyPair.privateKey);
}
await provider?.close();
});

test('AWS KMS', async () => {
const provider = new AwsKmsRsaPssProvider(CLIENT);
const keyPair = (await provider.generateKey(RSA_PSS_CREATION_ALGORITHM, true, [
'sign',
'verify',
])) as CryptoKeyPair;
const signature = await provider.sign(RSA_PSS_SIGN_ALGORITHM, keyPair.privateKey, PLAINTEXT);
const { publicKey, privateKey } = keyPair;

const signature = await provider.sign(RSA_PSS_SIGN_ALGORITHM, privateKey, PLAINTEXT);

await expect(
NODEJS_CRYPTO.subtle.verify(RSA_PSS_SIGN_ALGORITHM, keyPair.publicKey, signature, PLAINTEXT),
).resolves.toBe(true);
await expect(verifyAsymmetricSignature(publicKey, signature, PLAINTEXT)).resolves.toBe(true);
});
59 changes: 28 additions & 31 deletions src/functional_tests/gcp.test.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,52 @@
import { constants, createVerify } from 'crypto';
import { KeyManagementServiceClient } from '@google-cloud/kms';

import { initKmsProviderFromEnv, KmsRsaPssProvider } from '../index';
import { derPublicKeyToPem } from '../testUtils/asn1';
import { createKeyRingIfMissing } from './gcpUtils';
import {
derSerializePublicKey,
RSA_PSS_CREATION_ALGORITHM,
RSA_PSS_SIGN_ALGORITHM,
} from '../testUtils/webcrypto';

const PLAINTEXT = Buffer.from('this is the plaintext');
import { PLAINTEXT, verifyAsymmetricSignature } from './utils';
import { RSA_PSS_CREATION_ALGORITHM, RSA_PSS_SIGN_ALGORITHM } from '../testUtils/webcrypto';

if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
throw new Error('GOOGLE_APPLICATION_CREDENTIALS must be defined');
}

let gcpProvider: KmsRsaPssProvider;
let provider: KmsRsaPssProvider;
let keyPair: CryptoKeyPair;
beforeAll(async () => {
gcpProvider = await initKmsProviderFromEnv('GCP');
provider = await initKmsProviderFromEnv('GCP');
await createKeyRingIfMissing(process.env.GCP_KMS_KEYRING!, process.env.GCP_KMS_LOCATION!);

keyPair = await gcpProvider.generateKey(RSA_PSS_CREATION_ALGORITHM, true, ['sign', 'verify']);
keyPair = await provider.generateKey(RSA_PSS_CREATION_ALGORITHM, true, ['sign', 'verify']);
});
afterAll(async () => {
if (keyPair) {
await gcpProvider?.destroyKey(keyPair.privateKey);
await provider?.destroyKey(keyPair.privateKey);
}
await gcpProvider?.close();
await provider?.close();
});

test('Lifecycle', async () => {
test('GCP KMS', async () => {
const { publicKey, privateKey } = keyPair;

const signature = await gcpProvider.sign(RSA_PSS_SIGN_ALGORITHM, privateKey, PLAINTEXT);
const signature = await provider.sign(RSA_PSS_SIGN_ALGORITHM, privateKey, PLAINTEXT);

await expect(verifyAsymmetricSignature(publicKey, signature, PLAINTEXT)).resolves.toBe(true);
});

async function verifyAsymmetricSignature(
publicKey: CryptoKey,
signature: ArrayBuffer,
plaintext: Buffer,
): Promise<boolean> {
const verify = createVerify('sha256');
verify.update(plaintext);
verify.end();

const publicKeyDer = await derSerializePublicKey(publicKey);
return verify.verify(
{ key: derPublicKeyToPem(publicKeyDer), padding: constants.RSA_PKCS1_PSS_PADDING },
new Uint8Array(signature),
);
export async function createKeyRingIfMissing(keyRingId: string, location: string): Promise<string> {
const kmsClient = new KeyManagementServiceClient();
const project = await kmsClient.getProjectId();
const keyRingName = kmsClient.keyRingPath(project, location, keyRingId);
try {
await kmsClient.getKeyRing({ name: keyRingName });
} catch (err) {
if ((err as any).code !== 5) {
throw err;
}

// Key ring was not found
const locationPath = kmsClient.locationPath(project, location);
await kmsClient.createKeyRing({ parent: locationPath, keyRingId });
}

await kmsClient.close();
return keyRingName;
}
21 changes: 0 additions & 21 deletions src/functional_tests/gcpUtils.ts

This file was deleted.

22 changes: 22 additions & 0 deletions src/functional_tests/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { constants, createVerify } from 'crypto';

import { derSerializePublicKey } from '../testUtils/webcrypto';
import { derPublicKeyToPem } from '../testUtils/asn1';

export const PLAINTEXT = Buffer.from('this is the plaintext');

export async function verifyAsymmetricSignature(
publicKey: CryptoKey,
signature: ArrayBuffer,
plaintext: Buffer,
): Promise<boolean> {
const verify = createVerify('sha256');
verify.update(plaintext);
verify.end();

const publicKeyDer = await derSerializePublicKey(publicKey);
return verify.verify(
{ key: derPublicKeyToPem(publicKeyDer), padding: constants.RSA_PKCS1_PSS_PADDING },
new Uint8Array(signature),
);
}

0 comments on commit b182cb6

Please sign in to comment.