summaryrefslogtreecommitdiffhomepage
path: root/packages/server/src/helpers/iso/isoCrypto/verifyRSA.ts
diff options
context:
space:
mode:
authorMatthew Miller <matthew@millerti.me>2022-11-19 22:20:58 -0800
committerMatthew Miller <matthew@millerti.me>2022-11-19 22:21:08 -0800
commitd97b72e77b931d90c1755a2ac655ae124bc0945e (patch)
treedd332fc19540cae1d67d1236d37a452d48e2b746 /packages/server/src/helpers/iso/isoCrypto/verifyRSA.ts
parent296f50e9b4b3c6ac7431aa12379953dd013401d1 (diff)
Move complexity of sig ver into isoCrypto.verify()
Diffstat (limited to 'packages/server/src/helpers/iso/isoCrypto/verifyRSA.ts')
-rw-r--r--packages/server/src/helpers/iso/isoCrypto/verifyRSA.ts82
1 files changed, 82 insertions, 0 deletions
diff --git a/packages/server/src/helpers/iso/isoCrypto/verifyRSA.ts b/packages/server/src/helpers/iso/isoCrypto/verifyRSA.ts
new file mode 100644
index 0000000..b479515
--- /dev/null
+++ b/packages/server/src/helpers/iso/isoCrypto/verifyRSA.ts
@@ -0,0 +1,82 @@
+import { webcrypto } from 'node:crypto';
+
+import { COSEALG, COSEKEYS, COSEPublicKeyRSA, isCOSEAlg } from "../../cose";
+import { mapCoseAlgToWebCryptoAlg } from "./mapCoseAlgToWebCryptoAlg";
+import { importKey } from './importKey';
+import { isoBase64URL } from '../index';
+
+/**
+ *
+ */
+export async function verifyRSA(opts: {
+ cosePublicKey: COSEPublicKeyRSA,
+ signature: Uint8Array,
+ data: Uint8Array,
+ shaHashOverride?: COSEALG,
+}): Promise<boolean> {
+ const { cosePublicKey, signature, data, shaHashOverride } = opts;
+
+ const alg = cosePublicKey.get(COSEKEYS.alg);
+ const n = cosePublicKey.get(COSEKEYS.n);
+ const e = cosePublicKey.get(COSEKEYS.e);
+
+ if (!alg) {
+ throw new Error('Public key was missing alg (RSA)');
+ }
+
+ if (!isCOSEAlg(alg)) {
+ throw new Error(`Public key had invalid alg ${alg} (RSA)`);
+ }
+
+ if (!n) {
+ throw new Error('Public key was missing n (RSA)');
+ }
+
+ if (!e) {
+ throw new Error('Public key was missing e (RSA)');
+ }
+
+ const keyData: JsonWebKey = {
+ kty: 'RSA',
+ alg: '',
+ n: isoBase64URL.fromBuffer(n),
+ e: isoBase64URL.fromBuffer(e),
+ ext: false,
+ };
+
+ const keyAlgorithm = {
+ // TODO: Determine this from `alg` so we might support the rarer RSA-PSS
+ name: 'RSASSA-PKCS1-v1_5',
+ // This is actually the digest hash that'll get used by `.verify()`
+ hash: { name: mapCoseAlgToWebCryptoAlg(alg) },
+ };
+
+ if (shaHashOverride) {
+ keyAlgorithm.hash.name = mapCoseAlgToWebCryptoAlg(shaHashOverride);
+ }
+
+ if (keyAlgorithm.hash.name === 'SHA-256') {
+ keyData.alg = 'RS256';
+ } else if (keyAlgorithm.hash.name === 'SHA-384') {
+ keyData.alg = 'RS384';
+ } else if (keyAlgorithm.hash.name === 'SHA-512') {
+ keyData.alg = 'RS512';
+ } else if (keyAlgorithm.hash.name === 'SHA-1') {
+ keyData.alg = 'RS1';
+ }
+
+ const key = await importKey({
+ keyData,
+ algorithm: keyAlgorithm,
+ });
+
+ const verifyAlgorithm = {
+ // TODO: Determine this from `alg` so we might support the rarer RSA-PSS
+ name: 'RSASSA-PKCS1-v1_5',
+ };
+ if (globalThis.crypto) {
+ return globalThis.crypto.subtle.verify(verifyAlgorithm, key, signature, data);
+ } else {
+ return webcrypto.subtle.verify(verifyAlgorithm, key, signature, data);
+ }
+}