@@ -89,41 +89,49 @@ public function process(
8989 $ attestedCredentialData !== null || throw AuthenticatorResponseVerificationException::create (
9090 'No attested credential data found '
9191 );
92- $ aaguid = $ attestedCredentialData ->aaguid
93- ->__toString ();
94- if ($ publicKeyCredentialOptions ->attestation === null || $ publicKeyCredentialOptions ->attestation === PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE ) {
95- $ this ->logger ->debug ('No attestation is asked. ' );
96- if ($ aaguid === '00000000-0000-0000-0000-000000000000 ' && in_array (
97- $ attestationStatement ->type ,
98- [AttestationStatement::TYPE_NONE , AttestationStatement::TYPE_SELF ],
99- true
100- )) {
101- $ this ->logger ->debug ('The Attestation Statement is anonymous. ' );
102- $ this ->checkCertificateChain ($ attestationStatement , null );
103- return ;
104- }
92+
93+ /**
94+ * RP does not want to verify the authentication attestation.
95+ * @see https://www.w3.org/TR/webauthn-3/#dom-attestationconveyancepreference-none
96+ */
97+ if (in_array (
98+ $ publicKeyCredentialOptions ->attestation ,
99+ [null , PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE ],
100+ true
101+ )) {
105102 return ;
106103 }
107- // If no Attestation Statement has been returned or if null AAGUID (=00000000-0000-0000-0000-000000000000)
108- // => nothing to check
109- if ($ attestationStatement ->type === AttestationStatement::TYPE_NONE ) {
110- $ this ->logger ->debug ('No attestation returned. ' );
111- //No attestation is returned. We shall ensure that the AAGUID is a null one.
112- //if ($aaguid !== '00000000-0000-0000-0000-000000000000') {
113- //$this->logger->debug('Anonymization required. AAGUID and Attestation Statement changed.', [
114- // 'aaguid' => $aaguid,
115- // 'AttestationStatement' => $attestationStatement,
116- //]);
117- //$attestedCredentialData->aaguid = Uuid::fromString('00000000-0000-0000-0000-000000000000');
118- // return;
119- //}
104+
105+ /**
106+ * No trust path available for verification
107+ *
108+ * @see https://www.w3.org/TR/webauthn-3/#none
109+ * @see https://www.w3.org/TR/webauthn-3/#self
110+ */
111+ if (in_array (
112+ $ attestationStatement ->type ,
113+ [AttestationStatement::TYPE_NONE , AttestationStatement::TYPE_SELF ],
114+ true
115+ )) {
120116 return ;
121117 }
118+
119+ $ aaguid = $ attestedCredentialData ->aaguid
120+ ->__toString ();
121+ /**
122+ * All-zeros AAGUID: either privacy placeholder or U2F device (which predates AAGUID).
123+ * 1) Privacy Placeholder indicates the authenticator does not provide detailed information.
124+ * 2) U2F device can not provide useful AAGUID.
125+ *
126+ * So Metadata Statement lookup by AAGUID not possible, skip it.
127+ *
128+ * @see https://www.w3.org/TR/webauthn-3/#sctn-createCredential
129+ * @see https://fidoalliance.org/specs/fido-v2.2-ps-20250714/fido-client-to-authenticator-protocol-v2.2-ps-20250714.html#u2f-authenticatorMakeCredential-interoperability
130+ */
122131 if ($ aaguid === '00000000-0000-0000-0000-000000000000 ' ) {
123- //No need to continue if the AAGUID is null.
124- // This could be the case e.g. with AnonCA type
125132 return ;
126133 }
134+
127135 //The MDS Repository is mandatory here
128136 $ this ->metadataStatementRepository !== null || throw AuthenticatorResponseVerificationException::create (
129137 'The Metadata Statement Repository is mandatory when requesting attestation objects. '
@@ -181,17 +189,13 @@ private function checkStatusReport(string $aaguid): void
181189
182190 private function checkCertificateChain (
183191 AttestationStatement $ attestationStatement ,
184- ? MetadataStatement $ metadataStatement
192+ MetadataStatement $ metadataStatement
185193 ): void {
186194 $ trustPath = $ attestationStatement ->trustPath ;
187- if (! $ trustPath instanceof CertificateTrustPath) {
188- return ;
189- }
195+ $ trustPath instanceof CertificateTrustPath || throw AuthenticatorResponseVerificationException:: create (
196+ ' Certificate trust path is required for attestation verification '
197+ );
190198 $ authenticatorCertificates = $ trustPath ->certificates ;
191- if ($ metadataStatement === null ) {
192- $ this ->certificateChainValidator ?->check($ authenticatorCertificates , []);
193- return ;
194- }
195199 $ trustedCertificates = CertificateToolbox::fixPEMStructures (
196200 $ metadataStatement ->attestationRootCertificates
197201 );
0 commit comments