Skip to content

Attestation certificate validation of YubiKey Bio Series - FIDO Edition fails #225

@pmeulen

Description

@pmeulen

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 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:

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

No one assigned

    Type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions