Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(node): export full node crypto exports #121

Merged
merged 2 commits into from
Aug 2, 2023
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
51 changes: 6 additions & 45 deletions src/runtime/node/crypto/index.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,12 @@
// https://nodejs.org/api/crypto.html
// https://github.com/unjs/uncrypto
import type nodeCrypto from "node:crypto";

const webcrypto = globalThis.crypto;
import * as web from "./web";
import * as node from "./node";

export const subtle: typeof nodeCrypto.subtle = webcrypto.subtle;
export * from "./web";
export * from "./node";

// limit of Crypto.getRandomValues()
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
const MAX_BYTES: number = 65_536;

export const randomUUID: typeof nodeCrypto.randomUUID = () => {
return webcrypto.randomUUID();
};

export const getRandomValues: typeof nodeCrypto.getRandomValues = (
array: any,
) => {
return webcrypto.getRandomValues(array);
};

export const randomBytes /* :typeof nodeCrypto.randomBytes */ = (
size: number,
cb?: (err: Error | null, buf: Buffer) => void,
) => {
const bytes = Buffer.alloc(size, 0, undefined) as Buffer;

for (let generated = 0; generated < size; generated += MAX_BYTES) {
// buffer.slice automatically checks if the end is past the end of
// the buffer so we don't have to here
getRandomValues(
Uint8Array.prototype.slice.call(bytes, generated, generated + MAX_BYTES),
);
}

if (typeof cb === "function") {
cb(null, bytes);
return;
}
return bytes;
};

// TODO: Add missing exports (typecheck is not working!)
export default <typeof nodeCrypto>{
randomUUID,
getRandomValues,
randomBytes,
subtle,
webcrypto,
...web,
...node,
};
265 changes: 265 additions & 0 deletions src/runtime/node/crypto/node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
import type nodeCrypto from "node:crypto";

import { notImplemented, notImplementedClass } from "../../_internal/utils";
import { getRandomValues } from "./web";

// limit of Crypto.getRandomValues()
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
const MAX_RANDOM_VALUE_BYTES: number = 65_536;

// ---- implemented Utils ----

export const randomBytes: typeof nodeCrypto.randomBytes = (
size: number,
cb?: (err: Error | null, buf: Buffer) => void,
) => {
const bytes = Buffer.alloc(size, 0, undefined) as Buffer;

for (
let generated = 0;
generated < size;
generated += MAX_RANDOM_VALUE_BYTES
) {
// buffer.slice automatically checks if the end is past the end of
// the buffer so we don't have to here
getRandomValues(
Uint8Array.prototype.slice.call(
bytes,
generated,
generated + MAX_RANDOM_VALUE_BYTES,
),
);
}

if (typeof cb === "function") {
cb(null, bytes);
return undefined as any /* type override fix */;
}

return bytes;
};

// ---- Contants ----

export const fips: typeof nodeCrypto.fips = false;

export const constants = {} as typeof nodeCrypto.constants;

// ---- Unimplemented utils ----

export const checkPrime: typeof nodeCrypto.checkPrime =
notImplemented("crypto.checkPrime");

export const checkPrimeSync: typeof nodeCrypto.checkPrimeSync = notImplemented(
"crypto.checkPrimeSync",
);

export const createCipher: typeof nodeCrypto.createCipher = notImplemented(
"crypto.createCipher",
);

export const createDecipher: typeof nodeCrypto.createDecipher = notImplemented(
"crypto.createDecipher",
);

export const pseudoRandomBytes: typeof nodeCrypto.pseudoRandomBytes =
notImplemented("crypto.pseudoRandomBytes");

export const createCipheriv: typeof nodeCrypto.createCipheriv = notImplemented(
"crypto.createCipheriv",
);

export const createDecipheriv: typeof nodeCrypto.createDecipheriv =
notImplemented("crypto.createDecipheriv");

export const createDiffieHellman: typeof nodeCrypto.createDiffieHellman =
notImplemented("crypto.createDiffieHellman");

export const createDiffieHellmanGroup: typeof nodeCrypto.createDiffieHellmanGroup =
notImplemented("crypto.createDiffieHellmanGroup");

export const createECDH: typeof nodeCrypto.createECDH =
notImplemented("crypto.createECDH");

export const createHash: typeof nodeCrypto.createHash =
notImplemented("crypto.createHash");

export const createHmac: typeof nodeCrypto.createHmac =
notImplemented("crypto.createHmac");

export const createPrivateKey: typeof nodeCrypto.createPrivateKey =
notImplemented("crypto.createPrivateKey");

export const createPublicKey: typeof nodeCrypto.createPublicKey =
notImplemented("crypto.createPublicKey");

export const createSecretKey: typeof nodeCrypto.createSecretKey =
notImplemented("crypto.createSecretKey");

export const createSign: typeof nodeCrypto.createSign =
notImplemented("crypto.createSign");

export const createVerify: typeof nodeCrypto.createVerify = notImplemented(
"crypto.createVerify",
);

export const diffieHellman: typeof nodeCrypto.diffieHellman = notImplemented(
"crypto.diffieHellman",
);

export const generatePrime: typeof nodeCrypto.generatePrime = notImplemented(
"crypto.generatePrime",
);

export const generatePrimeSync: typeof nodeCrypto.generatePrimeSync =
notImplemented("crypto.generatePrimeSync");

export const getCiphers: typeof nodeCrypto.getCiphers =
notImplemented("crypto.getCiphers");

export const getCipherInfo: typeof nodeCrypto.getCipherInfo = notImplemented(
"crypto.getCipherInfo",
);

export const getCurves: typeof nodeCrypto.getCurves =
notImplemented("crypto.getCurves");

export const getDiffieHellman: typeof nodeCrypto.getDiffieHellman =
notImplemented("crypto.getDiffieHellman");

export const getHashes: typeof nodeCrypto.getHashes =
notImplemented("crypto.getHashes");

export const hkdf: typeof nodeCrypto.hkdf = notImplemented("crypto.hkdf");

export const hkdfSync: typeof nodeCrypto.hkdfSync =
notImplemented("crypto.hkdfSync");

export const pbkdf2: typeof nodeCrypto.pbkdf2 = notImplemented("crypto.pbkdf2");

export const pbkdf2Sync: typeof nodeCrypto.pbkdf2Sync =
notImplemented("crypto.pbkdf2Sync");

// @ts-expect-error promisify not supported
export const generateKeyPair: typeof nodeCrypto.generateKeyPair =
notImplemented("crypto.generateKeyPair");

export const generateKeyPairSync: typeof nodeCrypto.generateKeyPairSync =
notImplemented("crypto.generateKeyPairSync");

export const generateKey: typeof nodeCrypto.generateKey =
notImplemented("crypto.generateKey");

export const generateKeySync: typeof nodeCrypto.generateKeySync =
notImplemented("crypto.generateKeySync");

export const privateDecrypt: typeof nodeCrypto.privateDecrypt = notImplemented(
"crypto.privateDecrypt",
);

export const privateEncrypt: typeof nodeCrypto.privateEncrypt = notImplemented(
"crypto.privateEncrypt",
);

export const publicDecrypt: typeof nodeCrypto.publicDecrypt = notImplemented(
"crypto.publicDecrypt",
);

export const publicEncrypt: typeof nodeCrypto.publicEncrypt = notImplemented(
"crypto.publicEncrypt",
);

export const randomFill: typeof nodeCrypto.randomFill =
notImplemented("crypto.randomFill");

export const randomFillSync: typeof nodeCrypto.randomFillSync = notImplemented(
"crypto.randomFillSync",
);

export const randomInt: typeof nodeCrypto.randomInt =
notImplemented("crypto.randomInt");

export const scrypt: typeof nodeCrypto.scrypt = notImplemented("crypto.scrypt");

export const scryptSync: typeof nodeCrypto.scryptSync =
notImplemented("crypto.scryptSync");

export const sign: typeof nodeCrypto.sign = notImplemented("crypto.sign");

export const setEngine: typeof nodeCrypto.setEngine =
notImplemented("crypto.setEngine");

export const timingSafeEqual: typeof nodeCrypto.timingSafeEqual =
notImplemented("crypto.timingSafeEqual");

export const getFips: typeof nodeCrypto.getFips =
notImplemented("crypto.getFips");

export const setFips: typeof nodeCrypto.setFips =
notImplemented("crypto.setFips");

export const verify: typeof nodeCrypto.verify = notImplemented("crypto.verify");

export const secureHeapUsed: typeof nodeCrypto.secureHeapUsed = notImplemented(
"crypto.secureHeapUsed",
);

// ---- Unimplemented Classes ----

export const Certificate = notImplementedClass(
"crypto.Certificate",
) as unknown as typeof nodeCrypto.Certificate;

export const Cipher = notImplementedClass(
"crypto.Cipher",
) as unknown as typeof nodeCrypto.Cipher;

export const Cipheriv = notImplementedClass(
"crypto.Cipheriv",
// @ts-expect-error not typed yet
) as unknown as typeof nodeCrypto.Cipheriv;

export const Decipher = notImplementedClass(
"crypto.Decipher",
) as unknown as typeof nodeCrypto.Decipher;

export const Decipheriv = notImplementedClass(
"crypto.Decipheriv",
// @ts-expect-error not typed yet
) as unknown as typeof nodeCrypto.Decipheriv;

export const DiffieHellman = notImplementedClass(
"crypto.DiffieHellman",
) as unknown as typeof nodeCrypto.DiffieHellman;

export const DiffieHellmanGroup = notImplementedClass(
"crypto.DiffieHellmanGroup",
) as unknown as typeof nodeCrypto.DiffieHellmanGroup;

export const ECDH = notImplementedClass(
"crypto.ECDH",
) as unknown as typeof nodeCrypto.ECDH;

export const Hash = notImplementedClass(
"crypto.Hash",
) as unknown as typeof nodeCrypto.Hash;

export const Hmac = notImplementedClass(
"crypto.Hmac",
) as unknown as typeof nodeCrypto.Hmac;

export const KeyObject = notImplementedClass(
"crypto.KeyObject",
) as unknown as typeof nodeCrypto.KeyObject;

export const Sign = notImplementedClass(
"crypto.Sign",
) as unknown as typeof nodeCrypto.Sign;

export const Verify = notImplementedClass(
"crypto.Verify",
) as unknown as typeof nodeCrypto.Verify;

export const X509Certificate = notImplementedClass(
"crypto.X509Certificate",
) as unknown as typeof nodeCrypto.X509Certificate;
21 changes: 21 additions & 0 deletions src/runtime/node/crypto/web.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// https://nodejs.org/api/crypto.html
// https://github.com/unjs/uncrypto
import type nodeCrypto from "node:crypto";

export const CryptoKey =
globalThis.CryptoKey as unknown as typeof nodeCrypto.webcrypto.CryptoKey;

export const webcrypto: Crypto & typeof nodeCrypto.webcrypto = {
CryptoKey,
...globalThis.crypto,
};

export const subtle: SubtleCrypto = webcrypto.subtle;

export const randomUUID: Crypto["randomUUID"] = () => {
return webcrypto.randomUUID();
};

export const getRandomValues: Crypto["getRandomValues"] = (array: any) => {
return webcrypto.getRandomValues(array);
};