summaryrefslogtreecommitdiffhomepage
path: root/packages/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/server/src')
-rw-r--r--packages/server/src/attestation/verifications/tpm/verifyTPM.ts11
-rw-r--r--packages/server/src/attestation/verifications/verifyAndroidKey.ts29
-rw-r--r--packages/server/src/attestation/verifications/verifyFIDOU2F.ts13
-rw-r--r--packages/server/src/attestation/verifications/verifyPacked.ts11
-rw-r--r--packages/server/src/attestation/verifyAttestationResponse.ts2
5 files changed, 43 insertions, 23 deletions
diff --git a/packages/server/src/attestation/verifications/tpm/verifyTPM.ts b/packages/server/src/attestation/verifications/tpm/verifyTPM.ts
index 2f86e1c..e2fb772 100644
--- a/packages/server/src/attestation/verifications/tpm/verifyTPM.ts
+++ b/packages/server/src/attestation/verifications/tpm/verifyTPM.ts
@@ -14,6 +14,7 @@ import decodeCredentialPublicKey from '../../../helpers/decodeCredentialPublicKe
import { COSEKEYS, COSEALGHASH } from '../../../helpers/convertCOSEtoPKCS';
import toHash from '../../../helpers/toHash';
import convertCertBufferToPEM from '../../../helpers/convertCertBufferToPEM';
+import validateCertificatePath from '../../../helpers/validateCertificatePath';
import getCertificateInfo from '../../../helpers/getCertificateInfo';
import verifySignature from '../../../helpers/verifySignature';
import MetadataService from '../../../services/metadataService';
@@ -24,7 +25,8 @@ import parseCertInfo from './parseCertInfo';
import parsePubArea from './parsePubArea';
export default async function verifyTPM(options: AttestationFormatVerifierOpts): Promise<boolean> {
- const { aaguid, attStmt, authData, credentialPublicKey, clientDataHash } = options;
+ const { aaguid, attStmt, authData, credentialPublicKey, clientDataHash, rootCertificates } =
+ options;
const { ver, sig, alg, x5c, pubArea, certInfo } = attStmt;
/**
@@ -263,6 +265,13 @@ export default async function verifyTPM(options: AttestationFormatVerifierOpts):
} catch (err) {
throw new Error(`${err.message} (TPM)`);
}
+ } else {
+ try {
+ // Try validating the certificate path using the root certificates set via SettingsService
+ await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
+ } catch (err) {
+ throw new Error(`${err.message} (TPM)`);
+ }
}
// Verify signature over certInfo with the public key extracted from AIK certificate.
diff --git a/packages/server/src/attestation/verifications/verifyAndroidKey.ts b/packages/server/src/attestation/verifications/verifyAndroidKey.ts
index 460e97f..29d184e 100644
--- a/packages/server/src/attestation/verifications/verifyAndroidKey.ts
+++ b/packages/server/src/attestation/verifications/verifyAndroidKey.ts
@@ -5,6 +5,7 @@ import { KeyDescription, id_ce_keyDescription } from '@peculiar/asn1-android';
import type { AttestationFormatVerifierOpts } from '../verifyAttestationResponse';
import convertCertBufferToPEM from '../../helpers/convertCertBufferToPEM';
+import validateCertificatePath from '../../helpers/validateCertificatePath';
import verifySignature from '../../helpers/verifySignature';
import convertCOSEtoPKCS, { COSEALGHASH } from '../../helpers/convertCOSEtoPKCS';
import MetadataService from '../../services/metadataService';
@@ -16,7 +17,8 @@ import verifyAttestationWithMetadata from '../../metadata/verifyAttestationWithM
export default async function verifyAttestationAndroidKey(
options: AttestationFormatVerifierOpts,
): Promise<boolean> {
- const { authData, clientDataHash, attStmt, credentialPublicKey, aaguid } = options;
+ const { authData, clientDataHash, attStmt, credentialPublicKey, aaguid, rootCertificates } =
+ options;
const { x5c, sig, alg } = attStmt;
if (!x5c) {
@@ -73,14 +75,6 @@ export default async function verifyAttestationAndroidKey(
throw new Error('teeEnforced contained "allApplications [600]" tag (AndroidKey)');
}
- // TODO: Confirm that the root certificate is an expected certificate
- // const rootCertPEM = convertBufferToPEM(x5c[x5c.length - 1]);
- // console.log(rootCertPEM);
-
- // if (rootCertPEM !== expectedRootCert) {
- // throw new Error('Root certificate was not expected certificate (AndroidKey)');
- // }
-
const statement = await MetadataService.getStatement(aaguid);
if (statement) {
try {
@@ -88,6 +82,13 @@ export default async function verifyAttestationAndroidKey(
} catch (err) {
throw new Error(`${err.message} (AndroidKey)`);
}
+ } else {
+ try {
+ // Try validating the certificate path using the root certificates set via SettingsService
+ await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
+ } catch (err) {
+ throw new Error(`${err.message} (AndroidKey)`);
+ }
}
const signatureBase = Buffer.concat([authData, clientDataHash]);
@@ -96,13 +97,3 @@ export default async function verifyAttestationAndroidKey(
return verifySignature(sig, signatureBase, leafCertPEM, hashAlg);
}
-
-type KeyStoreExtensionDescription = {
- attestationVersion: number;
- attestationChallenge: Buffer;
- softwareEnforced: string[];
- teeEnforced: string[];
-};
-
-// TODO: Find the most up-to-date expected root cert, the one from Yuriy's article doesn't match
-const expectedRootCert = ``;
diff --git a/packages/server/src/attestation/verifications/verifyFIDOU2F.ts b/packages/server/src/attestation/verifications/verifyFIDOU2F.ts
index bf45472..a2bfd53 100644
--- a/packages/server/src/attestation/verifications/verifyFIDOU2F.ts
+++ b/packages/server/src/attestation/verifications/verifyFIDOU2F.ts
@@ -2,12 +2,15 @@ import type { AttestationFormatVerifierOpts } from '../verifyAttestationResponse
import convertCOSEtoPKCS from '../../helpers/convertCOSEtoPKCS';
import convertCertBufferToPEM from '../../helpers/convertCertBufferToPEM';
+import validateCertificatePath from '../../helpers/validateCertificatePath';
import verifySignature from '../../helpers/verifySignature';
/**
* Verify an attestation response with fmt 'fido-u2f'
*/
-export default function verifyAttestationFIDOU2F(options: AttestationFormatVerifierOpts): boolean {
+export default async function verifyAttestationFIDOU2F(
+ options: AttestationFormatVerifierOpts,
+): Promise<boolean> {
const {
attStmt,
clientDataHash,
@@ -15,6 +18,7 @@ export default function verifyAttestationFIDOU2F(options: AttestationFormatVerif
credentialID,
credentialPublicKey,
aaguid = '',
+ rootCertificates,
} = options;
const reservedByte = Buffer.from([0x00]);
@@ -44,6 +48,13 @@ export default function verifyAttestationFIDOU2F(options: AttestationFormatVerif
throw new Error(`AAGUID "${aaguidToHex}" was not expected value`);
}
+ try {
+ // Try validating the certificate path using the root certificates set via SettingsService
+ await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
+ } catch (err) {
+ throw new Error(`${err.message} (FIDOU2F)`);
+ }
+
const leafCertPEM = convertCertBufferToPEM(x5c[0]);
return verifySignature(sig, signatureBase, leafCertPEM);
diff --git a/packages/server/src/attestation/verifications/verifyPacked.ts b/packages/server/src/attestation/verifications/verifyPacked.ts
index 9d4a0c2..dd876c2 100644
--- a/packages/server/src/attestation/verifications/verifyPacked.ts
+++ b/packages/server/src/attestation/verifications/verifyPacked.ts
@@ -13,6 +13,7 @@ import convertCOSEtoPKCS, {
import { FIDO_METADATA_ATTESTATION_TYPES } from '../../helpers/constants';
import toHash from '../../helpers/toHash';
import convertCertBufferToPEM from '../../helpers/convertCertBufferToPEM';
+import validateCertificatePath from '../../helpers/validateCertificatePath';
import getCertificateInfo from '../../helpers/getCertificateInfo';
import verifySignature from '../../helpers/verifySignature';
import decodeCredentialPublicKey from '../../helpers/decodeCredentialPublicKey';
@@ -25,7 +26,8 @@ import verifyAttestationWithMetadata from '../../metadata/verifyAttestationWithM
export default async function verifyAttestationPacked(
options: AttestationFormatVerifierOpts,
): Promise<boolean> {
- const { attStmt, clientDataHash, authData, credentialPublicKey, aaguid } = options;
+ const { attStmt, clientDataHash, authData, credentialPublicKey, aaguid, rootCertificates } =
+ options;
const { sig, x5c, alg } = attStmt;
@@ -104,6 +106,13 @@ export default async function verifyAttestationPacked(
} catch (err) {
throw new Error(`${err.message} (Packed|Full)`);
}
+ } else {
+ try {
+ // Try validating the certificate path using the root certificates set via SettingsService
+ await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
+ } catch (err) {
+ throw new Error(`${err.message} (Packed|Full)`);
+ }
}
verified = verifySignature(sig, signatureBase, leafCert);
diff --git a/packages/server/src/attestation/verifyAttestationResponse.ts b/packages/server/src/attestation/verifyAttestationResponse.ts
index ac2bd5a..726acec 100644
--- a/packages/server/src/attestation/verifyAttestationResponse.ts
+++ b/packages/server/src/attestation/verifyAttestationResponse.ts
@@ -197,7 +197,7 @@ export default async function verifyAttestationResponse(
*/
let verified = false;
if (fmt === 'fido-u2f') {
- verified = verifyFIDOU2F(verifierOpts);
+ verified = await verifyFIDOU2F(verifierOpts);
} else if (fmt === 'packed') {
verified = await verifyPacked(verifierOpts);
} else if (fmt === 'android-safetynet') {