Skip to content

Attestation Certificate Chain is always NULL unless root checks are enabled. #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
My1 opened this issue May 4, 2025 · 0 comments
Open

Comments

@My1
Copy link
Contributor

My1 commented May 4, 2025

when checking over attestations for stats and nerdism, I noticed something weird.
several of the attestations were not chaining down to root.
While I have been using an older version of this tool, the source indicates that the behavior is still present.

code path

the certificateChain parameter, which can be used to get intermediate certs gets populated over here:

https://github.com/lbuchs/WebAuthn/blob/master/src/WebAuthn.php#L409

which asks the attestation object over here

https://github.com/lbuchs/WebAuthn/blob/master/src/Attestation/AttestationObject.php#L82

which asks the Attestation FORMAT over there

https://github.com/lbuchs/WebAuthn/blob/master/src/Attestation/Format/FormatBase.php#L39

this one checks whether a specific temp file has been created, if it has returns it, if not, returns NULL, so far so simple.

The problem stems from the creation of said temp file.

The function is protected so cannot be triggered from outside

https://github.com/lbuchs/WebAuthn/blob/master/src/Attestation/Format/FormatBase.php#L94

The function is only called within validateRootCertificate, from each of the respective formats, in this case packed

https://github.com/lbuchs/WebAuthn/blob/master/src/Attestation/Format/Packed.php#L81

this now is only called if we have root certificates to check against as can be seen here

https://github.com/lbuchs/WebAuthn/blob/master/src/WebAuthn.php#L381

In Conclusion:

if is_array($this->_caFiles) fails, as in when we dont check certificates on registration, the entire check gets cut out, therefore no temp file gets created, therefore you cannot obtain the chain to e.g. check certificates later if you want to.


on another note what does -1 do as a purpose in openssl_x509_checkpurpose?
As far as I have seen the values should be all positive
https://www.php.net/manual/en/function.openssl-x509-checkpurpose.php

    [X509_PURPOSE_SSL_CLIENT] => 1
    [X509_PURPOSE_SSL_SERVER] => 2
    [X509_PURPOSE_NS_SSL_SERVER] => 3
    [X509_PURPOSE_SMIME_SIGN] => 4
    [X509_PURPOSE_SMIME_ENCRYPT] => 5
    [X509_PURPOSE_CRL_SIGN] => 6
    [X509_PURPOSE_ANY] => 7

on a third note: relying on the Subject Key Identifier alone for e.g. checking if a cert is self signed, like here

https://github.com/lbuchs/WebAuthn/blob/master/src/Attestation/Format/FormatBase.php#L104

might cause issues as not all certificates of FIDO things have those stored inside. especially when checking actual entries, this can become a problem, as U2F Certs are identified by their SKID, heck even the Yubi Nano 4 is missing the SKID in the attestation cert.

one crazy way to get the SKID manually is to dig out the key and do it yourself, very crude, also would need to be adjusted for different key methods, for P256 you can use this:

$search=hex2bin("3059301306072A8648CE3D020106082A8648CE3D0301070342"); //OID for P256
//bincert is the binary represenation of the cert (so basically DER)
$skid=sha1(substr($bincert,strpos($bincert,$search)+strlen($search)+1,65));

Example Cert:
-----BEGIN CERTIFICATE-----
MIICRDCCAS6gAwIBAgIEVWK+oDALBgkqhkiG9w0BAQswLjEsMCoGA1UEAxMjWXVi
aWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEwIBcNMTQwODAxMDAwMDAw
WhgPMjA1MDA5MDQwMDAwMDBaMCoxKDAmBgNVBAMMH1l1YmljbyBVMkYgRUUgU2Vy
aWFsIDE0MzI1MzQ2ODgwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARLMx93PYFE
uZlcvkWFUX4XWDqkdiNpXL6FrEgsgBnyyblGeuBFsOZvExsuoyQ8kf2mAuMY8/xd
jSp6uucr0UMJozswOTAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4xLjQxNDgyLjEu
NTATBgsrBgEEAYLlHAIBAQQEAwIFIDALBgkqhkiG9w0BAQsDggEBAKwW2bNutrOp
t211lLNPWfT3PtvJ/espNetrRRyr9B0l0+cWFNdHJgTKcqV44yPtt2AEaF8F59G5
vgXbbpRA+sXPyTKmyvroUpl3LtsCeCAgPNQUHT7rb2os6Z45V4AyY6urjW7EgKff
CErSy6e31td8lMPrwLFm+WBXyvX+OmMeompDN2Kjb77PTPRFCWJf1a8QSap8i8do
mmZZ6a9d6PDXLCiCUXTFDgarf2oHkIN7bbMqv9y8qDXLuwkO8fDZnghpv+nlZ2TE
Iw5sBXcpsBDeDsX5zOTJHCgmIY6oCBq7lpFR7BZyWvKo2V53lbyqInqblEMgxCdh
nKr4VNmCmNc=
-----END CERTIFICATE-----

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant