mirror of https://github.com/waku-org/js-waku.git
Improve error feedback when crypto/subtle is not available
This commit is contained in:
parent
556e060335
commit
1ca7215478
|
@ -1,33 +1,48 @@
|
|||
import nodeCrypto from "crypto";
|
||||
|
||||
// IE 11
|
||||
declare global {
|
||||
interface Window {
|
||||
msCrypto?: Crypto;
|
||||
}
|
||||
import { concat } from "uint8arrays/concat";
|
||||
|
||||
interface Crypto {
|
||||
webkitSubtle?: SubtleCrypto;
|
||||
declare const self: Record<string, any> | undefined;
|
||||
const crypto: { node?: any; web?: any } = {
|
||||
node: nodeCrypto,
|
||||
web: typeof self === "object" && "crypto" in self ? self.crypto : undefined,
|
||||
};
|
||||
|
||||
export function getSubtle(): SubtleCrypto {
|
||||
if (crypto.web) {
|
||||
return crypto.web.subtle;
|
||||
} else if (crypto.node) {
|
||||
return crypto.node.webcrypto.subtle;
|
||||
} else {
|
||||
throw new Error(
|
||||
"The environment doesn't have Crypto Subtle API (if in the browser, be sure to use to be in a secure context, ie, https)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const crypto =
|
||||
(typeof window !== "undefined" &&
|
||||
(window as Window) &&
|
||||
(window.crypto || window.msCrypto)) ||
|
||||
(nodeCrypto.webcrypto as unknown as Crypto);
|
||||
const subtle: SubtleCrypto = crypto.subtle || crypto.webkitSubtle;
|
||||
|
||||
if (subtle === undefined) {
|
||||
throw new Error("crypto and/or subtle api unavailable");
|
||||
export function randomBytes(bytesLength = 32): Uint8Array {
|
||||
if (crypto.web) {
|
||||
return crypto.web.getRandomValues(new Uint8Array(bytesLength));
|
||||
} else if (crypto.node) {
|
||||
const { randomBytes } = crypto.node;
|
||||
return Uint8Array.from(randomBytes(bytesLength));
|
||||
} else {
|
||||
throw new Error(
|
||||
"The environment doesn't have randomBytes function (if in the browser, be sure to use to be in a secure context, ie, https)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { crypto, subtle };
|
||||
|
||||
export function randomBytes(size: number): Uint8Array {
|
||||
return crypto.getRandomValues(new Uint8Array(size));
|
||||
}
|
||||
|
||||
export function sha256(msg: ArrayBufferLike): Promise<ArrayBuffer> {
|
||||
return subtle.digest({ name: "SHA-256" }, msg);
|
||||
export async function sha256(...messages: Uint8Array[]): Promise<Uint8Array> {
|
||||
if (crypto.web) {
|
||||
const buffer = await crypto.web.subtle.digest("SHA-256", concat(messages));
|
||||
return new Uint8Array(buffer);
|
||||
} else if (crypto.node) {
|
||||
const { createHash } = crypto.node;
|
||||
const hash = createHash("sha256");
|
||||
messages.forEach((m) => hash.update(m));
|
||||
return Uint8Array.from(hash.digest());
|
||||
} else {
|
||||
throw new Error("The environment doesn't have sha256 function");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as secp from "@noble/secp256k1";
|
||||
import { concat } from "uint8arrays/concat";
|
||||
|
||||
import { randomBytes, sha256, subtle } from "../crypto";
|
||||
import { getSubtle, randomBytes, sha256 } from "../crypto";
|
||||
import { hexToBytes } from "../utils";
|
||||
/**
|
||||
* HKDF as implemented in go-ethereum.
|
||||
|
@ -37,10 +37,10 @@ function aesCtrEncrypt(
|
|||
key: ArrayBufferLike,
|
||||
data: ArrayBufferLike
|
||||
): Promise<Uint8Array> {
|
||||
return subtle
|
||||
return getSubtle()
|
||||
.importKey("raw", key, "AES-CTR", false, ["encrypt"])
|
||||
.then((cryptoKey) =>
|
||||
subtle.encrypt(
|
||||
getSubtle().encrypt(
|
||||
{ name: "AES-CTR", counter: counter, length: 128 },
|
||||
cryptoKey,
|
||||
data
|
||||
|
@ -54,10 +54,10 @@ function aesCtrDecrypt(
|
|||
key: ArrayBufferLike,
|
||||
data: ArrayBufferLike
|
||||
): Promise<Uint8Array> {
|
||||
return subtle
|
||||
return getSubtle()
|
||||
.importKey("raw", key, "AES-CTR", false, ["decrypt"])
|
||||
.then((cryptoKey) =>
|
||||
subtle.decrypt(
|
||||
getSubtle().decrypt(
|
||||
{ name: "AES-CTR", counter: counter, length: 128 },
|
||||
cryptoKey,
|
||||
data
|
||||
|
@ -71,9 +71,9 @@ function hmacSha256Sign(
|
|||
msg: ArrayBufferLike
|
||||
): PromiseLike<Uint8Array> {
|
||||
const algorithm = { name: "HMAC", hash: { name: "SHA-256" } };
|
||||
return subtle
|
||||
return getSubtle()
|
||||
.importKey("raw", key, algorithm, false, ["sign"])
|
||||
.then((cryptoKey) => subtle.sign(algorithm, cryptoKey, msg))
|
||||
.then((cryptoKey) => getSubtle().sign(algorithm, cryptoKey, msg))
|
||||
.then((bytes) => new Uint8Array(bytes));
|
||||
}
|
||||
|
||||
|
@ -83,9 +83,9 @@ function hmacSha256Verify(
|
|||
sig: ArrayBufferLike
|
||||
): Promise<boolean> {
|
||||
const algorithm = { name: "HMAC", hash: { name: "SHA-256" } };
|
||||
const _key = subtle.importKey("raw", key, algorithm, false, ["verify"]);
|
||||
const _key = getSubtle().importKey("raw", key, algorithm, false, ["verify"]);
|
||||
return _key.then((cryptoKey) =>
|
||||
subtle.verify(algorithm, cryptoKey, sig, msg)
|
||||
getSubtle().verify(algorithm, cryptoKey, sig, msg)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { randomBytes, subtle } from "../crypto";
|
||||
import { getSubtle, randomBytes } from "../crypto";
|
||||
|
||||
export const KeySize = 32;
|
||||
export const IvSize = 12;
|
||||
|
@ -11,10 +11,10 @@ export async function encrypt(
|
|||
key: Buffer,
|
||||
clearText: Buffer
|
||||
): Promise<Buffer> {
|
||||
return subtle
|
||||
return getSubtle()
|
||||
.importKey("raw", key, Algorithm, false, ["encrypt"])
|
||||
.then((cryptoKey) =>
|
||||
subtle.encrypt({ iv, ...Algorithm }, cryptoKey, clearText)
|
||||
getSubtle().encrypt({ iv, ...Algorithm }, cryptoKey, clearText)
|
||||
)
|
||||
.then(Buffer.from);
|
||||
}
|
||||
|
@ -24,10 +24,10 @@ export async function decrypt(
|
|||
key: Buffer,
|
||||
cipherText: Buffer
|
||||
): Promise<Buffer> {
|
||||
return subtle
|
||||
return getSubtle()
|
||||
.importKey("raw", key, Algorithm, false, ["decrypt"])
|
||||
.then((cryptoKey) =>
|
||||
subtle.decrypt({ iv, ...Algorithm }, cryptoKey, cipherText)
|
||||
getSubtle().decrypt({ iv, ...Algorithm }, cryptoKey, cipherText)
|
||||
)
|
||||
.then(Buffer.from);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue