diff options
author | Matt Mastracci <matthew@mastracci.com> | 2024-02-10 13:22:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-10 20:22:13 +0000 |
commit | f5e46c9bf2f50d66a953fa133161fc829cecff06 (patch) | |
tree | 8faf2f5831c1c7b11d842cd9908d141082c869a5 /tests/unit_node/crypto/crypto_key_test.ts | |
parent | d2477f780630a812bfd65e3987b70c0d309385bb (diff) |
chore: move cli/tests/ -> tests/ (#22369)
This looks like a massive PR, but it's only a move from cli/tests ->
tests, and updates of relative paths for files.
This is the first step towards aggregate all of the integration test
files under tests/, which will lead to a set of integration tests that
can run without the CLI binary being built.
While we could leave these tests under `cli`, it would require us to
keep a more complex directory structure for the various test runners. In
addition, we have a lot of complexity to ignore various test files in
the `cli` project itself (cargo publish exclusion rules, autotests =
false, etc).
And finally, the `tests/` folder will eventually house the `test_ffi`,
`test_napi` and other testing code, reducing the size of the root repo
directory.
For easier review, the extremely large and noisy "move" is in the first
commit (with no changes -- just a move), while the remainder of the
changes to actual files is in the second commit.
Diffstat (limited to 'tests/unit_node/crypto/crypto_key_test.ts')
-rw-r--r-- | tests/unit_node/crypto/crypto_key_test.ts | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/tests/unit_node/crypto/crypto_key_test.ts b/tests/unit_node/crypto/crypto_key_test.ts new file mode 100644 index 000000000..8d1b24b21 --- /dev/null +++ b/tests/unit_node/crypto/crypto_key_test.ts @@ -0,0 +1,233 @@ +// deno-lint-ignore-file no-explicit-any + +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +import { + createPrivateKey, + createSecretKey, + generateKeyPair, + generateKeyPairSync, + KeyObject, + randomBytes, +} from "node:crypto"; +import { promisify } from "node:util"; +import { Buffer } from "node:buffer"; +import { assertEquals, assertThrows } from "@test_util/std/assert/mod.ts"; +import { createHmac } from "node:crypto"; + +const RUN_SLOW_TESTS = Deno.env.get("SLOW_TESTS") === "1"; + +const generateKeyPairAsync = promisify( + ( + type: any, + options: any, + callback: ( + err: Error | null, + key: { publicKey: KeyObject; privateKey: KeyObject }, + ) => void, + ) => + generateKeyPair( + type, + options, + (err: Error | null, publicKey: KeyObject, privateKey: KeyObject) => { + callback(err, { publicKey, privateKey }); + }, + ), +); + +Deno.test({ + name: "create secret key", + fn() { + const key = createSecretKey(Buffer.alloc(0)); + assertEquals(key.type, "secret"); + assertEquals(key.asymmetricKeyType, undefined); + assertEquals(key.symmetricKeySize, 0); + }, +}); + +Deno.test({ + name: "export secret key", + fn() { + const material = Buffer.from(randomBytes(32)); + const key = createSecretKey(material); + assertEquals(Buffer.from(key.export()), material); + }, +}); + +Deno.test({ + name: "export jwk secret key", + fn() { + const material = Buffer.from("secret"); + const key = createSecretKey(material); + assertEquals(key.export({ format: "jwk" }), { + kty: "oct", + k: "c2VjcmV0", + }); + }, +}); + +Deno.test({ + name: "createHmac with secret key", + fn() { + const key = createSecretKey(Buffer.from("secret")); + assertEquals( + createHmac("sha256", key).update("hello").digest().toString("hex"), + "88aab3ede8d3adf94d26ab90d3bafd4a2083070c3bcce9c014ee04a443847c0b", + ); + }, +}); + +const modulusLengths = RUN_SLOW_TESTS ? [2048, 3072] : [2048]; + +for (const type of ["rsa", "rsa-pss", "dsa"]) { + for (const modulusLength of modulusLengths) { + Deno.test({ + name: `generate ${type} key ${modulusLength}`, + fn() { + const { publicKey, privateKey } = generateKeyPairSync(type as any, { + modulusLength, + }); + + assertEquals(publicKey.type, "public"); + assertEquals(privateKey.type, "private"); + }, + }); + + Deno.test({ + name: `generate ${type} key async ${modulusLength}`, + async fn() { + const x = await generateKeyPairAsync(type as any, { + modulusLength, + }); + const { publicKey, privateKey } = x; + assertEquals(publicKey.type, "public"); + assertEquals(privateKey.type, "private"); + }, + }); + } +} + +for (const namedCurve of ["P-384", "P-256"]) { + Deno.test({ + name: `generate ec key ${namedCurve}`, + fn() { + const { publicKey, privateKey } = generateKeyPairSync("ec", { + namedCurve, + }); + + assertEquals(publicKey.type, "public"); + assertEquals(privateKey.type, "private"); + }, + }); + + Deno.test({ + name: `generate ec key ${namedCurve} async`, + async fn() { + const { publicKey, privateKey } = await generateKeyPairAsync("ec", { + namedCurve, + }); + + assertEquals(publicKey.type, "public"); + assertEquals(privateKey.type, "private"); + }, + }); + + Deno.test({ + name: `generate ec key ${namedCurve} paramEncoding=explicit fails`, + fn() { + assertThrows(() => { + // @ts-ignore: @types/node is broken? + generateKeyPairSync("ec", { + namedCurve, + paramEncoding: "explicit", + }); + }); + }, + }); +} + +for ( + const groupName of ["modp5", "modp14", "modp15", "modp16", "modp17", "modp18"] +) { + Deno.test({ + name: `generate dh key ${groupName}`, + fn() { + // @ts-ignore: @types/node is broken? + const { publicKey, privateKey } = generateKeyPairSync("dh", { + group: groupName, + }); + + assertEquals(publicKey.type, "public"); + assertEquals(privateKey.type, "private"); + }, + }); + + Deno.test({ + name: `generate dh key ${groupName} async`, + async fn() { + // @ts-ignore: @types/node is broken? + const { publicKey, privateKey } = await generateKeyPairAsync("dh", { + group: groupName, + }); + + assertEquals(publicKey.type, "public"); + assertEquals(privateKey.type, "private"); + }, + }); +} + +const primeLengths = RUN_SLOW_TESTS ? [1024, 2048, 4096] : [1024]; + +for (const primeLength of primeLengths) { + Deno.test({ + name: `generate dh key ${primeLength}`, + fn() { + // @ts-ignore: @types/node is broken? + const { publicKey, privateKey } = generateKeyPairSync("dh", { + primeLength, + generator: 2, + }); + + assertEquals(publicKey.type, "public"); + assertEquals(privateKey.type, "private"); + }, + }); + + Deno.test({ + name: `generate dh key ${primeLength} async`, + async fn() { + // @ts-ignore: @types/node is broken? + const { publicKey, privateKey } = await generateKeyPairAsync("dh", { + primeLength, + generator: 2, + }); + + assertEquals(publicKey.type, "public"); + assertEquals(privateKey.type, "private"); + }, + }); +} + +const rsaPrivateKey = Deno.readTextFileSync( + new URL("../testdata/rsa_private.pem", import.meta.url), +); + +Deno.test("createPrivateKey rsa", function () { + const key = createPrivateKey(rsaPrivateKey); + assertEquals(key.type, "private"); + assertEquals(key.asymmetricKeyType, "rsa"); + assertEquals(key.asymmetricKeyDetails?.modulusLength, 2048); + assertEquals(key.asymmetricKeyDetails?.publicExponent, 65537n); +}); + +// openssl ecparam -name secp256r1 -genkey -noout -out a.pem +// openssl pkcs8 -topk8 -nocrypt -in a.pem -out b.pem +const ecPrivateKey = Deno.readTextFileSync( + new URL("./ec_private_secp256r1.pem", import.meta.url), +); + +Deno.test("createPrivateKey ec", function () { + const key = createPrivateKey(ecPrivateKey); + assertEquals(key.type, "private"); + assertEquals(key.asymmetricKeyType, "ec"); + assertEquals(key.asymmetricKeyDetails?.namedCurve, "p256"); +}); |