@simplewebauthn/server 13.1.2 → 13.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/authentication/generateAuthenticationOptions.d.ts +2 -2
- package/esm/authentication/generateAuthenticationOptions.d.ts.map +1 -1
- package/esm/helpers/convertAAGUIDToString.d.ts +2 -1
- package/esm/helpers/convertAAGUIDToString.d.ts.map +1 -1
- package/esm/helpers/convertCOSEtoPKCS.d.ts +2 -1
- package/esm/helpers/convertCOSEtoPKCS.d.ts.map +1 -1
- package/esm/helpers/convertCertBufferToPEM.d.ts +2 -2
- package/esm/helpers/convertCertBufferToPEM.d.ts.map +1 -1
- package/esm/helpers/convertPEMToBytes.d.ts +2 -1
- package/esm/helpers/convertPEMToBytes.d.ts.map +1 -1
- package/esm/helpers/convertX509PublicKeyToCOSE.d.ts +2 -1
- package/esm/helpers/convertX509PublicKeyToCOSE.d.ts.map +1 -1
- package/esm/helpers/convertX509PublicKeyToCOSE.js +2 -2
- package/esm/helpers/cose.d.ts +11 -10
- package/esm/helpers/cose.d.ts.map +1 -1
- package/esm/helpers/cose.js +0 -11
- package/esm/helpers/decodeAttestationObject.d.ts +8 -7
- package/esm/helpers/decodeAttestationObject.d.ts.map +1 -1
- package/esm/helpers/decodeAuthenticatorExtensions.d.ts +2 -1
- package/esm/helpers/decodeAuthenticatorExtensions.d.ts.map +1 -1
- package/esm/helpers/decodeCredentialPublicKey.d.ts +3 -2
- package/esm/helpers/decodeCredentialPublicKey.d.ts.map +1 -1
- package/esm/helpers/generateChallenge.d.ts +3 -2
- package/esm/helpers/generateChallenge.d.ts.map +1 -1
- package/esm/helpers/generateUserID.d.ts +3 -2
- package/esm/helpers/generateUserID.d.ts.map +1 -1
- package/esm/helpers/getCertificateInfo.d.ts +2 -1
- package/esm/helpers/getCertificateInfo.d.ts.map +1 -1
- package/esm/helpers/isCertRevoked.d.ts +2 -2
- package/esm/helpers/isCertRevoked.d.ts.map +1 -1
- package/esm/helpers/isCertRevoked.js +19 -22
- package/esm/helpers/iso/isoBase64URL.d.ts +3 -3
- package/esm/helpers/iso/isoBase64URL.d.ts.map +1 -1
- package/esm/helpers/iso/isoBase64URL.js +6 -1
- package/esm/helpers/iso/isoCBOR.d.ts +3 -2
- package/esm/helpers/iso/isoCBOR.d.ts.map +1 -1
- package/esm/helpers/iso/isoCrypto/digest.d.ts +3 -2
- package/esm/helpers/iso/isoCrypto/digest.d.ts.map +1 -1
- package/esm/helpers/iso/isoCrypto/getRandomValues.d.ts +2 -1
- package/esm/helpers/iso/isoCrypto/getRandomValues.d.ts.map +1 -1
- package/esm/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts +2 -1
- package/esm/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts.map +1 -1
- package/esm/helpers/iso/isoCrypto/verify.d.ts +4 -3
- package/esm/helpers/iso/isoCrypto/verify.d.ts.map +1 -1
- package/esm/helpers/iso/isoCrypto/verifyEC2.d.ts +4 -3
- package/esm/helpers/iso/isoCrypto/verifyEC2.d.ts.map +1 -1
- package/esm/helpers/iso/isoCrypto/verifyOKP.d.ts +4 -3
- package/esm/helpers/iso/isoCrypto/verifyOKP.d.ts.map +1 -1
- package/esm/helpers/iso/isoCrypto/verifyRSA.d.ts +4 -3
- package/esm/helpers/iso/isoCrypto/verifyRSA.d.ts.map +1 -1
- package/esm/helpers/iso/isoUint8Array.d.ts +9 -8
- package/esm/helpers/iso/isoUint8Array.d.ts.map +1 -1
- package/esm/helpers/matchExpectedRPID.d.ts +2 -1
- package/esm/helpers/matchExpectedRPID.d.ts.map +1 -1
- package/esm/helpers/parseAuthenticatorData.d.ts +10 -9
- package/esm/helpers/parseAuthenticatorData.d.ts.map +1 -1
- package/esm/helpers/toHash.d.ts +3 -2
- package/esm/helpers/toHash.d.ts.map +1 -1
- package/esm/helpers/validateCertificatePath.d.ts.map +1 -1
- package/esm/helpers/validateCertificatePath.js +85 -90
- package/esm/helpers/validateExtFIDOGenCEAAGUID.d.ts +3 -2
- package/esm/helpers/validateExtFIDOGenCEAAGUID.d.ts.map +1 -1
- package/esm/helpers/verifySignature.d.ts +5 -4
- package/esm/helpers/verifySignature.d.ts.map +1 -1
- package/esm/metadata/verifyAttestationWithMetadata.d.ts +3 -2
- package/esm/metadata/verifyAttestationWithMetadata.d.ts.map +1 -1
- package/esm/metadata/verifyJWT.d.ts +2 -1
- package/esm/metadata/verifyJWT.d.ts.map +1 -1
- package/esm/registration/generateRegistrationOptions.d.ts +3 -3
- package/esm/registration/generateRegistrationOptions.d.ts.map +1 -1
- package/esm/registration/verifications/tpm/parseCertInfo.d.ts +9 -8
- package/esm/registration/verifications/tpm/parseCertInfo.d.ts.map +1 -1
- package/esm/registration/verifications/tpm/parsePubArea.d.ts +4 -3
- package/esm/registration/verifications/tpm/parsePubArea.d.ts.map +1 -1
- package/esm/registration/verifications/tpm/verifyAttestationTPM.d.ts.map +1 -1
- package/esm/registration/verifications/verifyAttestationAndroidKey.js +2 -2
- package/esm/registration/verifications/verifyAttestationAndroidSafetyNet.d.ts.map +1 -1
- package/esm/registration/verifications/verifyAttestationAndroidSafetyNet.js +2 -2
- package/esm/registration/verifyRegistrationResponse.d.ts +16 -10
- package/esm/registration/verifyRegistrationResponse.d.ts.map +1 -1
- package/esm/registration/verifyRegistrationResponse.js +12 -10
- package/esm/services/defaultRootCerts/mds.d.ts +1 -1
- package/esm/services/defaultRootCerts/mds.d.ts.map +1 -1
- package/esm/services/defaultRootCerts/mds.js +20 -20
- package/esm/services/metadataService.d.ts +2 -1
- package/esm/services/metadataService.d.ts.map +1 -1
- package/esm/services/metadataService.js +1 -1
- package/esm/services/settingsService.d.ts +2 -1
- package/esm/services/settingsService.d.ts.map +1 -1
- package/esm/types/index.d.ts +16 -1
- package/esm/types/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/script/authentication/generateAuthenticationOptions.d.ts +2 -2
- package/script/authentication/generateAuthenticationOptions.d.ts.map +1 -1
- package/script/helpers/convertAAGUIDToString.d.ts +2 -1
- package/script/helpers/convertAAGUIDToString.d.ts.map +1 -1
- package/script/helpers/convertCOSEtoPKCS.d.ts +2 -1
- package/script/helpers/convertCOSEtoPKCS.d.ts.map +1 -1
- package/script/helpers/convertCertBufferToPEM.d.ts +2 -2
- package/script/helpers/convertCertBufferToPEM.d.ts.map +1 -1
- package/script/helpers/convertPEMToBytes.d.ts +2 -1
- package/script/helpers/convertPEMToBytes.d.ts.map +1 -1
- package/script/helpers/convertX509PublicKeyToCOSE.d.ts +2 -1
- package/script/helpers/convertX509PublicKeyToCOSE.d.ts.map +1 -1
- package/script/helpers/convertX509PublicKeyToCOSE.js +2 -2
- package/script/helpers/cose.d.ts +11 -10
- package/script/helpers/cose.d.ts.map +1 -1
- package/script/helpers/cose.js +0 -11
- package/script/helpers/decodeAttestationObject.d.ts +8 -7
- package/script/helpers/decodeAttestationObject.d.ts.map +1 -1
- package/script/helpers/decodeAuthenticatorExtensions.d.ts +2 -1
- package/script/helpers/decodeAuthenticatorExtensions.d.ts.map +1 -1
- package/script/helpers/decodeCredentialPublicKey.d.ts +3 -2
- package/script/helpers/decodeCredentialPublicKey.d.ts.map +1 -1
- package/script/helpers/generateChallenge.d.ts +3 -2
- package/script/helpers/generateChallenge.d.ts.map +1 -1
- package/script/helpers/generateUserID.d.ts +3 -2
- package/script/helpers/generateUserID.d.ts.map +1 -1
- package/script/helpers/getCertificateInfo.d.ts +2 -1
- package/script/helpers/getCertificateInfo.d.ts.map +1 -1
- package/script/helpers/isCertRevoked.d.ts +2 -2
- package/script/helpers/isCertRevoked.d.ts.map +1 -1
- package/script/helpers/isCertRevoked.js +19 -22
- package/script/helpers/iso/isoBase64URL.d.ts +3 -3
- package/script/helpers/iso/isoBase64URL.d.ts.map +1 -1
- package/script/helpers/iso/isoBase64URL.js +6 -1
- package/script/helpers/iso/isoCBOR.d.ts +3 -2
- package/script/helpers/iso/isoCBOR.d.ts.map +1 -1
- package/script/helpers/iso/isoCrypto/digest.d.ts +3 -2
- package/script/helpers/iso/isoCrypto/digest.d.ts.map +1 -1
- package/script/helpers/iso/isoCrypto/getRandomValues.d.ts +2 -1
- package/script/helpers/iso/isoCrypto/getRandomValues.d.ts.map +1 -1
- package/script/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts +2 -1
- package/script/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts.map +1 -1
- package/script/helpers/iso/isoCrypto/verify.d.ts +4 -3
- package/script/helpers/iso/isoCrypto/verify.d.ts.map +1 -1
- package/script/helpers/iso/isoCrypto/verifyEC2.d.ts +4 -3
- package/script/helpers/iso/isoCrypto/verifyEC2.d.ts.map +1 -1
- package/script/helpers/iso/isoCrypto/verifyOKP.d.ts +4 -3
- package/script/helpers/iso/isoCrypto/verifyOKP.d.ts.map +1 -1
- package/script/helpers/iso/isoCrypto/verifyRSA.d.ts +4 -3
- package/script/helpers/iso/isoCrypto/verifyRSA.d.ts.map +1 -1
- package/script/helpers/iso/isoUint8Array.d.ts +9 -8
- package/script/helpers/iso/isoUint8Array.d.ts.map +1 -1
- package/script/helpers/iso/isoUint8Array.js +4 -4
- package/script/helpers/matchExpectedRPID.d.ts +2 -1
- package/script/helpers/matchExpectedRPID.d.ts.map +1 -1
- package/script/helpers/parseAuthenticatorData.d.ts +10 -9
- package/script/helpers/parseAuthenticatorData.d.ts.map +1 -1
- package/script/helpers/toHash.d.ts +3 -2
- package/script/helpers/toHash.d.ts.map +1 -1
- package/script/helpers/validateCertificatePath.d.ts.map +1 -1
- package/script/helpers/validateCertificatePath.js +85 -90
- package/script/helpers/validateExtFIDOGenCEAAGUID.d.ts +3 -2
- package/script/helpers/validateExtFIDOGenCEAAGUID.d.ts.map +1 -1
- package/script/helpers/verifySignature.d.ts +5 -4
- package/script/helpers/verifySignature.d.ts.map +1 -1
- package/script/metadata/verifyAttestationWithMetadata.d.ts +3 -2
- package/script/metadata/verifyAttestationWithMetadata.d.ts.map +1 -1
- package/script/metadata/verifyJWT.d.ts +2 -1
- package/script/metadata/verifyJWT.d.ts.map +1 -1
- package/script/registration/generateRegistrationOptions.d.ts +3 -3
- package/script/registration/generateRegistrationOptions.d.ts.map +1 -1
- package/script/registration/verifications/tpm/parseCertInfo.d.ts +9 -8
- package/script/registration/verifications/tpm/parseCertInfo.d.ts.map +1 -1
- package/script/registration/verifications/tpm/parsePubArea.d.ts +4 -3
- package/script/registration/verifications/tpm/parsePubArea.d.ts.map +1 -1
- package/script/registration/verifications/tpm/verifyAttestationTPM.d.ts.map +1 -1
- package/script/registration/verifications/verifyAttestationAndroidKey.js +2 -2
- package/script/registration/verifications/verifyAttestationAndroidSafetyNet.d.ts.map +1 -1
- package/script/registration/verifications/verifyAttestationAndroidSafetyNet.js +2 -2
- package/script/registration/verifyRegistrationResponse.d.ts +16 -10
- package/script/registration/verifyRegistrationResponse.d.ts.map +1 -1
- package/script/registration/verifyRegistrationResponse.js +12 -10
- package/script/services/defaultRootCerts/mds.d.ts +1 -1
- package/script/services/defaultRootCerts/mds.d.ts.map +1 -1
- package/script/services/defaultRootCerts/mds.js +20 -20
- package/script/services/metadataService.d.ts +2 -1
- package/script/services/metadataService.d.ts.map +1 -1
- package/script/services/metadataService.js +1 -1
- package/script/services/settingsService.d.ts +2 -1
- package/script/services/settingsService.d.ts.map +1 -1
- package/script/types/index.d.ts +16 -1
- package/script/types/index.d.ts.map +1 -1
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validateCertificatePath = validateCertificatePath;
|
|
4
|
-
const
|
|
4
|
+
const x509_1 = require("@peculiar/x509");
|
|
5
5
|
const isCertRevoked_js_1 = require("./isCertRevoked.js");
|
|
6
|
-
const
|
|
7
|
-
const mapX509SignatureAlgToCOSEAlg_js_1 = require("./mapX509SignatureAlgToCOSEAlg.js");
|
|
8
|
-
const getCertificateInfo_js_1 = require("./getCertificateInfo.js");
|
|
9
|
-
const convertPEMToBytes_js_1 = require("./convertPEMToBytes.js");
|
|
6
|
+
const getWebCrypto_js_1 = require("./iso/isoCrypto/getWebCrypto.js");
|
|
10
7
|
/**
|
|
11
8
|
* Traverse an array of PEM certificates and ensure they form a proper chain
|
|
12
9
|
* @param x5cCertsPEM Typically the result of `x5c.map(convertASN1toPEM)`
|
|
@@ -17,27 +14,97 @@ async function validateCertificatePath(x5cCertsPEM, trustAnchorsPEM = []) {
|
|
|
17
14
|
// We have no trust anchors to chain back to, so skip path validation
|
|
18
15
|
return true;
|
|
19
16
|
}
|
|
17
|
+
const WebCrypto = await (0, getWebCrypto_js_1.getWebCrypto)();
|
|
18
|
+
// Prepare to work with x5c certs
|
|
19
|
+
const x5cCertsParsed = x5cCertsPEM.map((certPEM) => new x509_1.X509Certificate(certPEM));
|
|
20
|
+
// Check for any expired or temporally invalid certs in x5c
|
|
21
|
+
for (let i = 0; i < x5cCertsParsed.length; i++) {
|
|
22
|
+
const cert = x5cCertsParsed[i];
|
|
23
|
+
const certPEM = x5cCertsPEM[i];
|
|
24
|
+
try {
|
|
25
|
+
await assertCertNotRevoked(cert);
|
|
26
|
+
}
|
|
27
|
+
catch (_err) {
|
|
28
|
+
throw new Error(`Found revoked certificate in x5c:\n${certPEM}`);
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
assertCertIsWithinValidTimeWindow(cert.notBefore, cert.notAfter);
|
|
32
|
+
}
|
|
33
|
+
catch (_err) {
|
|
34
|
+
throw new Error(`Found certificate out of validity period in x5c:\n${certPEM}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Prepare to work with trust anchor certs
|
|
38
|
+
const trustAnchorsParsed = trustAnchorsPEM.map((certPEM) => {
|
|
39
|
+
try {
|
|
40
|
+
return new x509_1.X509Certificate(certPEM);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
const _err = err;
|
|
44
|
+
throw new Error(`Could not parse trust anchor certificate:\n${certPEM}`, { cause: _err });
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
// Filter out any expired or temporally invalid trust anchors certs
|
|
48
|
+
const validTrustAnchors = [];
|
|
49
|
+
for (let i = 0; i < trustAnchorsParsed.length; i++) {
|
|
50
|
+
const cert = trustAnchorsParsed[i];
|
|
51
|
+
try {
|
|
52
|
+
await assertCertNotRevoked(cert);
|
|
53
|
+
}
|
|
54
|
+
catch (_err) {
|
|
55
|
+
// Continue processing the other certs
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
assertCertIsWithinValidTimeWindow(cert.notBefore, cert.notAfter);
|
|
60
|
+
}
|
|
61
|
+
catch (_err) {
|
|
62
|
+
// Continue processing the other certs
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
validTrustAnchors.push(cert);
|
|
66
|
+
}
|
|
67
|
+
if (validTrustAnchors.length === 0) {
|
|
68
|
+
throw new Error('No specified trust anchor was valid for verifying x5c');
|
|
69
|
+
}
|
|
70
|
+
// Try to verify x5c with each trust anchor
|
|
20
71
|
let invalidSubjectAndIssuerError = false;
|
|
21
|
-
|
|
22
|
-
for (const anchorPEM of trustAnchorsPEM) {
|
|
72
|
+
for (const anchor of trustAnchorsParsed) {
|
|
23
73
|
try {
|
|
24
|
-
const
|
|
25
|
-
|
|
74
|
+
const x5cWithTrustAnchor = x5cCertsParsed.concat([anchor]);
|
|
75
|
+
if (new Set(x5cWithTrustAnchor).size !== x5cWithTrustAnchor.length) {
|
|
76
|
+
throw new Error('Invalid certificate path: found duplicate certificates');
|
|
77
|
+
}
|
|
78
|
+
// Check signatures, and notBefore and notAfter
|
|
79
|
+
for (let i = 0; i < x5cWithTrustAnchor.length - 1; i++) {
|
|
80
|
+
const subject = x5cWithTrustAnchor[i];
|
|
81
|
+
const issuer = x5cWithTrustAnchor[i + 1];
|
|
82
|
+
// Leaf or intermediate cert, make sure the next cert in the chain signed it
|
|
83
|
+
const issuerSignedSubject = await subject.verify({ publicKey: issuer.publicKey, signatureOnly: true }, WebCrypto);
|
|
84
|
+
if (!issuerSignedSubject) {
|
|
85
|
+
throw new InvalidSubjectAndIssuer();
|
|
86
|
+
}
|
|
87
|
+
if (issuer.subject === issuer.issuer) {
|
|
88
|
+
// Root cert detected, make sure it signed itself
|
|
89
|
+
const issuerSignedIssuer = await issuer.verify({ publicKey: issuer.publicKey, signatureOnly: true }, WebCrypto);
|
|
90
|
+
if (!issuerSignedIssuer) {
|
|
91
|
+
throw new InvalidSubjectAndIssuer();
|
|
92
|
+
}
|
|
93
|
+
// Don't process anything else after a root cert
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
26
97
|
// If we successfully validated a path then there's no need to continue. Reset any existing
|
|
27
98
|
// errors that were thrown by earlier trust anchors
|
|
28
99
|
invalidSubjectAndIssuerError = false;
|
|
29
|
-
certificateNotYetValidOrExpiredErrorMessage = undefined;
|
|
30
100
|
break;
|
|
31
101
|
}
|
|
32
102
|
catch (err) {
|
|
33
103
|
if (err instanceof InvalidSubjectAndIssuer) {
|
|
34
104
|
invalidSubjectAndIssuerError = true;
|
|
35
105
|
}
|
|
36
|
-
else if (err instanceof CertificateNotYetValidOrExpired) {
|
|
37
|
-
certificateNotYetValidOrExpiredErrorMessage = err.message;
|
|
38
|
-
}
|
|
39
106
|
else {
|
|
40
|
-
throw err;
|
|
107
|
+
throw new Error('Unexpected error while validating certificate path', { cause: err });
|
|
41
108
|
}
|
|
42
109
|
}
|
|
43
110
|
}
|
|
@@ -45,42 +112,6 @@ async function validateCertificatePath(x5cCertsPEM, trustAnchorsPEM = []) {
|
|
|
45
112
|
if (invalidSubjectAndIssuerError) {
|
|
46
113
|
throw new InvalidSubjectAndIssuer();
|
|
47
114
|
}
|
|
48
|
-
else if (certificateNotYetValidOrExpiredErrorMessage) {
|
|
49
|
-
throw new CertificateNotYetValidOrExpired(certificateNotYetValidOrExpiredErrorMessage);
|
|
50
|
-
}
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* @param x5cCerts X.509 `x5c` certs in PEM string format
|
|
55
|
-
* @param anchorCert X.509 trust anchor cert in PEM string format
|
|
56
|
-
*/
|
|
57
|
-
async function _validatePath(x5cCertsWithTrustAnchorPEM) {
|
|
58
|
-
if (new Set(x5cCertsWithTrustAnchorPEM).size !== x5cCertsWithTrustAnchorPEM.length) {
|
|
59
|
-
throw new Error('Invalid certificate path: found duplicate certificates');
|
|
60
|
-
}
|
|
61
|
-
// Make sure no certs are revoked, and all are within their time validity window
|
|
62
|
-
for (const certificatePEM of x5cCertsWithTrustAnchorPEM) {
|
|
63
|
-
const certInfo = (0, getCertificateInfo_js_1.getCertificateInfo)((0, convertPEMToBytes_js_1.convertPEMToBytes)(certificatePEM));
|
|
64
|
-
await assertCertNotRevoked(certInfo.parsedCertificate);
|
|
65
|
-
assertCertIsWithinValidTimeWindow(certInfo, certificatePEM);
|
|
66
|
-
}
|
|
67
|
-
// Make sure each x5c cert is issued by the next certificate in the chain
|
|
68
|
-
for (let i = 0; i < (x5cCertsWithTrustAnchorPEM.length - 1); i += 1) {
|
|
69
|
-
const subjectPem = x5cCertsWithTrustAnchorPEM[i];
|
|
70
|
-
const issuerPem = x5cCertsWithTrustAnchorPEM[i + 1];
|
|
71
|
-
const subjectInfo = (0, getCertificateInfo_js_1.getCertificateInfo)((0, convertPEMToBytes_js_1.convertPEMToBytes)(subjectPem));
|
|
72
|
-
const issuerInfo = (0, getCertificateInfo_js_1.getCertificateInfo)((0, convertPEMToBytes_js_1.convertPEMToBytes)(issuerPem));
|
|
73
|
-
// Make sure subject issuer is issuer subject
|
|
74
|
-
if (subjectInfo.issuer.combined !== issuerInfo.subject.combined) {
|
|
75
|
-
throw new InvalidSubjectAndIssuer();
|
|
76
|
-
}
|
|
77
|
-
const issuerCertIsRootCert = issuerInfo.issuer.combined === issuerInfo.subject.combined;
|
|
78
|
-
await assertSubjectIsSignedByIssuer(subjectInfo.parsedCertificate, issuerPem);
|
|
79
|
-
// Perform one final check if the issuer cert is also a root certificate
|
|
80
|
-
if (issuerCertIsRootCert) {
|
|
81
|
-
await assertSubjectIsSignedByIssuer(issuerInfo.parsedCertificate, issuerPem);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
115
|
return true;
|
|
85
116
|
}
|
|
86
117
|
/**
|
|
@@ -90,39 +121,16 @@ async function assertCertNotRevoked(certificate) {
|
|
|
90
121
|
// Check for certificate revocation
|
|
91
122
|
const subjectCertRevoked = await (0, isCertRevoked_js_1.isCertRevoked)(certificate);
|
|
92
123
|
if (subjectCertRevoked) {
|
|
93
|
-
throw new Error(
|
|
124
|
+
throw new Error('Found revoked certificate in certificate path');
|
|
94
125
|
}
|
|
95
126
|
}
|
|
96
127
|
/**
|
|
97
128
|
* Require the cert to be within its notBefore and notAfter time window
|
|
98
|
-
*
|
|
99
|
-
* @param certInfo Parsed cert information
|
|
100
|
-
* @param certPEM PEM-formatted certificate, for error reporting
|
|
101
129
|
*/
|
|
102
|
-
function assertCertIsWithinValidTimeWindow(
|
|
103
|
-
const { notBefore, notAfter } = certInfo;
|
|
130
|
+
function assertCertIsWithinValidTimeWindow(certNotBefore, certNotAfter) {
|
|
104
131
|
const now = new Date(Date.now());
|
|
105
|
-
if (
|
|
106
|
-
throw new
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Ensure that the subject cert has been signed by the next cert in the chain
|
|
111
|
-
*/
|
|
112
|
-
async function assertSubjectIsSignedByIssuer(subjectCert, issuerPEM) {
|
|
113
|
-
// Verify the subject certificate's signature with the issuer cert's public key
|
|
114
|
-
const data = asn1_schema_1.AsnSerializer.serialize(subjectCert.tbsCertificate);
|
|
115
|
-
const signature = subjectCert.signatureValue;
|
|
116
|
-
const signatureAlgorithm = (0, mapX509SignatureAlgToCOSEAlg_js_1.mapX509SignatureAlgToCOSEAlg)(subjectCert.signatureAlgorithm.algorithm);
|
|
117
|
-
const issuerCertBytes = (0, convertPEMToBytes_js_1.convertPEMToBytes)(issuerPEM);
|
|
118
|
-
const verified = await (0, verifySignature_js_1.verifySignature)({
|
|
119
|
-
data: new Uint8Array(data),
|
|
120
|
-
signature: new Uint8Array(signature),
|
|
121
|
-
x509Certificate: issuerCertBytes,
|
|
122
|
-
hashAlgorithm: signatureAlgorithm,
|
|
123
|
-
});
|
|
124
|
-
if (!verified) {
|
|
125
|
-
throw new InvalidSubjectSignatureForIssuer();
|
|
132
|
+
if (certNotBefore > now || certNotAfter < now) {
|
|
133
|
+
throw new Error('Certificate is not yet valid or expired');
|
|
126
134
|
}
|
|
127
135
|
}
|
|
128
136
|
// Custom errors to help pass on certain errors
|
|
@@ -133,16 +141,3 @@ class InvalidSubjectAndIssuer extends Error {
|
|
|
133
141
|
this.name = 'InvalidSubjectAndIssuer';
|
|
134
142
|
}
|
|
135
143
|
}
|
|
136
|
-
class InvalidSubjectSignatureForIssuer extends Error {
|
|
137
|
-
constructor() {
|
|
138
|
-
const message = 'Subject signature was invalid for issuer';
|
|
139
|
-
super(message);
|
|
140
|
-
this.name = 'InvalidSubjectSignatureForIssuer';
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
class CertificateNotYetValidOrExpired extends Error {
|
|
144
|
-
constructor(message) {
|
|
145
|
-
super(message);
|
|
146
|
-
this.name = 'CertificateNotYetValidOrExpired';
|
|
147
|
-
}
|
|
148
|
-
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Extensions } from '@peculiar/asn1-x509';
|
|
1
|
+
import type { Extensions } from '@peculiar/asn1-x509';
|
|
2
|
+
import type { Uint8Array_ } from '../types/index.js';
|
|
2
3
|
/**
|
|
3
4
|
* Look for the id-fido-gen-ce-aaguid certificate extension. If it's present then check it against
|
|
4
5
|
* the attestation statement AAGUID.
|
|
5
6
|
*/
|
|
6
|
-
export declare function validateExtFIDOGenCEAAGUID(certExtensions: Extensions | undefined, aaguid:
|
|
7
|
+
export declare function validateExtFIDOGenCEAAGUID(certExtensions: Extensions | undefined, aaguid: Uint8Array_): boolean;
|
|
7
8
|
//# sourceMappingURL=validateExtFIDOGenCEAAGUID.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateExtFIDOGenCEAAGUID.d.ts","sourceRoot":"","sources":["../../src/helpers/validateExtFIDOGenCEAAGUID.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"validateExtFIDOGenCEAAGUID.d.ts","sourceRoot":"","sources":["../../src/helpers/validateExtFIDOGenCEAAGUID.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AASrD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,UAAU,GAAG,SAAS,EACtC,MAAM,EAAE,WAAW,GAClB,OAAO,CA6BT"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { COSEALG } from './cose.js';
|
|
2
|
+
import type { Uint8Array_ } from '../types/index.js';
|
|
2
3
|
/**
|
|
3
4
|
* Verify an authenticator's signature
|
|
4
5
|
*/
|
|
5
6
|
export declare function verifySignature(opts: {
|
|
6
|
-
signature:
|
|
7
|
-
data:
|
|
8
|
-
credentialPublicKey?:
|
|
9
|
-
x509Certificate?:
|
|
7
|
+
signature: Uint8Array_;
|
|
8
|
+
data: Uint8Array_;
|
|
9
|
+
credentialPublicKey?: Uint8Array_;
|
|
10
|
+
x509Certificate?: Uint8Array_;
|
|
10
11
|
hashAlgorithm?: COSEALG;
|
|
11
12
|
}): Promise<boolean>;
|
|
12
13
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifySignature.d.ts","sourceRoot":"","sources":["../../src/helpers/verifySignature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"verifySignature.d.ts","sourceRoot":"","sources":["../../src/helpers/verifySignature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,WAAW,CAAC;AAInD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,SAAS,EAAE,WAAW,CAAC;IACvB,IAAI,EAAE,WAAW,CAAC;IAClB,mBAAmB,CAAC,EAAE,WAAW,CAAC;IAClC,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GAAG,OAAO,CAAC,OAAO,CAAC,CAmCnB;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB;sBAClB,OAAO,CAAC,OAAO,CAAC;CACnC,CAAC"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { Base64URLString } from '../types/index.js';
|
|
2
2
|
import type { AlgSign, MetadataStatement } from './mdsTypes.js';
|
|
3
3
|
import { type COSEALG, type COSECRV, COSEKTY } from '../helpers/cose.js';
|
|
4
|
+
import type { Uint8Array_ } from '../types/index.js';
|
|
4
5
|
/**
|
|
5
6
|
* Match properties of the authenticator's attestation statement against expected values as
|
|
6
7
|
* registered with the FIDO Alliance Metadata Service
|
|
7
8
|
*/
|
|
8
9
|
export declare function verifyAttestationWithMetadata({ statement, credentialPublicKey, x5c, attestationStatementAlg, }: {
|
|
9
10
|
statement: MetadataStatement;
|
|
10
|
-
credentialPublicKey:
|
|
11
|
-
x5c:
|
|
11
|
+
credentialPublicKey: Uint8Array_;
|
|
12
|
+
x5c: Uint8Array_[] | Base64URLString[];
|
|
12
13
|
attestationStatementAlg?: number;
|
|
13
14
|
}): Promise<boolean>;
|
|
14
15
|
type COSEInfo = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyAttestationWithMetadata.d.ts","sourceRoot":"","sources":["../../src/metadata/verifyAttestationWithMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIhE,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,OAAO,EAEZ,OAAO,EAER,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"verifyAttestationWithMetadata.d.ts","sourceRoot":"","sources":["../../src/metadata/verifyAttestationWithMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIhE,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,OAAO,EAEZ,OAAO,EAER,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;GAGG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,SAAS,EACT,mBAAmB,EACnB,GAAG,EACH,uBAAuB,GACxB,EAAE;IACD,SAAS,EAAE,iBAAiB,CAAC;IAC7B,mBAAmB,EAAE,WAAW,CAAC;IACjC,GAAG,EAAE,WAAW,EAAE,GAAG,eAAe,EAAE,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,GAAG,OAAO,CAAC,OAAO,CAAC,CAoJnB;AAED,KAAK,QAAQ,GAAG;IACd,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE;KAAG,GAAG,IAAI,OAAO,GAAG,QAAQ;CAe9D,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Uint8Array_ } from '../types/index.js';
|
|
1
2
|
/**
|
|
2
3
|
* Lightweight verification for FIDO MDS JWTs. Supports use of EC2 and RSA.
|
|
3
4
|
*
|
|
@@ -7,5 +8,5 @@
|
|
|
7
8
|
*
|
|
8
9
|
* (Pulled from https://www.rfc-editor.org/rfc/rfc7515#section-4.1.1)
|
|
9
10
|
*/
|
|
10
|
-
export declare function verifyJWT(jwt: string, leafCert:
|
|
11
|
+
export declare function verifyJWT(jwt: string, leafCert: Uint8Array_): Promise<boolean>;
|
|
11
12
|
//# sourceMappingURL=verifyJWT.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyJWT.d.ts","sourceRoot":"","sources":["../../src/metadata/verifyJWT.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"verifyJWT.d.ts","sourceRoot":"","sources":["../../src/metadata/verifyJWT.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CA0B9E"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuthenticationExtensionsClientInputs, AuthenticatorSelectionCriteria, AuthenticatorTransportFuture, Base64URLString, COSEAlgorithmIdentifier, PublicKeyCredentialCreationOptionsJSON } from '../types/index.js';
|
|
1
|
+
import type { AuthenticationExtensionsClientInputs, AuthenticatorSelectionCriteria, AuthenticatorTransportFuture, Base64URLString, COSEAlgorithmIdentifier, PublicKeyCredentialCreationOptionsJSON, Uint8Array_ } from '../types/index.js';
|
|
2
2
|
export type GenerateRegistrationOptionsOpts = Parameters<typeof generateRegistrationOptions>[0];
|
|
3
3
|
/**
|
|
4
4
|
* Supported crypto algo identifiers
|
|
@@ -29,8 +29,8 @@ export declare function generateRegistrationOptions(options: {
|
|
|
29
29
|
rpName: string;
|
|
30
30
|
rpID: string;
|
|
31
31
|
userName: string;
|
|
32
|
-
userID?:
|
|
33
|
-
challenge?: string |
|
|
32
|
+
userID?: Uint8Array_;
|
|
33
|
+
challenge?: string | Uint8Array_;
|
|
34
34
|
userDisplayName?: string;
|
|
35
35
|
timeout?: number;
|
|
36
36
|
attestationType?: 'direct' | 'enterprise' | 'none';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateRegistrationOptions.d.ts","sourceRoot":"","sources":["../../src/registration/generateRegistrationOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oCAAoC,EACpC,8BAA8B,EAC9B,4BAA4B,EAC5B,eAAe,EACf,uBAAuB,EACvB,sCAAsC,
|
|
1
|
+
{"version":3,"file":"generateRegistrationOptions.d.ts","sourceRoot":"","sources":["../../src/registration/generateRegistrationOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oCAAoC,EACpC,8BAA8B,EAC9B,4BAA4B,EAC5B,eAAe,EACf,uBAAuB,EACvB,sCAAsC,EAGtC,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAK3B,MAAM,MAAM,+BAA+B,GAAG,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhG;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,EAAE,uBAAuB,EAqBtE,CAAC;AAsBF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE;IACP,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,MAAM,CAAC;IACnD,kBAAkB,CAAC,EAAE;QACnB,EAAE,EAAE,eAAe,CAAC;QACpB,UAAU,CAAC,EAAE,4BAA4B,EAAE,CAAC;KAC7C,EAAE,CAAC;IACJ,sBAAsB,CAAC,EAAE,8BAA8B,CAAC;IACxD,UAAU,CAAC,EAAE,oCAAoC,CAAC;IAClD,qBAAqB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAClD,0BAA0B,CAAC,EAAE,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC;CAC7E,GACA,OAAO,CAAC,sCAAsC,CAAC,CAqIjD"}
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
+
import type { Uint8Array_ } from '../../../types/index.js';
|
|
1
2
|
/**
|
|
2
3
|
* Cut up a TPM attestation's certInfo into intelligible chunks
|
|
3
4
|
*/
|
|
4
|
-
export declare function parseCertInfo(certInfo:
|
|
5
|
+
export declare function parseCertInfo(certInfo: Uint8Array_): ParsedCertInfo;
|
|
5
6
|
type ParsedCertInfo = {
|
|
6
7
|
magic: number;
|
|
7
8
|
type: string;
|
|
8
|
-
qualifiedSigner:
|
|
9
|
-
extraData:
|
|
9
|
+
qualifiedSigner: Uint8Array_;
|
|
10
|
+
extraData: Uint8Array_;
|
|
10
11
|
clockInfo: {
|
|
11
|
-
clock:
|
|
12
|
+
clock: Uint8Array_;
|
|
12
13
|
resetCount: number;
|
|
13
14
|
restartCount: number;
|
|
14
15
|
safe: boolean;
|
|
15
16
|
};
|
|
16
|
-
firmwareVersion:
|
|
17
|
+
firmwareVersion: Uint8Array_;
|
|
17
18
|
attested: {
|
|
18
19
|
nameAlg: string;
|
|
19
|
-
nameAlgBuffer:
|
|
20
|
-
name:
|
|
21
|
-
qualifiedName:
|
|
20
|
+
nameAlgBuffer: Uint8Array_;
|
|
21
|
+
name: Uint8Array_;
|
|
22
|
+
qualifiedName: Uint8Array_;
|
|
22
23
|
};
|
|
23
24
|
};
|
|
24
25
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseCertInfo.d.ts","sourceRoot":"","sources":["../../../../src/registration/verifications/tpm/parseCertInfo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"parseCertInfo.d.ts","sourceRoot":"","sources":["../../../../src/registration/verifications/tpm/parseCertInfo.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,GAAG,cAAc,CAkEnE;AAED,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,WAAW,CAAC;IAC7B,SAAS,EAAE,WAAW,CAAC;IACvB,SAAS,EAAE;QACT,KAAK,EAAE,WAAW,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,EAAE,OAAO,CAAC;KACf,CAAC;IACF,eAAe,EAAE,WAAW,CAAC;IAC7B,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,EAAE,WAAW,CAAC;QAC3B,IAAI,EAAE,WAAW,CAAC;QAClB,aAAa,EAAE,WAAW,CAAC;KAC5B,CAAC;CACH,CAAC"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { Uint8Array_ } from '../../../types/index.js';
|
|
1
2
|
/**
|
|
2
3
|
* Break apart a TPM attestation's pubArea buffer
|
|
3
4
|
*
|
|
4
5
|
* See 12.2.4 TPMT_PUBLIC here:
|
|
5
6
|
* https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-00.96-130315.pdf
|
|
6
7
|
*/
|
|
7
|
-
export declare function parsePubArea(pubArea:
|
|
8
|
+
export declare function parsePubArea(pubArea: Uint8Array_): ParsedPubArea;
|
|
8
9
|
type ParsedPubArea = {
|
|
9
10
|
type: 'TPM_ALG_RSA' | 'TPM_ALG_ECC';
|
|
10
11
|
nameAlg: string;
|
|
@@ -21,12 +22,12 @@ type ParsedPubArea = {
|
|
|
21
22
|
decrypt: boolean;
|
|
22
23
|
signOrEncrypt: boolean;
|
|
23
24
|
};
|
|
24
|
-
authPolicy:
|
|
25
|
+
authPolicy: Uint8Array_;
|
|
25
26
|
parameters: {
|
|
26
27
|
rsa?: RSAParameters;
|
|
27
28
|
ecc?: ECCParameters;
|
|
28
29
|
};
|
|
29
|
-
unique:
|
|
30
|
+
unique: Uint8Array_;
|
|
30
31
|
};
|
|
31
32
|
type RSAParameters = {
|
|
32
33
|
symmetric: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsePubArea.d.ts","sourceRoot":"","sources":["../../../../src/registration/verifications/tpm/parsePubArea.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"parsePubArea.d.ts","sourceRoot":"","sources":["../../../../src/registration/verifications/tpm/parsePubArea.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,CAyGhE;AAED,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,aAAa,GAAG,aAAa,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE;QAChB,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,EAAE,OAAO,CAAC;QACrB,mBAAmB,EAAE,OAAO,CAAC;QAC7B,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;QACzB,IAAI,EAAE,OAAO,CAAC;QACd,oBAAoB,EAAE,OAAO,CAAC;QAC9B,UAAU,EAAE,OAAO,CAAC;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,UAAU,EAAE,WAAW,CAAC;IACxB,UAAU,EAAE;QACV,GAAG,CAAC,EAAE,aAAa,CAAC;QACpB,GAAG,CAAC,EAAE,aAAa,CAAC;KACrB,CAAC;IACF,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyAttestationTPM.d.ts","sourceRoot":"","sources":["../../../../src/registration/verifications/tpm/verifyAttestationTPM.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"verifyAttestationTPM.d.ts","sourceRoot":"","sources":["../../../../src/registration/verifications/tpm/verifyAttestationTPM.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAC;AAwBzF,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,OAAO,CAAC,CA+VlB"}
|
|
@@ -83,7 +83,7 @@ async function verifyAttestationAndroidKey(options) {
|
|
|
83
83
|
}
|
|
84
84
|
catch (err) {
|
|
85
85
|
const _err = err;
|
|
86
|
-
throw new Error(`${_err.message} (Android Key)
|
|
86
|
+
throw new Error(`${_err.message} (Android Key)`, { cause: _err });
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
else {
|
|
@@ -97,7 +97,7 @@ async function verifyAttestationAndroidKey(options) {
|
|
|
97
97
|
}
|
|
98
98
|
catch (err) {
|
|
99
99
|
const _err = err;
|
|
100
|
-
throw new Error(`${_err.message} (Android Key)
|
|
100
|
+
throw new Error(`${_err.message} (Android Key)`, { cause: _err });
|
|
101
101
|
}
|
|
102
102
|
/**
|
|
103
103
|
* Make sure the root certificate is one of the Google Hardware Attestation Root certificates
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyAttestationAndroidSafetyNet.d.ts","sourceRoot":"","sources":["../../../src/registration/verifications/verifyAttestationAndroidSafetyNet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AAWtF;;GAEG;AACH,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"verifyAttestationAndroidSafetyNet.d.ts","sourceRoot":"","sources":["../../../src/registration/verifications/verifyAttestationAndroidSafetyNet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AAWtF;;GAEG;AACH,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,OAAO,CAAC,CA4IlB"}
|
|
@@ -13,7 +13,7 @@ const verifyAttestationWithMetadata_js_1 = require("../../metadata/verifyAttesta
|
|
|
13
13
|
* Verify an attestation response with fmt 'android-safetynet'
|
|
14
14
|
*/
|
|
15
15
|
async function verifyAttestationAndroidSafetyNet(options) {
|
|
16
|
-
const { attStmt, clientDataHash, authData, aaguid, rootCertificates, verifyTimestampMS = true, credentialPublicKey, } = options;
|
|
16
|
+
const { attStmt, clientDataHash, authData, aaguid, rootCertificates, verifyTimestampMS = true, credentialPublicKey, attestationSafetyNetEnforceCTSCheck, } = options;
|
|
17
17
|
const alg = attStmt.get('alg');
|
|
18
18
|
const response = attStmt.get('response');
|
|
19
19
|
const ver = attStmt.get('ver');
|
|
@@ -52,7 +52,7 @@ async function verifyAttestationAndroidSafetyNet(options) {
|
|
|
52
52
|
if (nonce !== expectedNonce) {
|
|
53
53
|
throw new Error('Could not verify payload nonce (SafetyNet)');
|
|
54
54
|
}
|
|
55
|
-
if (!ctsProfileMatch) {
|
|
55
|
+
if (attestationSafetyNetEnforceCTSCheck && !ctsProfileMatch) {
|
|
56
56
|
throw new Error('Could not verify device integrity (SafetyNet)');
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { COSEAlgorithmIdentifier, CredentialDeviceType, RegistrationResponseJSON, WebAuthnCredential } from '../types/index.js';
|
|
1
|
+
import type { COSEAlgorithmIdentifier, CredentialDeviceType, RegistrationResponseJSON, Uint8Array_, WebAuthnCredential } from '../types/index.js';
|
|
2
2
|
import { type AttestationFormat, type AttestationStatement } from '../helpers/decodeAttestationObject.js';
|
|
3
3
|
import type { AuthenticationExtensionsAuthenticatorOutputs } from '../helpers/decodeAuthenticatorExtensions.js';
|
|
4
4
|
/**
|
|
@@ -18,6 +18,7 @@ export type VerifyRegistrationResponseOpts = Parameters<typeof verifyRegistratio
|
|
|
18
18
|
* @param requireUserPresence **(Optional)** - Enforce user presence by the authenticator (or skip it during auto registration) Defaults to `true`
|
|
19
19
|
* @param requireUserVerification **(Optional)** - Enforce user verification by the authenticator (via PIN, fingerprint, etc...) Defaults to `true`
|
|
20
20
|
* @param supportedAlgorithmIDs **(Optional)** - Array of numeric COSE algorithm identifiers supported for attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms. Defaults to all supported algorithm IDs
|
|
21
|
+
* @param attestationSafetyNetEnforceCTSCheck **(Optional)** - Require that an Android device's system integrity has not been tampered with if it uses SafetyNet attestation. Defaults to `true`
|
|
21
22
|
*/
|
|
22
23
|
export declare function verifyRegistrationResponse(options: {
|
|
23
24
|
response: RegistrationResponseJSON;
|
|
@@ -28,6 +29,7 @@ export declare function verifyRegistrationResponse(options: {
|
|
|
28
29
|
requireUserPresence?: boolean;
|
|
29
30
|
requireUserVerification?: boolean;
|
|
30
31
|
supportedAlgorithmIDs?: COSEAlgorithmIdentifier[];
|
|
32
|
+
attestationSafetyNetEnforceCTSCheck?: boolean;
|
|
31
33
|
}): Promise<VerifiedRegistrationResponse>;
|
|
32
34
|
/**
|
|
33
35
|
* Result of registration verification
|
|
@@ -56,13 +58,16 @@ export declare function verifyRegistrationResponse(options: {
|
|
|
56
58
|
* by the browser
|
|
57
59
|
*/
|
|
58
60
|
export type VerifiedRegistrationResponse = {
|
|
59
|
-
verified:
|
|
60
|
-
registrationInfo?:
|
|
61
|
+
verified: false;
|
|
62
|
+
registrationInfo?: never;
|
|
63
|
+
} | {
|
|
64
|
+
verified: true;
|
|
65
|
+
registrationInfo: {
|
|
61
66
|
fmt: AttestationFormat;
|
|
62
67
|
aaguid: string;
|
|
63
68
|
credential: WebAuthnCredential;
|
|
64
69
|
credentialType: 'public-key';
|
|
65
|
-
attestationObject:
|
|
70
|
+
attestationObject: Uint8Array_;
|
|
66
71
|
userVerified: boolean;
|
|
67
72
|
credentialDeviceType: CredentialDeviceType;
|
|
68
73
|
credentialBackedUp: boolean;
|
|
@@ -75,14 +80,15 @@ export type VerifiedRegistrationResponse = {
|
|
|
75
80
|
* Values passed to all attestation format verifiers, from which they are free to use as they please
|
|
76
81
|
*/
|
|
77
82
|
export type AttestationFormatVerifierOpts = {
|
|
78
|
-
aaguid:
|
|
83
|
+
aaguid: Uint8Array_;
|
|
79
84
|
attStmt: AttestationStatement;
|
|
80
|
-
authData:
|
|
81
|
-
clientDataHash:
|
|
82
|
-
credentialID:
|
|
83
|
-
credentialPublicKey:
|
|
85
|
+
authData: Uint8Array_;
|
|
86
|
+
clientDataHash: Uint8Array_;
|
|
87
|
+
credentialID: Uint8Array_;
|
|
88
|
+
credentialPublicKey: Uint8Array_;
|
|
84
89
|
rootCertificates: string[];
|
|
85
|
-
rpIdHash:
|
|
90
|
+
rpIdHash: Uint8Array_;
|
|
86
91
|
verifyTimestampMS?: boolean;
|
|
92
|
+
attestationSafetyNetEnforceCTSCheck?: boolean;
|
|
87
93
|
};
|
|
88
94
|
//# sourceMappingURL=verifyRegistrationResponse.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyRegistrationResponse.d.ts","sourceRoot":"","sources":["../../src/registration/verifyRegistrationResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAE1B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,4CAA4C,EAAE,MAAM,6CAA6C,CAAC;AAoBhH;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9F
|
|
1
|
+
{"version":3,"file":"verifyRegistrationResponse.d.ts","sourceRoot":"","sources":["../../src/registration/verifyRegistrationResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EACxB,WAAW,EACX,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAE1B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,4CAA4C,EAAE,MAAM,6CAA6C,CAAC;AAoBhH;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9F;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE;IACP,QAAQ,EAAE,wBAAwB,CAAC;IACnC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAChF,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,qBAAqB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAClD,mCAAmC,CAAC,EAAE,OAAO,CAAC;CAC/C,GACA,OAAO,CAAC,4BAA4B,CAAC,CAqPvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,QAAQ,EAAE,KAAK,CAAC;IAChB,gBAAgB,CAAC,EAAE,KAAK,CAAC;CAC1B,GAAG;IACF,QAAQ,EAAE,IAAI,CAAC;IACf,gBAAgB,EAAE;QAChB,GAAG,EAAE,iBAAiB,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,kBAAkB,CAAC;QAC/B,cAAc,EAAE,YAAY,CAAC;QAC7B,iBAAiB,EAAE,WAAW,CAAC;QAC/B,YAAY,EAAE,OAAO,CAAC;QACtB,oBAAoB,EAAE,oBAAoB,CAAC;QAC3C,kBAAkB,EAAE,OAAO,CAAC;QAC5B,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,6BAA6B,CAAC,EAAE,4CAA4C,CAAC;KAC9E,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,QAAQ,EAAE,WAAW,CAAC;IACtB,cAAc,EAAE,WAAW,CAAC;IAC5B,YAAY,EAAE,WAAW,CAAC;IAC1B,mBAAmB,EAAE,WAAW,CAAC;IACjC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,WAAW,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mCAAmC,CAAC,EAAE,OAAO,CAAC;CAC/C,CAAC"}
|
|
@@ -32,9 +32,10 @@ const verifyAttestationApple_js_1 = require("./verifications/verifyAttestationAp
|
|
|
32
32
|
* @param requireUserPresence **(Optional)** - Enforce user presence by the authenticator (or skip it during auto registration) Defaults to `true`
|
|
33
33
|
* @param requireUserVerification **(Optional)** - Enforce user verification by the authenticator (via PIN, fingerprint, etc...) Defaults to `true`
|
|
34
34
|
* @param supportedAlgorithmIDs **(Optional)** - Array of numeric COSE algorithm identifiers supported for attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms. Defaults to all supported algorithm IDs
|
|
35
|
+
* @param attestationSafetyNetEnforceCTSCheck **(Optional)** - Require that an Android device's system integrity has not been tampered with if it uses SafetyNet attestation. Defaults to `true`
|
|
35
36
|
*/
|
|
36
37
|
async function verifyRegistrationResponse(options) {
|
|
37
|
-
const { response, expectedChallenge, expectedOrigin, expectedRPID, expectedType, requireUserPresence = true, requireUserVerification = true, supportedAlgorithmIDs = generateRegistrationOptions_js_1.supportedCOSEAlgorithmIdentifiers, } = options;
|
|
38
|
+
const { response, expectedChallenge, expectedOrigin, expectedRPID, expectedType, requireUserPresence = true, requireUserVerification = true, supportedAlgorithmIDs = generateRegistrationOptions_js_1.supportedCOSEAlgorithmIdentifiers, attestationSafetyNetEnforceCTSCheck = true, } = options;
|
|
38
39
|
const { id, rawId, type: credentialType, response: attestationResponse } = response;
|
|
39
40
|
// Ensure credential specified an ID
|
|
40
41
|
if (!id) {
|
|
@@ -153,6 +154,7 @@ async function verifyRegistrationResponse(options) {
|
|
|
153
154
|
credentialPublicKey,
|
|
154
155
|
rootCertificates,
|
|
155
156
|
rpIdHash,
|
|
157
|
+
attestationSafetyNetEnforceCTSCheck,
|
|
156
158
|
};
|
|
157
159
|
/**
|
|
158
160
|
* Verification can only be performed when attestation = 'direct'
|
|
@@ -186,12 +188,13 @@ async function verifyRegistrationResponse(options) {
|
|
|
186
188
|
else {
|
|
187
189
|
throw new Error(`Unsupported Attestation Format: ${fmt}`);
|
|
188
190
|
}
|
|
189
|
-
|
|
190
|
-
verified
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
191
|
+
if (!verified) {
|
|
192
|
+
return { verified: false };
|
|
193
|
+
}
|
|
194
|
+
const { credentialDeviceType, credentialBackedUp } = (0, parseBackupFlags_js_1.parseBackupFlags)(flags);
|
|
195
|
+
return {
|
|
196
|
+
verified: true,
|
|
197
|
+
registrationInfo: {
|
|
195
198
|
fmt,
|
|
196
199
|
aaguid: (0, convertAAGUIDToString_js_1.convertAAGUIDToString)(aaguid),
|
|
197
200
|
credentialType,
|
|
@@ -208,7 +211,6 @@ async function verifyRegistrationResponse(options) {
|
|
|
208
211
|
origin: clientDataJSON.origin,
|
|
209
212
|
rpID: matchedRPID,
|
|
210
213
|
authenticatorExtensionResults: extensionsData,
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return toReturn;
|
|
214
|
+
},
|
|
215
|
+
};
|
|
214
216
|
}
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
* SHA256 Fingerprint
|
|
9
9
|
* CB:B5:22:D7:B7:F1:27:AD:6A:01:13:86:5B:DF:1C:D4:10:2E:7D:07:59:AF:63:5A:7C:F4:72:0D:C9:63:C5:3B
|
|
10
10
|
*/
|
|
11
|
-
export declare const GlobalSign_Root_CA_R3 = "-----BEGIN CERTIFICATE-----\
|
|
11
|
+
export declare const GlobalSign_Root_CA_R3 = "-----BEGIN CERTIFICATE-----\nMIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G\nA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp\nZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4\nMTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG\nA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8\nRgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT\ngHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm\nKPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd\nQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ\nXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw\nDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o\nLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU\nRUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp\njjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK\n6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX\nmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs\nMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH\nWD9f\n-----END CERTIFICATE-----\n ";
|
|
12
12
|
//# sourceMappingURL=mds.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mds.d.ts","sourceRoot":"","sources":["../../../src/services/defaultRootCerts/mds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"mds.d.ts","sourceRoot":"","sources":["../../../src/services/defaultRootCerts/mds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,wuCAqBhC,CAAC"}
|