@simplewebauthn/server
Advanced tools
Comparing version 5.4.3 to 5.4.4
@@ -12,10 +12,12 @@ "use strict"; | ||
function convertCertBufferToPEM(certBuffer) { | ||
let buffer; | ||
let b64cert; | ||
/** | ||
* Get certBuffer to a base64 representation | ||
*/ | ||
if (typeof certBuffer === 'string') { | ||
buffer = base64url_1.default.toBuffer(certBuffer); | ||
b64cert = base64url_1.default.toBase64(certBuffer); | ||
} | ||
else { | ||
buffer = certBuffer; | ||
b64cert = certBuffer.toString('base64'); | ||
} | ||
const b64cert = buffer.toString('base64'); | ||
let PEMKey = ''; | ||
@@ -22,0 +24,0 @@ for (let i = 0; i < Math.ceil(b64cert.length / 64); i += 1) { |
@@ -211,3 +211,7 @@ import { Base64URLString } from '@simplewebauthn/typescript-types'; | ||
pinProtocols?: number[]; | ||
algorithms?: { | ||
type: 'public-key'; | ||
alg: number; | ||
}[]; | ||
}; | ||
export {}; |
@@ -8,3 +8,8 @@ /// <reference types="node" /> | ||
*/ | ||
export declare function verifyAttestationWithMetadata(statement: MetadataStatement, credentialPublicKey: Buffer, x5c: Buffer[] | Base64URLString[]): Promise<boolean>; | ||
export declare function verifyAttestationWithMetadata({ statement, credentialPublicKey, x5c, attestationStatementAlg, }: { | ||
statement: MetadataStatement; | ||
credentialPublicKey: Buffer; | ||
x5c: Buffer[] | Base64URLString[]; | ||
attestationStatementAlg?: number; | ||
}): Promise<boolean>; | ||
declare type COSEInfo = { | ||
@@ -11,0 +16,0 @@ kty: number; |
@@ -12,6 +12,7 @@ "use strict"; | ||
*/ | ||
async function verifyAttestationWithMetadata(statement, credentialPublicKey, x5c) { | ||
async function verifyAttestationWithMetadata({ statement, credentialPublicKey, x5c, attestationStatementAlg, }) { | ||
const { authenticationAlgorithms, authenticatorGetInfo, attestationRootCertificates, } = statement; | ||
// Make sure the alg in the attestation statement matches one of the ones specified in metadata | ||
const keypairCOSEAlgs = new Set(); | ||
statement.authenticationAlgorithms.forEach(algSign => { | ||
authenticationAlgorithms.forEach(algSign => { | ||
// Map algSign string to { kty, alg, crv } | ||
@@ -71,3 +72,3 @@ const algSignCOSEINFO = exports.algSignToCOSEInfoMap[algSign]; | ||
*/ | ||
const debugMDSAlgs = statement.authenticationAlgorithms | ||
const debugMDSAlgs = authenticationAlgorithms | ||
.map((algSign) => `'${algSign}' (COSE info: ${stringifyCOSEInfo(exports.algSignToCOSEInfoMap[algSign])})`); | ||
@@ -81,9 +82,33 @@ const strMDSAlgs = JSON.stringify(debugMDSAlgs, null, 2).replace(/"/g, ''); | ||
} | ||
try { | ||
await (0, validateCertificatePath_1.validateCertificatePath)(x5c.map(convertCertBufferToPEM_1.convertCertBufferToPEM), statement.attestationRootCertificates.map(convertCertBufferToPEM_1.convertCertBufferToPEM)); | ||
/** | ||
* Confirm the attestation statement's algorithm is one supported according to metadata | ||
*/ | ||
if (attestationStatementAlg !== undefined && (authenticatorGetInfo === null || authenticatorGetInfo === void 0 ? void 0 : authenticatorGetInfo.algorithms) !== undefined) { | ||
const getInfoAlgs = authenticatorGetInfo.algorithms.map(_alg => _alg.alg); | ||
if (getInfoAlgs.indexOf(attestationStatementAlg) < 0) { | ||
throw new Error(`Attestation statement alg ${attestationStatementAlg} did not match one of ${getInfoAlgs}`); | ||
} | ||
} | ||
catch (err) { | ||
const _err = err; | ||
throw new Error(`Could not validate certificate path with any metadata root certificates: ${_err.message}`); | ||
// Prepare to check the certificate chain | ||
const authenticatorCerts = x5c.map(convertCertBufferToPEM_1.convertCertBufferToPEM); | ||
const statementRootCerts = attestationRootCertificates.map(convertCertBufferToPEM_1.convertCertBufferToPEM); | ||
/** | ||
* If an authenticator returns exactly one certificate in its x5c, and that cert is found in the | ||
* metadata statement then the authenticator is "self-referencing". In this case we forego | ||
* certificate chain validation. | ||
*/ | ||
let authenticatorIsSelfReferencing = false; | ||
if (authenticatorCerts.length === 1 && | ||
statementRootCerts.indexOf(authenticatorCerts[0]) >= 0) { | ||
authenticatorIsSelfReferencing = true; | ||
} | ||
if (!authenticatorIsSelfReferencing) { | ||
try { | ||
await (0, validateCertificatePath_1.validateCertificatePath)(authenticatorCerts, statementRootCerts); | ||
} | ||
catch (err) { | ||
const _err = err; | ||
throw new Error(`Could not validate certificate path with any metadata root certificates: ${_err.message}`); | ||
} | ||
} | ||
return true; | ||
@@ -90,0 +115,0 @@ } |
@@ -203,3 +203,8 @@ "use strict"; | ||
try { | ||
await (0, verifyAttestationWithMetadata_1.verifyAttestationWithMetadata)(statement, credentialPublicKey, x5c); | ||
await (0, verifyAttestationWithMetadata_1.verifyAttestationWithMetadata)({ | ||
statement, | ||
credentialPublicKey, | ||
x5c, | ||
attestationStatementAlg: alg, | ||
}); | ||
} | ||
@@ -206,0 +211,0 @@ catch (err) { |
@@ -60,3 +60,8 @@ "use strict"; | ||
try { | ||
await (0, verifyAttestationWithMetadata_1.verifyAttestationWithMetadata)(statement, credentialPublicKey, x5c); | ||
await (0, verifyAttestationWithMetadata_1.verifyAttestationWithMetadata)({ | ||
statement, | ||
credentialPublicKey, | ||
x5c, | ||
attestationStatementAlg: alg, | ||
}); | ||
} | ||
@@ -63,0 +68,0 @@ catch (err) { |
@@ -20,3 +20,3 @@ "use strict"; | ||
const { attStmt, clientDataHash, authData, aaguid, rootCertificates, verifyTimestampMS = true, credentialPublicKey, } = options; | ||
const { response, ver } = attStmt; | ||
const { alg, response, ver } = attStmt; | ||
if (!ver) { | ||
@@ -77,3 +77,8 @@ throw new Error('No ver value in attestation (SafetyNet)'); | ||
try { | ||
await (0, verifyAttestationWithMetadata_1.verifyAttestationWithMetadata)(statement, credentialPublicKey, HEADER.x5c); | ||
await (0, verifyAttestationWithMetadata_1.verifyAttestationWithMetadata)({ | ||
statement, | ||
credentialPublicKey, | ||
x5c: HEADER.x5c, | ||
attestationStatementAlg: alg, | ||
}); | ||
} | ||
@@ -80,0 +85,0 @@ catch (err) { |
@@ -74,3 +74,8 @@ "use strict"; | ||
try { | ||
await (0, verifyAttestationWithMetadata_1.verifyAttestationWithMetadata)(statement, credentialPublicKey, x5c); | ||
await (0, verifyAttestationWithMetadata_1.verifyAttestationWithMetadata)({ | ||
statement, | ||
credentialPublicKey, | ||
x5c, | ||
attestationStatementAlg: alg, | ||
}); | ||
} | ||
@@ -77,0 +82,0 @@ catch (err) { |
{ | ||
"name": "@simplewebauthn/server", | ||
"version": "5.4.3", | ||
"version": "5.4.4", | ||
"description": "SimpleWebAuthn for Servers", | ||
@@ -62,3 +62,3 @@ "main": "dist/index.js", | ||
}, | ||
"gitHead": "bee3aefe652cba5b6e46dc2af282ec4028e3eefa", | ||
"gitHead": "9c05ec591fa1e8a1d7480a9f115a075fec9a88c5", | ||
"devDependencies": { | ||
@@ -65,0 +65,0 @@ "@types/cbor": "^5.0.1", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
262169
4097