-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Tested in Stepup-webauthn 2.0.6
Registration of a YubiKey Bio Series - FIDO Edition (AAGUID 7409272d-1ff9-4e10-9fc9-ac0019c124fd) fails. It is present in the MDS, but the validation of the certificate chain fails.
TLDR: This fails because the PhpCertificateChainValidator expects the trusted certificates to be Root CA certificates and expects the untrusted certificates to contain all the certificates to complete the chain. This is how a validation of a TLS server certificate would work, where the server sends the end-entity (server) certificate and the chain, and the client checks this chain against it's trust store of CA root certificates. Validation if a FIDO attestation certificate however works differently:
- The attestationRootCertificates MAY contain intermediates CA certificates (i.e. "chain" certificates). See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#dom-metadatastatement-attestationrootcertificates
- The
x5carray must contain the end-entity certificate at position 0, and MAY have additional chain certificates. (When present these must be in chain order). x5c follows the JSON Web Token spec. "Attestation Certificate and its certificate chain as described in [JWS] section 4.1.6." See: https://fidoalliance.org/specs/fido-v2.0-ps-20150904/fido-key-attestation-v2.0-ps-20150904.html
The signature of the check() method is public function check(array $untrustedCertificates, array $trustedCertificates): void
PhpCertificateChainValidator::check() it is fed the attestationRootCertificates from the MDS metadata as $trustedCertificates and the x5c from the token's attestationObject as $untrustedCertificates. (See: https://github.com/web-auth/webauthn-lib/blob/5.2.2/src/CeremonyStep/CheckMetadataStatement.php#L172-L189)
However the attestationRootCertificates contains the intermediate CA certificate that are required to build the chain, and are not present in the x5c array in the token's attestationRootCertificates. When trying to build the chain it fails because it does not consider completing the chain with certificates from the $trustedCertificates:
- It loops over the
$trustedCertificates(i.e. attestationRootCertificates) one-by-one: https://github.com/web-auth/webauthn-lib/blob/5.2.2/src/MetadataService/CertificateChain/PhpCertificateChainValidator.php#L68 - Then validates the chain with the
$untrustedCertificates(i.e. the x5c token certificate) and the$trustedCertificatebeing tested. See: https://github.com/web-auth/webauthn-lib/blob/5.2.2/src/MetadataService/CertificateChain/PhpCertificateChainValidator.php#L73
This can never lead to a chain that that terminates in a self-signed (i.e. root) certificate as required by the PathValidator.
The PhpCertificateChainValidator performs CRL checks, however MDS as a different revocation mechanism (statusReports), further strengthening the suspicion that the PhpCertificateChainValidator was never intended for validating attestation certificates against FIDO MDS as currently used.
The error from the Stepup-WebAuthn logs:
{
"exception": {
"class": "Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException",
"message": "Unable to validate the certificate chain.",
"code": 0,
"file": "/var/www/html/vendor/web-auth/webauthn-symfony-bundle/src/Security/Http/Authenticator/WebauthnAuthenticator.php: 283",
"previous": {
"class": "Webauthn\\Exception\\CertificateChainException",
"message": "Unable to validate the certificate chain.",
"code": 0,
"file": "/var/www/html/vendor/web-auth/webauthn-lib/src/Exception/CertificateChainException.php:34"
}
}Exception location: https://github.com/web-auth/webauthn-symfony-bundle/blob/5.2.2/src/Security/Http/Authenticator/WebauthnAuthenticator.php#L283
The exception: https://github.com/web-auth/webauthn-lib/blob/5.2.2/src/Exception/CertificateChainException.php#L34
The CertificateChainException exception is only thrown by the PhpCertificateChainValidator: https://github.com/web-auth/webauthn-lib/blob/5.2.2/src/MetadataService/CertificateChain/PhpCertificateChainValidator.php
The PhpCertificateChainValidator is the default certificate_chain_checker that is used is used by the CheckMetadataStatement CeremonyStep.
This CeremonyStep is part of the check() on the attestationResponseValidator in https://github.com/web-auth/webauthn-symfony-bundle/blob/5.2.2/src/Security/Http/Authenticator/WebauthnAuthenticator.php#L255-L259
Token response:
{
"id": "pFMxgVzUVXOk-9GVmUDqtmzEboFQYKIeTaZprJerRbVeERDzRZyQ2PspELDs1PWCc7G-aymsH7CrPrXDJs9m6w",
"rawId": "pFMxgVzUVXOk-9GVmUDqtmzEboFQYKIeTaZprJerRbVeERDzRZyQ2PspELDs1PWCc7G-aymsH7CrPrXDJs9m6w",
"response": {
"attestationObject": "o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIhAPuOmTr0EflTs03CK7xRcMWR6lZw9I9XasL9UoioVxFwAiA41fgBtTd_U_914AywSFOV9oHzy4uUho0B_67btb8k_GN4NWOBWQLFMIICwTCCAamgAwIBAgIJAPixTI1SfWJyMA0GCSqGSIb3DQEBCwUAMCYxJDAiBgNVBAMMG1l1YmljbyBGSURPIEF0dGVzdGF0aW9uIEIgMTAgFw0yNDEyMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowdTELMAkGA1UEBhMCU0UxEjAQBgNVBAoMCVl1YmljbyBBQjEiMCAGA1UECwwZQXV0aGVudGljYXRvciBBdHRlc3RhdGlvbjEuMCwGA1UEAwwlWXViaWNvIEZJRE8gRUUgU2VyaWFsIDE0MDY5NDc2MTgxMjQ3MjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEDe_ETwplfJFFBIl6hxOg3gyVhpFV0tLr8QoPR8bUzj2JJcTVsJ69g5hhXeGdpncQaFQ7Yv_T5dvlqhv7zclkyjbDBqMBMGCisGAQQBgsQKDQEEBQQDBQcEMCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS45MCEGCysGAQQBguUcAQEEBBIEEHQJJy0f-U4Qn8msABnBJP0wDAYDVR0TAQH_BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAOLMF4W0G3hZwlscE-3U0GjAh9OiNkrA-xnDqlR77Wph7a017GZ7jTvJteIYA5bF8eZNGMFZQAnRdSVAxQfss3aUsR6uIcaxWjUv3v63ZSgkJrKrIKDuF_HMjwubwKR09CYsHArcw7oRjW7nYPxWWaAFX7mJSr8JSx7f9fOw61oQZD-1gYaP7aOjRSlQI8zuRH0LuJ6l_Ui7I0cVTyDBJpMNholoPHM2Cn45gylK3yXxC_U9RwYsyy0EvTDSQMSXgq4ss38ChHg0vkY3oN5F-O_SZMb8LkR3SiU5041XQb3PF9Qek19eK4zPqrH3CW0UekyOkWKMp8Zr1Y26skqEdxWhhdXRoRGF0YVjE1SHZosOfudu4e6ND69j8ip3avTetdPzJEZlwXQyfI2RFAAAAA3QJJy0f-U4Qn8msABnBJP0AQKRTMYFc1FVzpPvRlZlA6rZsxG6BUGCiHk2maayXq0W1XhEQ80WckNj7KRCw7NT1gnOxvmsprB-wqz61wybPZuulAQIDJiABIVggs767sS3c6mlwKreCY5EEjuCUqMsO-HFyD0je-VtHuqAiWCB20ZcP2wG3RenBpVmY7h2AnkgNBgLBFiFCOxkSijIryg",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiaDExQzVHaFlQN1VxbGZGSjhpMEtJcUVwbHRJYlRHaXZBbmJ3dXRDR0hRRTJTUHRHejNQOFJYOTMxU2xtVkhGWmppS3NhR05aVFp1dmxMX1ljUFZLRVEiLCJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLnRlc3Quc3VyZmNvbmV4dC5ubCIsImNyb3NzT3JpZ2luIjpmYWxzZX0",
"transports": [
"usb"
],
"publicKeyAlgorithm": -7,
"publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEs767sS3c6mlwKreCY5EEjuCUqMsO-HFyD0je-VtHuqB20ZcP2wG3RenBpVmY7h2AnkgNBgLBFiFCOxkSijIryg",
"authenticatorData": "1SHZosOfudu4e6ND69j8ip3avTetdPzJEZlwXQyfI2RFAAAAA3QJJy0f-U4Qn8msABnBJP0AQKRTMYFc1FVzpPvRlZlA6rZsxG6BUGCiHk2maayXq0W1XhEQ80WckNj7KRCw7NT1gnOxvmsprB-wqz61wybPZuulAQIDJiABIVggs767sS3c6mlwKreCY5EEjuCUqMsO-HFyD0je-VtHuqAiWCB20ZcP2wG3RenBpVmY7h2AnkgNBgLBFiFCOxkSijIryg"
},
"type": "public-key",
"clientExtensionResults": {},
"authenticatorAttachment": "platform"
}Metadata
Metadata
Assignees
Labels
Type
Projects
Status