Skip to content

Commit cca1b23

Browse files
committed
chore: simplify metadata statement check
1 parent 4d7c777 commit cca1b23

File tree

1 file changed

+32
-36
lines changed

1 file changed

+32
-36
lines changed

src/webauthn/src/CeremonyStep/CheckMetadataStatement.php

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -79,41 +79,41 @@ public function process(
7979
$attestedCredentialData !== null || throw AuthenticatorResponseVerificationException::create(
8080
'No attested credential data found'
8181
);
82-
$aaguid = $attestedCredentialData->aaguid
83-
->__toString();
84-
if ($publicKeyCredentialOptions->attestation === null || $publicKeyCredentialOptions->attestation === PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE) {
85-
$this->logger->debug('No attestation is asked.');
86-
if ($aaguid === '00000000-0000-0000-0000-000000000000' && in_array(
87-
$attestationStatement->type,
88-
[AttestationStatement::TYPE_NONE, AttestationStatement::TYPE_SELF],
89-
true
90-
)) {
91-
$this->logger->debug('The Attestation Statement is anonymous.');
92-
$this->checkCertificateChain($attestationStatement, null);
93-
return;
94-
}
82+
83+
/**
84+
* RP does not want to verify the authentication attestation.
85+
* @see https://www.w3.org/TR/webauthn-3/#dom-attestationconveyancepreference-none
86+
*/
87+
if (in_array($publicKeyCredentialOptions->attestation, [null, PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE], true)) {
9588
return;
9689
}
97-
// If no Attestation Statement has been returned or if null AAGUID (=00000000-0000-0000-0000-000000000000)
98-
// => nothing to check
99-
if ($attestationStatement->type === AttestationStatement::TYPE_NONE) {
100-
$this->logger->debug('No attestation returned.');
101-
//No attestation is returned. We shall ensure that the AAGUID is a null one.
102-
//if ($aaguid !== '00000000-0000-0000-0000-000000000000') {
103-
//$this->logger->debug('Anonymization required. AAGUID and Attestation Statement changed.', [
104-
// 'aaguid' => $aaguid,
105-
// 'AttestationStatement' => $attestationStatement,
106-
//]);
107-
//$attestedCredentialData->aaguid = Uuid::fromString('00000000-0000-0000-0000-000000000000');
108-
// return;
109-
//}
90+
91+
/**
92+
* No trust path available for verification
93+
*
94+
* @see https://www.w3.org/TR/webauthn-3/#none
95+
* @see https://www.w3.org/TR/webauthn-3/#self
96+
*/
97+
if (in_array($attestationStatement->type, [AttestationStatement::TYPE_NONE, AttestationStatement::TYPE_SELF], true)) {
11098
return;
11199
}
100+
101+
$aaguid = $attestedCredentialData->aaguid
102+
->__toString();
103+
/**
104+
* All-zeros AAGUID: either privacy placeholder or U2F device (which predates AAGUID).
105+
* 1) Privacy Placeholder indicates the authenticator does not provide detailed information.
106+
* 2) U2F device can not provide useful AAGUID.
107+
*
108+
* So Metadata Statement lookup by AAGUID not possible, skip it.
109+
*
110+
* @see https://www.w3.org/TR/webauthn-3/#sctn-createCredential
111+
* @see https://fidoalliance.org/specs/fido-v2.2-ps-20250714/fido-client-to-authenticator-protocol-v2.2-ps-20250714.html#u2f-authenticatorMakeCredential-interoperability
112+
*/
112113
if ($aaguid === '00000000-0000-0000-0000-000000000000') {
113-
//No need to continue if the AAGUID is null.
114-
// This could be the case e.g. with AnonCA type
115114
return;
116115
}
116+
117117
//The MDS Repository is mandatory here
118118
$this->metadataStatementRepository !== null || throw AuthenticatorResponseVerificationException::create(
119119
'The Metadata Statement Repository is mandatory when requesting attestation objects.'
@@ -171,17 +171,13 @@ private function checkStatusReport(string $aaguid): void
171171

172172
private function checkCertificateChain(
173173
AttestationStatement $attestationStatement,
174-
?MetadataStatement $metadataStatement
174+
MetadataStatement $metadataStatement
175175
): void {
176176
$trustPath = $attestationStatement->trustPath;
177-
if (! $trustPath instanceof CertificateTrustPath) {
178-
return;
179-
}
177+
$trustPath instanceof CertificateTrustPath || throw AuthenticatorResponseVerificationException::create(
178+
'Certificate trust path is required for attestation verification'
179+
);
180180
$authenticatorCertificates = $trustPath->certificates;
181-
if ($metadataStatement === null) {
182-
$this->certificateChainValidator?->check($authenticatorCertificates, []);
183-
return;
184-
}
185181
$trustedCertificates = CertificateToolbox::fixPEMStructures(
186182
$metadataStatement->attestationRootCertificates
187183
);

0 commit comments

Comments
 (0)