Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

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