Skip to content

Commit

Permalink
[KeyVault-Keys] [CryptographyClient] tests and recordings (#4611)
Browse files Browse the repository at this point in the history
Tests and recordings
  • Loading branch information
sadasant committed Aug 1, 2019
1 parent 2b06e6b commit b21c762
Show file tree
Hide file tree
Showing 14 changed files with 7,995 additions and 4,803 deletions.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

8 changes: 2 additions & 6 deletions sdk/keyvault/keyvault-keys/tests/CRUD.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import * as assert from "assert";
import { KeysClient, CreateEcKeyOptions, UpdateKeyOptions, GetKeyOptions } from "../src";
import { RestError } from "@azure/core-http";
import { isNode, retry, env } from "./utils/recorder";
import { retry, env } from "./utils/recorder";
import { authenticate } from "./utils/testAuthentication";
import TestClient from "./utils/testClient";
import { AbortController } from "@azure/abort-controller";
Expand Down Expand Up @@ -50,11 +50,7 @@ describe("Keys client - create, read, update and delete operations", () => {
} catch (e) {
error = e;
}
if (isNode) {
assert.equal(error.message, "The request was aborted");
} else {
assert.equal(error.message, "Failed to send the request.");
}
assert.equal(error.message, "The request was aborted");
});

it("cannot create a key with an empty name", async function() {
Expand Down
135 changes: 135 additions & 0 deletions sdk/keyvault/keyvault-keys/tests/crypto.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import * as assert from "assert";
import * as crypto from "crypto";
import * as constants from "constants";
import { isNode } from "@azure/core-http";
import { ClientSecretCredential } from "@azure/identity";
import { CryptographyClient, Key, KeysClient } from "../src";
import { authenticate } from "./utils/testAuthentication";
import TestClient from "./utils/testClient";
import { isRecording } from "./utils/recorder";
import { stringToUint8Array, uint8ArrayToString } from "./utils/crypto";

let keyto: any;
if (isNode) {
keyto = require("@trust/keyto");
}

describe("CryptographyClient (all decrypts happen remotely)", () => {
let client: KeysClient;
let testClient: TestClient;
let cryptoClient: CryptographyClient;
let recorder: any;
let credential: ClientSecretCredential;
let keyName: string;
let key: Key;
let keyVaultUrl: string;
let keyUrl: string;

before(async function() {
const authentication = await authenticate(this);
client = authentication.client;
recorder = authentication.recorder;
testClient = authentication.testClient;
credential = authentication.credential;
keyName = testClient.formatName("cryptography-client-test");
key = await client.createKey(keyName, "RSA");
keyVaultUrl = key.vaultUrl;
keyUrl = key.keyMaterial!.kid as string;
cryptoClient = new CryptographyClient(keyVaultUrl, key.keyMaterial!.kid!, credential);
});

after(async function() {
await testClient.flushKey(keyName);
recorder.stop();
});

// The tests follow

it("getKey from client initialized with a key URL", async function() {
const getKeyResult = await cryptoClient.getKey();
assert.equal(getKeyResult.kid, keyUrl);
});

it("getKey from client initialized with a JWK key", async function() {
const jwtKeyClient = new CryptographyClient(keyVaultUrl, key.keyMaterial!, credential);
const getKeyResult = await jwtKeyClient.getKey();
assert.equal(getKeyResult.kid, key.keyMaterial!.kid);
});

if (isRecording) {
it("encrypt & decrypt with RSA1_5", async function() {
const text = this.test!.title;
const encryptResult = await cryptoClient.encrypt("RSA1_5", stringToUint8Array(text));
const decryptResult = await cryptoClient.decrypt("RSA1_5", encryptResult.result);
const decryptedText = uint8ArrayToString(decryptResult.result);
assert.equal(text, decryptedText);
});

if (isNode) {
it("manually encrypt locally and decrypt remotely, both with RSA1_5", async function() {
const text = this.test!.title;
const key = await cryptoClient.getKey();
const keyPEM = keyto.from(key, "jwk").toString("pem", "public_pkcs1");
const padded: any = { key: keyPEM, padding: constants.RSA_PKCS1_PADDING };
const encrypted = crypto.publicEncrypt(padded, Buffer.from(text));
const decryptResult = await cryptoClient.decrypt("RSA1_5", encrypted);
const decryptedText = uint8ArrayToString(decryptResult.result);
assert.equal(text, decryptedText);
});
}

it("encrypt & decrypt with RSA-OAEP", async function() {
const text = this.test!.title;
const encryptResult = await cryptoClient.encrypt("RSA-OAEP", stringToUint8Array(text));
const decryptResult = await cryptoClient.decrypt("RSA-OAEP", encryptResult.result);
const decryptedText = uint8ArrayToString(decryptResult.result);
assert.equal(text, decryptedText);
});

if (isNode) {
it("manually encrypt locally and decrypt remotely, both with RSA-OAEP", async function() {
const text = this.test!.title;
const key = await cryptoClient.getKey();
// Encrypting outside the client since the client will intentionally
const keyPEM = keyto.from(key, "jwk").toString("pem", "public_pkcs1");
const encrypted = crypto.publicEncrypt(keyPEM, Buffer.from(text));
const decryptResult = await cryptoClient.decrypt("RSA-OAEP", encrypted);
const decryptedText = uint8ArrayToString(decryptResult.result);
assert.equal(text, decryptedText);
});
}
}

if (isNode) {
it("sign and verify with RS256", async function() {
const signatureValue = this.test!.title;
const hash = crypto.createHash("sha256");
hash.update(signatureValue);
const digest = hash.digest();
const signature = await cryptoClient.sign("RS256", digest);
const verifyResult = await cryptoClient.verify("RS256", digest, signature.result);
assert.ok(verifyResult);
});
}

if (isRecording) {
it("wrap and unwrap with rsa1_5", async function() {
const text = "arepa";
const wrapped = await cryptoClient.wrapKey("RSA1_5", stringToUint8Array(text));
const unwrappedResult = await cryptoClient.unwrapKey("RSA1_5", wrapped.result);
const unwrappedText = uint8ArrayToString(unwrappedResult.result);
assert.equal(text, unwrappedText);
});

it("wrap and unwrap with RSA-OAEP", async function() {
const text = this.test!.title;
const wrapped = await cryptoClient.wrapKey("RSA-OAEP", stringToUint8Array(text));
const unwrappedResult = await cryptoClient.unwrapKey("RSA-OAEP", wrapped.result);
const unwrappedText = uint8ArrayToString(unwrappedResult.result);
assert.equal(text, unwrappedText);
});
}
});
25 changes: 25 additions & 0 deletions sdk/keyvault/keyvault-keys/tests/utils/crypto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { isNode } from "./recorder";

export function stringToUint8Array(str: string): Uint8Array {
if (isNode) {
return new Uint8Array(Buffer.from(str));
} else {
const bytes = new Uint8Array(str.length);
for (let i = 0; i < str.length; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
}
}

export function uint8ArrayToString(ab: Uint8Array): string {
if (isNode) {
return Buffer.from(ab).toString("utf-8");
} else {
const decoder = new TextDecoder("utf-8");
return decoder.decode(ab);
}
}
4 changes: 2 additions & 2 deletions sdk/keyvault/keyvault-keys/tests/utils/recorder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ if (!isBrowser()) {
}

export const env = isBrowser() ? (window as any).__env__ : process.env;
const isRecording = env.TEST_MODE === "record";
const isPlayingBack = env.TEST_MODE === "playback";
export const isRecording = env.TEST_MODE === "record";
export const isPlayingBack = env.TEST_MODE === "playback";

// IMPORTANT: These are my attempts to make this more generic without changing it significantly
let replaceableVariables: { [key: string]: any } = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ export async function authenticate(that: any): Promise<any> {
const client = new KeysClient(keyVaultUrl, credential);
const testClient = new TestClient(client);

return { recorder, client, testClient, keySuffix };
return { recorder, client, credential, testClient, keySuffix };
}
2 changes: 1 addition & 1 deletion sdk/servicebus/service-bus/review/service-bus.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export interface OnMessage {
// @public
export class QueueClient implements Client {
close(): Promise<void>;
createReceiver(receiveMode: ReceiveMode): Receiver;
createReceiver(receiveMode: ReceiveMode, sessionOptions: SessionReceiverOptions): SessionReceiver;
createReceiver(receiveMode: ReceiveMode): Receiver;
createSender(): Sender;
readonly entityPath: string;
static getDeadLetterQueuePath(queueName: string): string;
Expand Down

0 comments on commit b21c762

Please sign in to comment.