diff --git a/src/typings/crypto.d.ts b/src/typings/crypto.d.ts new file mode 100644 index 0000000000000..378904595fb87 --- /dev/null +++ b/src/typings/crypto.d.ts @@ -0,0 +1,83 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// NOTE that this is a partial copy from lib.dom.d.ts which is NEEDED because these utils are used in the /common/ +// layer which has no dependency on the DOM/browser-context. However, `crypto` is available as global in all browsers and +// in nodejs. Therefore it's OK to spell out its typings here + +declare global { + + /** + * This Web Crypto API interface provides a number of low-level cryptographic functions. It is accessed via the Crypto.subtle properties available in a window context (via Window.crypto). + * Available only in secure contexts. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto) + */ + interface SubtleCrypto { + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/decrypt) */ + // decrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveBits) */ + // deriveBits(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, length?: number | null): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveKey) */ + // deriveKey(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, derivedKeyType: AlgorithmIdentifier | AesDerivedKeyParams | HmacImportParams | HkdfParams | Pbkdf2Params, extractable: boolean, keyUsages: KeyUsage[]): Promise; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/digest) */ + digest(algorithm: { name: string } | string, data: ArrayBufferView | ArrayBuffer): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/encrypt) */ + // encrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/exportKey) */ + // exportKey(format: "jwk", key: CryptoKey): Promise; + // exportKey(format: Exclude, key: CryptoKey): Promise; + // exportKey(format: KeyFormat, key: CryptoKey): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey) */ + // generateKey(algorithm: "Ed25519", extractable: boolean, keyUsages: ReadonlyArray<"sign" | "verify">): Promise; + // generateKey(algorithm: RsaHashedKeyGenParams | EcKeyGenParams, extractable: boolean, keyUsages: ReadonlyArray): Promise; + // generateKey(algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params, extractable: boolean, keyUsages: ReadonlyArray): Promise; + // generateKey(algorithm: AlgorithmIdentifier, extractable: boolean, keyUsages: KeyUsage[]): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/importKey) */ + // importKey(format: "jwk", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: ReadonlyArray): Promise; + // importKey(format: Exclude, keyData: BufferSource, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/sign) */ + // sign(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, data: BufferSource): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/unwrapKey) */ + // unwrapKey(format: KeyFormat, wrappedKey: BufferSource, unwrappingKey: CryptoKey, unwrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, unwrappedKeyAlgorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/verify) */ + // verify(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, signature: BufferSource, data: BufferSource): Promise; + // /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/wrapKey) */ + // wrapKey(format: KeyFormat, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams): Promise; + } + + /** + * Basic cryptography features available in the current context. It allows access to a cryptographically strong random number generator and to cryptographic primitives. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto) + */ + interface Crypto { + /** + * Available only in secure contexts. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/subtle) + */ + readonly subtle: SubtleCrypto; + /** + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) + */ + getRandomValues(array: T): T; + /** + * Available only in secure contexts. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID) + */ + randomUUID(): `${string}-${string}-${string}-${string}-${string}`; + } + + var Crypto: { + prototype: Crypto; + new(): Crypto; + }; + + var crypto: Crypto; + +} +export { } diff --git a/src/vs/base/common/hash.ts b/src/vs/base/common/hash.ts index edaaf2b4f0ee4..78697a888d74e 100644 --- a/src/vs/base/common/hash.ts +++ b/src/vs/base/common/hash.ts @@ -69,12 +69,7 @@ function objectHash(obj: any, initialHashVal: number): number { }, initialHashVal); } -// this is shared global between browsers and nodejs -declare const crypto: { - subtle: { - digest(a: string, b: ArrayBufferView): Promise; - }; -}; + /** Hashes the input as SHA-1, returning a hex-encoded string. */ export const hashAsync = (input: string | ArrayBufferView | VSBuffer) => { diff --git a/src/vs/base/common/uuid.ts b/src/vs/base/common/uuid.ts index 0bd0c937caed7..d1d08064f5afc 100644 --- a/src/vs/base/common/uuid.ts +++ b/src/vs/base/common/uuid.ts @@ -10,72 +10,4 @@ export function isUUID(value: string): boolean { return _UUIDPattern.test(value); } -declare const crypto: undefined | { - //https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#browser_compatibility - getRandomValues?(data: Uint8Array): Uint8Array; - //https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID#browser_compatibility - randomUUID?(): string; -}; - -export const generateUuid = (function (): () => string { - - // use `randomUUID` if possible - if (typeof crypto === 'object' && typeof crypto.randomUUID === 'function') { - return crypto.randomUUID.bind(crypto); - } - - // use `randomValues` if possible - let getRandomValues: (bucket: Uint8Array) => Uint8Array; - if (typeof crypto === 'object' && typeof crypto.getRandomValues === 'function') { - getRandomValues = crypto.getRandomValues.bind(crypto); - - } else { - getRandomValues = function (bucket: Uint8Array): Uint8Array { - for (let i = 0; i < bucket.length; i++) { - bucket[i] = Math.floor(Math.random() * 256); - } - return bucket; - }; - } - - // prep-work - const _data = new Uint8Array(16); - const _hex: string[] = []; - for (let i = 0; i < 256; i++) { - _hex.push(i.toString(16).padStart(2, '0')); - } - - return function generateUuid(): string { - // get data - getRandomValues(_data); - - // set version bits - _data[6] = (_data[6] & 0x0f) | 0x40; - _data[8] = (_data[8] & 0x3f) | 0x80; - - // print as string - let i = 0; - let result = ''; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += '-'; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += '-'; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += '-'; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += '-'; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - result += _hex[_data[i++]]; - return result; - }; -})(); +export const generateUuid: () => string = crypto.randomUUID.bind(crypto);