diff options
7 files changed, 43 insertions, 105 deletions
diff --git a/packages/server/src/attestation/verifications/tpm/verifyTPM.ts b/packages/server/src/attestation/verifications/tpm/verifyTPM.ts index b859fb5..2f86e1c 100644 --- a/packages/server/src/attestation/verifications/tpm/verifyTPM.ts +++ b/packages/server/src/attestation/verifications/tpm/verifyTPM.ts @@ -8,7 +8,8 @@ import { Name, } from '@peculiar/asn1-x509'; -import type { AttestationStatement } from '../../../helpers/decodeAttestationObject'; +import type { AttestationFormatVerifierOpts } from '../../verifyAttestationResponse'; + import decodeCredentialPublicKey from '../../../helpers/decodeCredentialPublicKey'; import { COSEKEYS, COSEALGHASH } from '../../../helpers/convertCOSEtoPKCS'; import toHash from '../../../helpers/toHash'; @@ -22,15 +23,7 @@ import { TPM_ECC_CURVE, TPM_MANUFACTURERS } from './constants'; import parseCertInfo from './parseCertInfo'; import parsePubArea from './parsePubArea'; -type Options = { - aaguid: Buffer; - attStmt: AttestationStatement; - authData: Buffer; - credentialPublicKey: Buffer; - clientDataHash: Buffer; -}; - -export default async function verifyTPM(options: Options): Promise<boolean> { +export default async function verifyTPM(options: AttestationFormatVerifierOpts): Promise<boolean> { const { aaguid, attStmt, authData, credentialPublicKey, clientDataHash } = options; const { ver, sig, alg, x5c, pubArea, certInfo } = attStmt; diff --git a/packages/server/src/attestation/verifications/verifyAndroidKey.ts b/packages/server/src/attestation/verifications/verifyAndroidKey.ts index f3a47ee..460e97f 100644 --- a/packages/server/src/attestation/verifications/verifyAndroidKey.ts +++ b/packages/server/src/attestation/verifications/verifyAndroidKey.ts @@ -2,22 +2,20 @@ import { AsnParser } from '@peculiar/asn1-schema'; import { Certificate } from '@peculiar/asn1-x509'; import { KeyDescription, id_ce_keyDescription } from '@peculiar/asn1-android'; -import type { AttestationStatement } from '../../helpers/decodeAttestationObject'; +import type { AttestationFormatVerifierOpts } from '../verifyAttestationResponse'; + import convertCertBufferToPEM from '../../helpers/convertCertBufferToPEM'; import verifySignature from '../../helpers/verifySignature'; import convertCOSEtoPKCS, { COSEALGHASH } from '../../helpers/convertCOSEtoPKCS'; import MetadataService from '../../services/metadataService'; import verifyAttestationWithMetadata from '../../metadata/verifyAttestationWithMetadata'; -type Options = { - authData: Buffer; - clientDataHash: Buffer; - attStmt: AttestationStatement; - credentialPublicKey: Buffer; - aaguid: Buffer; -}; - -export default async function verifyAttestationAndroidKey(options: Options): Promise<boolean> { +/** + * Verify an attestation response with fmt 'android-key' + */ +export default async function verifyAttestationAndroidKey( + options: AttestationFormatVerifierOpts, +): Promise<boolean> { const { authData, clientDataHash, attStmt, credentialPublicKey, aaguid } = options; const { x5c, sig, alg } = attStmt; diff --git a/packages/server/src/attestation/verifications/verifyAndroidSafetyNet.ts b/packages/server/src/attestation/verifications/verifyAndroidSafetyNet.ts index 8f9a237..12845a4 100644 --- a/packages/server/src/attestation/verifications/verifyAndroidSafetyNet.ts +++ b/packages/server/src/attestation/verifications/verifyAndroidSafetyNet.ts @@ -1,6 +1,6 @@ import base64url from 'base64url'; -import type { AttestationStatement } from '../../helpers/decodeAttestationObject'; +import type { AttestationFormatVerifierOpts } from '../verifyAttestationResponse'; import toHash from '../../helpers/toHash'; import verifySignature from '../../helpers/verifySignature'; @@ -10,20 +10,11 @@ import convertCertBufferToPEM from '../../helpers/convertCertBufferToPEM'; import MetadataService from '../../services/metadataService'; import verifyAttestationWithMetadata from '../../metadata/verifyAttestationWithMetadata'; -type Options = { - attStmt: AttestationStatement; - clientDataHash: Buffer; - authData: Buffer; - aaguid: Buffer; - rootCertificates: string[]; - verifyTimestampMS?: boolean; -}; - /** * Verify an attestation response with fmt 'android-safetynet' */ export default async function verifyAttestationAndroidSafetyNet( - options: Options, + options: AttestationFormatVerifierOpts, ): Promise<boolean> { const { attStmt, diff --git a/packages/server/src/attestation/verifications/verifyApple.ts b/packages/server/src/attestation/verifications/verifyApple.ts index 7e892d7..69d94af 100644 --- a/packages/server/src/attestation/verifications/verifyApple.ts +++ b/packages/server/src/attestation/verifications/verifyApple.ts @@ -1,21 +1,16 @@ import { AsnParser } from '@peculiar/asn1-schema'; import { Certificate } from '@peculiar/asn1-x509'; -import type { AttestationStatement } from '../../helpers/decodeAttestationObject'; +import type { AttestationFormatVerifierOpts } from '../verifyAttestationResponse'; + import validateCertificatePath from '../../helpers/validateCertificatePath'; import convertCertBufferToPEM from '../../helpers/convertCertBufferToPEM'; import toHash from '../../helpers/toHash'; import convertCOSEtoPKCS from '../../helpers/convertCOSEtoPKCS'; -type Options = { - attStmt: AttestationStatement; - authData: Buffer; - clientDataHash: Buffer; - credentialPublicKey: Buffer; - rootCertificates: string[]; -}; - -export default async function verifyApple(options: Options): Promise<boolean> { +export default async function verifyApple( + options: AttestationFormatVerifierOpts, +): Promise<boolean> { const { attStmt, authData, clientDataHash, credentialPublicKey, rootCertificates } = options; const { x5c } = attStmt; diff --git a/packages/server/src/attestation/verifications/verifyFIDOU2F.ts b/packages/server/src/attestation/verifications/verifyFIDOU2F.ts index 310cb83..bf45472 100644 --- a/packages/server/src/attestation/verifications/verifyFIDOU2F.ts +++ b/packages/server/src/attestation/verifications/verifyFIDOU2F.ts @@ -1,22 +1,13 @@ -import type { AttestationStatement } from '../../helpers/decodeAttestationObject'; +import type { AttestationFormatVerifierOpts } from '../verifyAttestationResponse'; import convertCOSEtoPKCS from '../../helpers/convertCOSEtoPKCS'; import convertCertBufferToPEM from '../../helpers/convertCertBufferToPEM'; import verifySignature from '../../helpers/verifySignature'; -type Options = { - attStmt: AttestationStatement; - clientDataHash: Buffer; - rpIdHash: Buffer; - credentialID: Buffer; - credentialPublicKey: Buffer; - aaguid: Buffer; -}; - /** * Verify an attestation response with fmt 'fido-u2f' */ -export default function verifyAttestationFIDOU2F(options: Options): boolean { +export default function verifyAttestationFIDOU2F(options: AttestationFormatVerifierOpts): boolean { const { attStmt, clientDataHash, diff --git a/packages/server/src/attestation/verifications/verifyPacked.ts b/packages/server/src/attestation/verifications/verifyPacked.ts index 854ef1a..9d4a0c2 100644 --- a/packages/server/src/attestation/verifications/verifyPacked.ts +++ b/packages/server/src/attestation/verifications/verifyPacked.ts @@ -1,7 +1,8 @@ import elliptic from 'elliptic'; import NodeRSA from 'node-rsa'; -import type { AttestationStatement } from '../../helpers/decodeAttestationObject'; +import type { AttestationFormatVerifierOpts } from '../verifyAttestationResponse'; + import convertCOSEtoPKCS, { COSEKEYS, COSEALGHASH, @@ -18,18 +19,12 @@ import decodeCredentialPublicKey from '../../helpers/decodeCredentialPublicKey'; import MetadataService from '../../services/metadataService'; import verifyAttestationWithMetadata from '../../metadata/verifyAttestationWithMetadata'; -type Options = { - attStmt: AttestationStatement; - clientDataHash: Buffer; - authData: Buffer; - credentialPublicKey: Buffer; - aaguid: Buffer; -}; - /** * Verify an attestation response with fmt 'packed' */ -export default async function verifyAttestationPacked(options: Options): Promise<boolean> { +export default async function verifyAttestationPacked( + options: AttestationFormatVerifierOpts, +): Promise<boolean> { const { attStmt, clientDataHash, authData, credentialPublicKey, aaguid } = options; const { sig, x5c, alg } = attStmt; diff --git a/packages/server/src/attestation/verifyAttestationResponse.ts b/packages/server/src/attestation/verifyAttestationResponse.ts index d24b0f4..2b3b4d3 100644 --- a/packages/server/src/attestation/verifyAttestationResponse.ts +++ b/packages/server/src/attestation/verifyAttestationResponse.ts @@ -177,6 +177,18 @@ export default async function verifyAttestationResponse( throw new Error(`Unexpected public key alg "${alg}", expected one of "${supported}"`); } + // Prepare arguments to pass to the relevant verification method + const verifierOpts: AttestationFormatVerifierOpts = { + aaguid, + attStmt, + authData, + clientDataHash, + credentialID, + credentialPublicKey, + rootCertificates, + rpIdHash, + }; + const clientDataHash = toHash(base64url.toBuffer(response.clientDataJSON)); const rootCertificates = settingsService.getRootCertificates({ attestationFormat: fmt }); @@ -185,54 +197,17 @@ export default async function verifyAttestationResponse( */ let verified = false; if (fmt === 'fido-u2f') { - verified = verifyFIDOU2F({ - attStmt, - clientDataHash, - credentialID, - credentialPublicKey, - rpIdHash, - aaguid, - }); + verified = verifyFIDOU2F(verifierOpts); } else if (fmt === 'packed') { - verified = await verifyPacked({ - attStmt, - authData, - clientDataHash, - credentialPublicKey, - aaguid, - }); + verified = await verifyPacked(verifierOpts); } else if (fmt === 'android-safetynet') { - verified = await verifyAndroidSafetynet({ - attStmt, - authData, - clientDataHash, - aaguid, - rootCertificates, - }); + verified = await verifyAndroidSafetynet(verifierOpts); } else if (fmt === 'android-key') { - verified = await verifyAndroidKey({ - attStmt, - authData, - clientDataHash, - credentialPublicKey, - aaguid, - }); + verified = await verifyAndroidKey(verifierOpts); } else if (fmt === 'tpm') { - verified = await verifyTPM({ - aaguid, - attStmt, - authData, - credentialPublicKey, - clientDataHash, - }); + verified = await verifyTPM(verifierOpts); } else if (fmt === 'apple') { - verified = await verifyApple({ - attStmt, - authData, - clientDataHash, - credentialPublicKey, - rootCertificates, - }); + verified = await verifyApple(verifierOpts); } else if (fmt === 'none') { if (Object.keys(attStmt).length > 0) { throw new Error('None attestation had unexpected attestation statement'); |