diff --git a/sdk/keyvault/keyvault-keys/package.json b/sdk/keyvault/keyvault-keys/package.json index b926d4b4ed84..1e9c730d6b68 100644 --- a/sdk/keyvault/keyvault-keys/package.json +++ b/sdk/keyvault/keyvault-keys/package.json @@ -36,7 +36,9 @@ ], "browser": { "os": false, - "process": false + "process": false, + "./dist-esm/keyvault-keys/src/localCryptography/algorithms.js": "./dist-esm/keyvault-keys/src/localCryptography/algorithms.browser.js", + "./dist-esm/keyvault-keys/src/localCryptography/hash.js": "./dist-esm/keyvault-keys/src/localCryptography/hash.browser.js" }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", diff --git a/sdk/keyvault/keyvault-keys/rollup.base.config.js b/sdk/keyvault/keyvault-keys/rollup.base.config.js index d5837c4243ed..1992f62d54df 100644 --- a/sdk/keyvault/keyvault-keys/rollup.base.config.js +++ b/sdk/keyvault/keyvault-keys/rollup.base.config.js @@ -125,7 +125,7 @@ export function browserConfig(test = false) { ] }; - baseConfig.external = ["fs-extra", "path", "crypto", "constants"]; + baseConfig.external = ["fs-extra", "path"]; if (test) { baseConfig.input = ["dist-esm/**/*.spec.js"]; baseConfig.plugins.unshift(multiEntry({ exports: false })); diff --git a/sdk/keyvault/keyvault-keys/src/cryptographyClient.ts b/sdk/keyvault/keyvault-keys/src/cryptographyClient.ts index e9af78404ac8..4a1309dca388 100644 --- a/sdk/keyvault/keyvault-keys/src/cryptographyClient.ts +++ b/sdk/keyvault/keyvault-keys/src/cryptographyClient.ts @@ -18,12 +18,7 @@ import { SDK_VERSION } from "./generated/utils/constants"; import { KeyVaultClient } from "./generated/keyVaultClient"; import { challengeBasedAuthenticationPolicy } from "../../keyvault-common/src"; -import { - LocalSupportedAlgorithmName, - localSupportedAlgorithms, - LocalCryptographyOperationFunction, - isLocallySupported -} from "./localCryptography/algorithms"; +import { localSupportedAlgorithms, isLocallySupported } from "./localCryptography/algorithms"; import { LocalCryptographyClient } from "./localCryptographyClient"; @@ -50,12 +45,16 @@ import { } from "./cryptographyClientModels"; import { KeyBundle } from "./generated/models"; import { parseKeyVaultKeyId } from "./identifier"; +import { + LocalCryptographyOperationFunction, + LocalSupportedAlgorithmName +} from "./localCryptography/models"; /** * Checks whether a key can be used at that specific moment, * by comparing the current date with the bundle's notBefore and expires values. */ -export function checkKeyValidity(keyId?: string, keyBundle?: KeyBundle) { +export function checkKeyValidity(keyId?: string, keyBundle?: KeyBundle): void { const attributes = keyBundle?.attributes || {}; const { notBefore, expires } = attributes; const now = new Date(); diff --git a/sdk/keyvault/keyvault-keys/src/index.ts b/sdk/keyvault/keyvault-keys/src/index.ts index 059ca8d16da4..8ad4d846d194 100644 --- a/sdk/keyvault/keyvault-keys/src/index.ts +++ b/sdk/keyvault/keyvault-keys/src/index.ts @@ -100,9 +100,9 @@ import { WrapResult, EncryptResult } from "./cryptographyClientModels"; -import { LocalSupportedAlgorithmName } from "./localCryptography/algorithms"; import { parseKeyVaultKeyId, KeyVaultKeyId } from "./identifier"; +import { LocalSupportedAlgorithmName } from "./localCryptography/models"; export { CryptographyClientOptions, diff --git a/sdk/keyvault/keyvault-keys/src/localCryptography/algorithms.browser.ts b/sdk/keyvault/keyvault-keys/src/localCryptography/algorithms.browser.ts new file mode 100644 index 000000000000..d37ba5feed10 --- /dev/null +++ b/sdk/keyvault/keyvault-keys/src/localCryptography/algorithms.browser.ts @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { LocalAssertion, LocalSupportedAlgorithmsRecord } from "./models"; + +/** + * This file contains the implementation of local supported algorithms for the browser. + * + * We currently don't support any cryptography operation in the browser. + * + */ + +/** + * @internal + * @ignore + * The list of known assertions so far. + * Assertions verify that the requirements to execute a local cryptography operation are met. + */ +export const assertions: Record = {}; + +/** + * A plain object containing all of the locally supported algorithms. + */ +export const localSupportedAlgorithms: LocalSupportedAlgorithmsRecord = { + RSA1_5: undefined, + "RSA-OAEP": undefined, + PS256: undefined, + RS256: undefined, + PS384: undefined, + RS384: undefined, + PS512: undefined, + RS512: undefined +}; + +/** + * Checks whether a given algorithm name is supported or not. + * @param algorithm string name of the algorithm + */ +export function isLocallySupported(_algorithm: string): boolean { + return false; +} diff --git a/sdk/keyvault/keyvault-keys/src/localCryptography/algorithms.ts b/sdk/keyvault/keyvault-keys/src/localCryptography/algorithms.ts index be8d1656887d..82b90fbfb25b 100644 --- a/sdk/keyvault/keyvault-keys/src/localCryptography/algorithms.ts +++ b/sdk/keyvault/keyvault-keys/src/localCryptography/algorithms.ts @@ -5,7 +5,14 @@ import { publicEncrypt, createVerify } from "crypto"; import * as constants from "constants"; import { isNode } from "@azure/core-http"; import { JsonWebKey, KeyOperation } from "../keysModels"; -import { LocalCryptographyUnsupportedError } from "./models"; +import { + LocalAssertion, + LocalCryptographyOperationName, + LocalCryptographyUnsupportedError, + LocalSupportedAlgorithm, + LocalSupportedAlgorithmName, + LocalSupportedAlgorithmsRecord +} from "./models"; import { createHash } from "./hash"; /** @@ -23,19 +30,6 @@ import { createHash } from "./hash"; * we will be able to increase the support of our existing algorithms. */ -/** - * @internal - * @ignore - * Abstract representation of a assertion. - * Assertions verify that the requirements to execute a local cryptography operation are met. - * @param key The JSON Web Key that will be used during the local operation. - * @param operationName The name of the operation, as in "encrypt", "decrypt", "sign", etc. - */ -export type LocalAssertion = ( - key?: JsonWebKey, - operationName?: LocalCryptographyOperationName -) => void; - /** * @internal * @ignore @@ -80,77 +74,6 @@ const pipeAssertions = (...assertions: LocalAssertion[]): LocalAssertion => (... } }; -/** - * TypeScript fancy for making plain objects require at least one key-value pair of another set of key-values. - */ -export type RequireAtLeastOne = { - [K in keyof T]-?: Required> & Partial>>; -}[keyof T]; - -/** - * Union type representing the names of the supported local cryptography operations. - */ -export type LocalCryptographyOperationName = "encrypt" | "wrapKey" | "createHash" | "verify"; - -/** - * Abstract representation of a Local Cryptography Operation function. - * @param keyPEM The string representation of a PEM key. - * @param data The data used on the cryptography operation, in Buffer type. - */ -export type LocalCryptographyOperationFunction = (keyPEM: string, data: Buffer) => Promise; - -/** - * Abstract representation of a Local Cryptography Operation function, this time with an additional signature buffer. - * @param keyPEM The string representation of a PEM key. - * @param data The data used on the cryptography operation, in Buffer type. - * @param signature The signature used on the cryptography operation, in Buffer type. - */ -export type LocalCryptographyOperationFunctionWithSignature = ( - keyPEM: string, - data: Buffer, - signature: Buffer -) => Promise; - -/** - * Key-value map of local cryptography operations. - */ -export type LocalCryptographyOperations = Record< - LocalCryptographyOperationName, - LocalCryptographyOperationFunction | LocalCryptographyOperationFunctionWithSignature ->; - -/** - * Abstract representation of a locally supported cryptography algorithm, with its assertions, - * and its operations. - */ -export interface LocalSupportedAlgorithm { - /** - * List of assertions that need to pass in order to execute this cryptography operation. - */ - validate: LocalAssertion; - /** - * Optional algorithm used to sign or validate data. - */ - signAlgorithm?: string; - /** - * List of local cryptography operations supported by an algorithm. - */ - operations: RequireAtLeastOne; -} - -/** - * A union type representing the names of all of the locally supported algorithms. - */ -export type LocalSupportedAlgorithmName = - | "RSA1_5" - | "RSA-OAEP" - | "PS256" - | "RS256" - | "PS384" - | "RS384" - | "PS512" - | "RS512"; - /** * Local support of the RSA1_5 algorithm. * We currently only support encrypting and wrapping keys with it. @@ -212,14 +135,6 @@ const makeSigner = (signAlgorithm: SignAlgorithmName): LocalSupportedAlgorithm = }; }; -/** - * A Record containing all of the locally supported algorithms. - */ -export type LocalSupportedAlgorithmsRecord = Record< - LocalSupportedAlgorithmName, - LocalSupportedAlgorithm ->; - /** * A plain object containing all of the locally supported algorithms. */ diff --git a/sdk/keyvault/keyvault-keys/src/localCryptography/hash.browser.ts b/sdk/keyvault/keyvault-keys/src/localCryptography/hash.browser.ts new file mode 100644 index 000000000000..01fa15817354 --- /dev/null +++ b/sdk/keyvault/keyvault-keys/src/localCryptography/hash.browser.ts @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { LocalCryptographyUnsupportedError } from "./models"; + +/** + * @internal + * @ignore + * Use the platform-local hashing functionality + */ +export async function createHash(_algorithm: string, _data: Uint8Array): Promise { + throw new LocalCryptographyUnsupportedError( + "Our libraries don't currently support browser hashing" + ); +} diff --git a/sdk/keyvault/keyvault-keys/src/localCryptography/hash.ts b/sdk/keyvault/keyvault-keys/src/localCryptography/hash.ts index 393eba0a3210..e3d2bf64640e 100644 --- a/sdk/keyvault/keyvault-keys/src/localCryptography/hash.ts +++ b/sdk/keyvault/keyvault-keys/src/localCryptography/hash.ts @@ -2,8 +2,6 @@ // Licensed under the MIT license. import { createHash as cryptoCreateHash } from "crypto"; -import { isNode } from "@azure/core-http"; -import { LocalCryptographyUnsupportedError } from "./models"; /** * @internal @@ -11,14 +9,8 @@ import { LocalCryptographyUnsupportedError } from "./models"; * Use the platform-local hashing functionality */ export async function createHash(algorithm: string, data: Uint8Array): Promise { - if (isNode) { - const hash = cryptoCreateHash(algorithm); - hash.update(Buffer.from(data)); - const digest = hash.digest(); - return digest; - } else { - throw new LocalCryptographyUnsupportedError( - "Our libraries don't currently support browser hashing" - ); - } + const hash = cryptoCreateHash(algorithm); + hash.update(Buffer.from(data)); + const digest = hash.digest(); + return digest; } diff --git a/sdk/keyvault/keyvault-keys/src/localCryptography/models.ts b/sdk/keyvault/keyvault-keys/src/localCryptography/models.ts index 5608837bad92..335daece6983 100644 --- a/sdk/keyvault/keyvault-keys/src/localCryptography/models.ts +++ b/sdk/keyvault/keyvault-keys/src/localCryptography/models.ts @@ -1,4 +1,98 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { JsonWebKey } from "../keysModels"; + +/** + * TypeScript fancy for making plain objects require at least one key-value pair of another set of key-values. + */ +export type RequireAtLeastOne = { + [K in keyof T]-?: Required> & Partial>>; +}[keyof T]; + +/** + * Union type representing the names of the supported local cryptography operations. + */ +export type LocalCryptographyOperationName = "encrypt" | "wrapKey" | "createHash" | "verify"; + +/** + * @internal + * @ignore + * Abstract representation of a assertion. + * Assertions verify that the requirements to execute a local cryptography operation are met. + * @param key The JSON Web Key that will be used during the local operation. + * @param operationName The name of the operation, as in "encrypt", "decrypt", "sign", etc. + */ +export type LocalAssertion = ( + key?: JsonWebKey, + operationName?: LocalCryptographyOperationName +) => void; + +/** + * A union type representing the names of all of the locally supported algorithms. + */ +export type LocalSupportedAlgorithmName = + | "RSA1_5" + | "RSA-OAEP" + | "PS256" + | "RS256" + | "PS384" + | "RS384" + | "PS512" + | "RS512"; + +/** + * Abstract representation of a Local Cryptography Operation function. + * @param keyPEM The string representation of a PEM key. + * @param data The data used on the cryptography operation, in Buffer type. + */ +export type LocalCryptographyOperationFunction = (keyPEM: string, data: Buffer) => Promise; + +/** + * Abstract representation of a Local Cryptography Operation function, this time with an additional signature buffer. + * @param keyPEM The string representation of a PEM key. + * @param data The data used on the cryptography operation, in Buffer type. + * @param signature The signature used on the cryptography operation, in Buffer type. + */ +export type LocalCryptographyOperationFunctionWithSignature = ( + keyPEM: string, + data: Buffer, + signature: Buffer +) => Promise; + +/** + * Key-value map of local cryptography operations. + */ +export type LocalCryptographyOperations = Record< + LocalCryptographyOperationName, + LocalCryptographyOperationFunction | LocalCryptographyOperationFunctionWithSignature +>; + +/** + * Abstract representation of a locally supported cryptography algorithm, with its assertions, + * and its operations. + */ +export interface LocalSupportedAlgorithm { + /** + * List of assertions that need to pass in order to execute this cryptography operation. + */ + validate: LocalAssertion; + /** + * Optional algorithm used to sign or validate data. + */ + signAlgorithm?: string; + /** + * List of local cryptography operations supported by an algorithm. + */ + operations: RequireAtLeastOne; +} + +/** + * A Record containing all of the locally supported algorithms. + */ +export type LocalSupportedAlgorithmsRecord = Record< + LocalSupportedAlgorithmName, + LocalSupportedAlgorithm | undefined +>; + export class LocalCryptographyUnsupportedError extends Error {} diff --git a/sdk/keyvault/keyvault-keys/src/localCryptography/runOperation.ts b/sdk/keyvault/keyvault-keys/src/localCryptography/runOperation.ts index 1765c7ddfcc9..ee218209971a 100644 --- a/sdk/keyvault/keyvault-keys/src/localCryptography/runOperation.ts +++ b/sdk/keyvault/keyvault-keys/src/localCryptography/runOperation.ts @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { LocalCryptographyUnsupportedError } from "./models"; import { - localSupportedAlgorithms, + LocalCryptographyOperationName, + LocalCryptographyUnsupportedError, LocalSupportedAlgorithm, - LocalSupportedAlgorithmName, - LocalCryptographyOperationName -} from "./algorithms"; + LocalSupportedAlgorithmName +} from "./models"; +import { localSupportedAlgorithms } from "./algorithms"; import { JsonWebKey } from "../keysModels"; import { convertJWKtoPEM } from "./conversions"; @@ -18,7 +18,7 @@ export async function runOperation( data: Buffer, signature?: Buffer ): Promise { - const algorithm: LocalSupportedAlgorithm = localSupportedAlgorithms[algorithmName]; + const algorithm: LocalSupportedAlgorithm | undefined = localSupportedAlgorithms[algorithmName]; if (!algorithm) { throw new LocalCryptographyUnsupportedError(`Unsupported algorithm ${algorithm}`); } diff --git a/sdk/keyvault/keyvault-keys/src/localCryptographyClient.ts b/sdk/keyvault/keyvault-keys/src/localCryptographyClient.ts index e9ce8e8ab7d7..5bcdf9b25a93 100644 --- a/sdk/keyvault/keyvault-keys/src/localCryptographyClient.ts +++ b/sdk/keyvault/keyvault-keys/src/localCryptographyClient.ts @@ -3,8 +3,10 @@ import { isNode } from "@azure/core-http"; -import { LocalCryptographyUnsupportedError } from "./localCryptography/models"; -import { LocalSupportedAlgorithmName } from "./localCryptography/algorithms"; +import { + LocalCryptographyUnsupportedError, + LocalSupportedAlgorithmName +} from "./localCryptography/models"; import { JsonWebKey } from "./keysModels"; import { diff --git a/sdk/keyvault/keyvault-keys/test/public/localCryptography.spec.ts b/sdk/keyvault/keyvault-keys/test/public/localCryptography.spec.ts index 06ece4590c0d..5ad8b33c83c2 100644 --- a/sdk/keyvault/keyvault-keys/test/public/localCryptography.spec.ts +++ b/sdk/keyvault/keyvault-keys/test/public/localCryptography.spec.ts @@ -2,10 +2,7 @@ // Licensed under the MIT license. import { - localSupportedAlgorithms, - LocalSupportedAlgorithmName -} from "../../src/localCryptography/algorithms"; -import { + LocalSupportedAlgorithmName, KeyClient, CryptographyClient, SignatureAlgorithm, @@ -18,6 +15,7 @@ import { authenticate } from "../utils/testAuthentication"; import TestClient from "../utils/testClient"; import { Recorder, env } from "@azure/test-utils-recorder"; import { ClientSecretCredential } from "@azure/identity"; +import { localSupportedAlgorithms } from "../../src/localCryptography/algorithms"; const { assert } = chai; describe("Local cryptography public tests", () => { @@ -111,8 +109,7 @@ describe("Local cryptography public tests", () => { for (const localAlgorithmName of localSupportedAlgorithmNames) { const algorithm = localSupportedAlgorithms[localAlgorithmName as LocalSupportedAlgorithmName]; - const signAlgorithm = algorithm.signAlgorithm; - + const signAlgorithm = algorithm?.signAlgorithm; if (!signAlgorithm) { continue; }