131 lines
4.0 KiB
TypeScript
131 lines
4.0 KiB
TypeScript
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import { CRYPTO_RSA_CODES, type CryptoRsaError } from "../errors/errors.js";
|
|
import type { RsaKeyHandle, RsaKeyHandleProvider } from "./handle.types.js";
|
|
import {
|
|
decryptWithHandle,
|
|
registerKeyHandleProvider,
|
|
resolveKeyHandle,
|
|
signWithHandle,
|
|
unregisterKeyHandleProvider,
|
|
} from "./registry.js";
|
|
|
|
function makeStubProvider(name: string): RsaKeyHandleProvider {
|
|
return {
|
|
name,
|
|
async resolve(_handle: RsaKeyHandle) {
|
|
return { n: 1n, e: 3n, bitLength: 1 };
|
|
},
|
|
async sign(_handle, _message, _options) {
|
|
return new Uint8Array([0xab]);
|
|
},
|
|
async decrypt(_handle, _ciphertext, _options) {
|
|
return new Uint8Array([0xcd]);
|
|
},
|
|
};
|
|
}
|
|
|
|
describe("registerKeyHandleProvider + resolveKeyHandle", () => {
|
|
it("registers a provider and resolves a handle", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const provider = makeStubProvider("stub-resolve");
|
|
registerKeyHandleProvider(provider);
|
|
try {
|
|
const handle: RsaKeyHandle = {
|
|
provider: "stub-resolve",
|
|
id: "k1",
|
|
};
|
|
const resolved = await resolveKeyHandle(handle);
|
|
expect(resolved.n).toBe(1n);
|
|
} finally {
|
|
unregisterKeyHandleProvider("stub-resolve");
|
|
}
|
|
});
|
|
|
|
it("idempotent re-registration of the same provider value", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const provider = makeStubProvider("stub-idem");
|
|
registerKeyHandleProvider(provider);
|
|
registerKeyHandleProvider(provider);
|
|
unregisterKeyHandleProvider("stub-idem");
|
|
});
|
|
|
|
it("conflicting registration of a different provider rejects with INVALID_KEY", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const a = makeStubProvider("stub-conflict");
|
|
const b = makeStubProvider("stub-conflict");
|
|
registerKeyHandleProvider(a);
|
|
try {
|
|
try {
|
|
registerKeyHandleProvider(b);
|
|
throw new Error("should have thrown");
|
|
} catch (err) {
|
|
expect((err as CryptoRsaError).code).toBe(
|
|
CRYPTO_RSA_CODES.INVALID_KEY
|
|
);
|
|
}
|
|
} finally {
|
|
unregisterKeyHandleProvider("stub-conflict");
|
|
}
|
|
});
|
|
|
|
it("resolves missing-provider lookup with INVALID_KEY", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const handle: RsaKeyHandle = {
|
|
provider: "nonexistent",
|
|
id: "x",
|
|
};
|
|
try {
|
|
await resolveKeyHandle(handle);
|
|
throw new Error("should have thrown");
|
|
} catch (err) {
|
|
expect((err as CryptoRsaError).code).toBe(
|
|
CRYPTO_RSA_CODES.INVALID_KEY
|
|
);
|
|
}
|
|
});
|
|
|
|
it("signWithHandle delegates to the provider", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const provider = makeStubProvider("stub-sign");
|
|
registerKeyHandleProvider(provider);
|
|
try {
|
|
const handle: RsaKeyHandle = {
|
|
provider: "stub-sign",
|
|
id: "k1",
|
|
};
|
|
const sig = await signWithHandle(handle, new Uint8Array([1, 2]), {
|
|
scheme: "pkcs1v15",
|
|
hash: "SHA-256",
|
|
});
|
|
expect(sig[0]).toBe(0xab);
|
|
} finally {
|
|
unregisterKeyHandleProvider("stub-sign");
|
|
}
|
|
});
|
|
|
|
it("decryptWithHandle delegates to the provider", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const provider = makeStubProvider("stub-decrypt");
|
|
registerKeyHandleProvider(provider);
|
|
try {
|
|
const handle: RsaKeyHandle = {
|
|
provider: "stub-decrypt",
|
|
id: "k1",
|
|
};
|
|
const pt = await decryptWithHandle(handle, new Uint8Array([1, 2]), {
|
|
scheme: "oaep",
|
|
hash: "SHA-256",
|
|
});
|
|
expect(pt[0]).toBe(0xcd);
|
|
} finally {
|
|
unregisterKeyHandleProvider("stub-decrypt");
|
|
}
|
|
});
|
|
});
|