From 2f5012878720bcfd3b9db5ad222659dcbff81067 Mon Sep 17 00:00:00 2001 From: mei23 Date: Tue, 5 Mar 2024 00:36:31 +0900 Subject: [PATCH 1/2] Handle Invalid Digest header algorithm Fix #7 --- dist/index.cjs | 13 ++++++++++++- dist/index.mjs | 13 ++++++++++++- dist/pem/pkcs8.d.ts | 2 -- dist/pem/spki.d.ts | 11 ++++++++++- src/digest/digest-rfc3230.test.ts | 8 ++++++++ src/digest/digest-rfc3230.ts | 12 +++++++++++- 6 files changed, 53 insertions(+), 6 deletions(-) diff --git a/dist/index.cjs b/dist/index.cjs index bbe98ad..f3d7608 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -838,7 +838,18 @@ async function verifyRFC3230DigestHeader(request, rawBody, failOnNoDigest = true errorLogger(`Invalid Digest header algorithm: ${match[1]}`); return false; } - const hash = await createBase64Digest(rawBody, algo); + let hash; + try { + hash = await createBase64Digest(rawBody, algo); + } catch (e) { + if (e.name === "NotSupportedError") { + if (errorLogger) + errorLogger(`Invalid Digest header algorithm: ${algo}`); + return false; + } + throw e; + } + ; if (hash !== value) { if (errorLogger) errorLogger(`Digest header hash mismatch`); diff --git a/dist/index.mjs b/dist/index.mjs index 681cefe..5ac147a 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -741,7 +741,18 @@ async function verifyRFC3230DigestHeader(request, rawBody, failOnNoDigest = true errorLogger(`Invalid Digest header algorithm: ${match[1]}`); return false; } - const hash = await createBase64Digest(rawBody, algo); + let hash; + try { + hash = await createBase64Digest(rawBody, algo); + } catch (e) { + if (e.name === "NotSupportedError") { + if (errorLogger) + errorLogger(`Invalid Digest header algorithm: ${algo}`); + return false; + } + throw e; + } + ; if (hash !== value) { if (errorLogger) errorLogger(`Digest header hash mismatch`); diff --git a/dist/pem/pkcs8.d.ts b/dist/pem/pkcs8.d.ts index f018b48..a6fa922 100644 --- a/dist/pem/pkcs8.d.ts +++ b/dist/pem/pkcs8.d.ts @@ -6,8 +6,6 @@ export declare class Pkcs8ParseError extends Error { export type ParsedPkcs8 = ParsedAlgorithmIdentifierBase & { /** * DER - * - * (Somehow crypto.createPublicKey will cause `error:1E08010C:DECODER routines::unsupported`) */ der: ArrayBuffer; attributesRaw: ArrayBuffer | null; diff --git a/dist/pem/spki.d.ts b/dist/pem/spki.d.ts index 90c0464..ac975cd 100644 --- a/dist/pem/spki.d.ts +++ b/dist/pem/spki.d.ts @@ -7,7 +7,7 @@ export declare class SpkiParseError extends Error { * Get algorithm name from OID * https://datatracker.ietf.org/doc/html/rfc3279#section-2.3 * https://datatracker.ietf.org/doc/html/rfc8420#appendix-A - * @param oidStr e.g. '1.2.840.113549.1.1.1' or SpkiParsedAlgorithmIdentifier.algorithm + * @param oidStr e.g. '1.2.840.113549.1.1.1' or ParsedAlgorithmIdentifier.algorithm * @returns e.g. 'RSASSA-PKCS1-v1_5' */ export declare function getPublicKeyAlgorithmNameFromOid(oidStr: string): KeyAlgorithmName; @@ -78,6 +78,15 @@ export declare function parseAlgorithmIdentifier(input: ASN1): ParsedAlgorithmId export declare function parseSpki(input: ASN1.StreamOrBinary): SpkiParsedAlgorithmIdentifier; /** * Parse X.509 SubjectPublicKeyInfo (SPKI) public key + * + * In Node.js, `createPublicKey(publicKey)` does not need any information, + * but `crypto.subtle.importKey` needs to be provided by us for the key type. + * + * So, this function parses the SPKI and parses the type of key stored. + * + * If the key is PKCS#1, the function wraps it in SPKI. In that case, + * it assumes that the algorithm is `RSASSA-PKCS1-v1_5`. + * * @param input SPKI public key PEM or DER * @returns parsed object */ diff --git a/src/digest/digest-rfc3230.test.ts b/src/digest/digest-rfc3230.test.ts index bc2097d..4222b76 100644 --- a/src/digest/digest-rfc3230.test.ts +++ b/src/digest/digest-rfc3230.test.ts @@ -45,6 +45,14 @@ describe('rfc3230', () => { } as any; expect(await verifyRFC3230DigestHeader(request, 'foo')).toBe(true); }); + test('Unrecognized algorithm name', async () => { + const request = { + headers: { + 'digest': `FOO=${await createBase64Digest('foo', 'SHA-256')}`, + }, + } as any; + expect(await verifyRFC3230DigestHeader(request, 'foo')).toBe(false); + }); }); }); diff --git a/src/digest/digest-rfc3230.ts b/src/digest/digest-rfc3230.ts index cbc7f81..4468730 100644 --- a/src/digest/digest-rfc3230.ts +++ b/src/digest/digest-rfc3230.ts @@ -44,7 +44,17 @@ export async function verifyRFC3230DigestHeader( return false; } - const hash = await createBase64Digest(rawBody, algo); + let hash: string; + try { + hash = await createBase64Digest(rawBody, algo); + } catch (e: any) { + if (e.name === 'NotSupportedError') { + if (errorLogger) errorLogger(`Invalid Digest header algorithm: ${algo}`); + return false; + } + throw e; + }; + if (hash !== value) { if (errorLogger) errorLogger(`Digest header hash mismatch`); return false; From b8c851a6277ca7dba07abfd1df300a9451adad7a Mon Sep 17 00:00:00 2001 From: mei23 Date: Tue, 5 Mar 2024 00:38:36 +0900 Subject: [PATCH 2/2] lint --- src/digest/digest-rfc3230.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/digest/digest-rfc3230.ts b/src/digest/digest-rfc3230.ts index 4468730..5a9ddc6 100644 --- a/src/digest/digest-rfc3230.ts +++ b/src/digest/digest-rfc3230.ts @@ -53,7 +53,7 @@ export async function verifyRFC3230DigestHeader( return false; } throw e; - }; + } if (hash !== value) { if (errorLogger) errorLogger(`Digest header hash mismatch`);