webauthn-ruby
webauthn-ruby copied to clipboard
Pass FIDO2 conformance Server-ServerAuthenticatorAttestationResponse-Resp-5 F-10 test
F-10 Send ServerAuthenticatorAttestationResponse with FULL "packed" attestation, with attStmt.x5c containing full chain, and check that server returns an error
How to run FIDO2 conformance tests: https://github.com/cedarcode/webauthn-ruby/tree/master/spec/conformance.
Related issue: https://github.com/fido-alliance/conformance-test-tools-resources/issues/678
This seems to be caused by the way we validate our certificate chain – essentially:
store = OpenSSL::X509::Store.new
root_certificates.each do |root_certificate|
store.add_cert(root_certificate)
end
attestation_certificate = attestation_trust_path.first
store.verify(attestation_certificate, attestation_trust_path)
For this spec, the root certificate – present in the attestationRootCertificates
attribute in the authenticator's Metadata Statement – is:
See root_cert
-----BEGIN CERTIFICATE-----
MIIFwDCCA6gCCQCNm1u56oRwXTANBgkqhkiG9w0BAQsFADCBoTEYMBYGA1UEAwwP
RklETzIgVEVTVCBST09UMTEwLwYJKoZIhvcNAQkBFiJjb25mb3JtYW5jZS10b29s
c0BmaWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMQwwCgYD
VQQLDANDV0cxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNWTESMBAGA1UEBwwJV2Fr
ZWZpZWxkMB4XDTE4MDMxNjE0MzUyN1oXDTQ1MDgwMTE0MzUyN1owgaExGDAWBgNV
BAMMD0ZJRE8yIFRFU1QgUk9PVDExMC8GCSqGSIb3DQEJARYiY29uZm9ybWFuY2Ut
dG9vbHNAZmlkb2FsbGlhbmNlLm9yZzEWMBQGA1UECgwNRklETyBBbGxpYW5jZTEM
MAoGA1UECwwDQ1dHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcM
CVdha2VmaWVsZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL11U5yA
IVLMrL3xS8u8ysMSdOkDeoTO+RcAy+uXXp6k4SC+jOy37gICEtYI+MKQV1EMeMMf
3rM1ueZAO3iPFa0NEdi/oQ7npnGjBNI8wMzD8FfNe6rWtzkDaHpsZW///MwWDpGy
JR+Xyjcq6U4vS9bS6zZ7jslw0Oczx4UsYgOsIUXSSBaGOrRbxJ/JC5gnDYEYvtNM
+PDPczLNKAyhdvBZWNWHr7MZ0P5TeJQcXsAoShRX2Y8U8fRNJm7SeiFKDP0Nn/QK
xOSt7zGP4xt9nMasE1q2ZTdar2+W13CRz37RI0ZWpq/+YquoEbZ7Uj7NmBTcqhb2
60nmDER2FpwwYwPSark92IZbamozB8d7OEI1jJgsrjJhKan0EmRaWVBpHT4xYKdE
u7r09S0JhKyU+52WDmmVQTMpYLrm4Xl7hRxyPyBYkalrozsGmPs8vlhNq3VsVbyB
SMSpEmUaeAa7LLE9/Vh0agJLVFHh1ehYKJpzHnmmBXUqx0Fz3afmDm1NX0sr3O/6
xIx1VSTViT3KNxBYpVH1qjHATLzuxcWmm+75fcJMiPYPSMXVmRb3Q1l91AM4BBeW
hlP3Fbc7gDy0r+s7m0sGS6PT2J2rGog2rUxnJ+zCM11M7DeO0XM2nny4uRYPPk9w
2EXzfvtdvieYU/5RB4RDm5TGxHhGXVZUgac5AgMBAAEwDQYJKoZIhvcNAQELBQAD
ggIBAFt2XGd3k5GpbO1EUm3u60zT1fE6u6pOscp156k5VnsHgaHRHdIAPNLeLNmR
7y5OnrXbh13CrGwU1q84jjJXpv+v14xUCc5i01yopFTQFLr4A7NHp2nNYfNhhIVS
FAgW43EflJflbLEelCJzxLlWb5BoDsZeeNmEQsXIM1mJ26R3r0dzsHBb0uy+8LNR
1gdVqdjhC8BLy3gh4+BWuidyZNt07LveDsSFW5rcj5wRrSx9hXPIyVpjQSljNvY7
MVTouqJzNAAQMsTKkXPkTXldCop9Qo9UPkHRRm0l7LLtdaOoXrct0Ymocf8zxf9b
FNiw9f4WRYQM6sMhzt8+s/oDilo4QhcUgeJEiEPESi6ynYTV62SHA4eMunUJ5dlC
aRnFiR9DTImFa5IRzie326/nW/SPCaKc/yrFIihMMjJoSAPhpTb/K6yHOUG8r+Ki
Qut7NzqGV301pQ9u62dGL5Oi1VXmCFlE2ramZs15BNOUyAo2CBbRJg3jKcdu/8QC
6ojjDvQ863+7LPtn74wJC5RpUJsS0GhQWgq5pAXO3wA61Uobxi6MkOpCC0zBWx/d
4CqpS4j4hFgxWBTXX48ihPu+hIxIF/AxbqtPvqLMExW/xZITn6ArpWyQ9e4SUVr3
n3F33ap1XdDyZ0vwFcm18JQAtsvXT6qCLrWOXnHUgfn/+Viu
-----END CERTIFICATE-----
On the other hand, the attestation_trust_path
– which comes from the x5c
attribute of the attestation statement – for this spec is the following:
See attestation_trust_path
-----BEGIN CERTIFICATE-----
MIICjjCCAjSgAwIBAgIBATAKBggqhkjOPQQDAjCBrzEmMCQGA1UEAwwdRklETzIg
SU5URVJNRURJQVRFIHByaW1lMjU2djExMTAvBgkqhkiG9w0BCQEWImNvbmZvcm1h
bmNlLXRvb2xzQGZpZG9hbGxpYW5jZS5vcmcxFjAUBgNVBAoMDUZJRE8gQWxsaWFu
Y2UxDDAKBgNVBAsMA0NXRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYD
VQQHDAlXYWtlZmllbGQwHhcNMTgwNTIzMTQzNzQxWhcNMjgwNTIwMTQzNzQxWjCB
wjEjMCEGA1UEAwwaRklETzIgQkFUQ0ggS0VZIHByaW1lMjU2djExMTAvBgkqhkiG
9w0BCQEWImNvbmZvcm1hbmNlLXRvb2xzQGZpZG9hbGxpYW5jZS5vcmcxFjAUBgNV
BAoMDUZJRE8gQWxsaWFuY2UxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0ZXN0
YXRpb24xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNWTESMBAGA1UEBwwJV2FrZWZp
ZWxkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEutlirPGtUi+a+woMkhwX2+s6
mZPQpKNmY77E9cvyGvuAZGllHFGRg/R8kQ/MKjRlMrcP68cW2x0OAb1XbilIZKMs
MCowCQYDVR0TBAIwADAdBgNVHQ4EFgQUSlTlBtKRRE9tDzNd1v3HRmy5X1QwCgYI
KoZIzj0EAwIDSAAwRQIhALlbNrRzfaOsENMNvvXrleUEJ0JaRJV/O+GGodN/J+pF
AiBNC6zAOECkfCpP9fpbxphxyp6cpv0coXwM1pGEczcpeA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEMTCCAhmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBoTEYMBYGA1UEAwwPRklE
TzIgVEVTVCBST09UMTEwLwYJKoZIhvcNAQkBFiJjb25mb3JtYW5jZS10b29sc0Bm
aWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMQwwCgYDVQQL
DANDV0cxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNWTESMBAGA1UEBwwJV2FrZWZp
ZWxkMB4XDTE4MDcyMzE0MjkwN1oXDTQ1MTIwODE0MjkwN1owga8xJjAkBgNVBAMM
HUZJRE8yIElOVEVSTUVESUFURSBwcmltZTI1NnYxMTEwLwYJKoZIhvcNAQkBFiJj
b25mb3JtYW5jZS10b29sc0BmaWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURP
IEFsbGlhbmNlMQwwCgYDVQQLDANDV0cxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJN
WTESMBAGA1UEBwwJV2FrZWZpZWxkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
3EEd31Vtf01zjKl1FHpVcfRjACkj1m+0e16XhyBwWQUOyc6HqW80V4rU3Qi0wnzV
6SxNRuiUXLLT5l/bS0l586MvMC0wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUZ8EZ
kpBb9V0AwdYhDowtdiGSR8AwDQYJKoZIhvcNAQELBQADggIBAAuYLqezVLsHJ3Yn
7+XcJWehiEj0xHIkHTMZjaPZxPQUQDtm7UNA3SXYnwPBp0EHdvXSIJPFOPFrnGOK
s7r0WWius+gCK1NmwFJSayp5U2b43YjN6Ik2PVk4gfXsn5iv2YBL+1vQxBVu764d
9vqY0jRdVcsbjBKZ2tV+rMqrTQ1RvsNGC43ZF4tHIrkSctEPQPdL5jCoAMYJ0Xwq
JeWkFJR6WTE4ivvDgqfLEqKtOUDd/Yst+LuAHihlFnrio2BMDbICoJ/r9fgNXW1M
NnFmIOdzouZvw0C5bflrNYaJLsF8QnpGgb4ngfZ7td32F7+0pIMLljzcMhT5UJFq
SD4G/XmTBN5J1IidhAEtVBO5K2ljYN3EDtr+rWNuPufhZhMrlopxgoax7ME9LGLZ
oUBpVmtGwlfXxCy+vWwjuuEYlqHpy7Il9eYZpgu/mWxfQ9VR49QR0fXoqAGVFaJx
IgyUmR7VcV5ZlN40AYaxD87ReUZ+u9Hc6vxOByz3826ylvi9hdovlhFhe3LYnDVQ
QS11B7BQLxmDKr+wxNMwxmmey/o1yI0gohNiI4sQoTGMP2hWMJsdDesrl3iQ2LvH
wklzikz0emUbCwkN/LVxUkEcp9U+RYL8XbO0NrMYLVVwjcvBTKKH9u4IzLuYuKQL
dpXVxDsdcyNj/jb+hhcWNlPwbVyD
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFwDCCA6gCCQCNm1u56oRwXTANBgkqhkiG9w0BAQsFADCBoTEYMBYGA1UEAwwP
RklETzIgVEVTVCBST09UMTEwLwYJKoZIhvcNAQkBFiJjb25mb3JtYW5jZS10b29s
c0BmaWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMQwwCgYD
VQQLDANDV0cxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNWTESMBAGA1UEBwwJV2Fr
ZWZpZWxkMB4XDTE4MDMxNjE0MzUyN1oXDTQ1MDgwMTE0MzUyN1owgaExGDAWBgNV
BAMMD0ZJRE8yIFRFU1QgUk9PVDExMC8GCSqGSIb3DQEJARYiY29uZm9ybWFuY2Ut
dG9vbHNAZmlkb2FsbGlhbmNlLm9yZzEWMBQGA1UECgwNRklETyBBbGxpYW5jZTEM
MAoGA1UECwwDQ1dHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcM
CVdha2VmaWVsZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL11U5yA
IVLMrL3xS8u8ysMSdOkDeoTO+RcAy+uXXp6k4SC+jOy37gICEtYI+MKQV1EMeMMf
3rM1ueZAO3iPFa0NEdi/oQ7npnGjBNI8wMzD8FfNe6rWtzkDaHpsZW///MwWDpGy
JR+Xyjcq6U4vS9bS6zZ7jslw0Oczx4UsYgOsIUXSSBaGOrRbxJ/JC5gnDYEYvtNM
+PDPczLNKAyhdvBZWNWHr7MZ0P5TeJQcXsAoShRX2Y8U8fRNJm7SeiFKDP0Nn/QK
xOSt7zGP4xt9nMasE1q2ZTdar2+W13CRz37RI0ZWpq/+YquoEbZ7Uj7NmBTcqhb2
60nmDER2FpwwYwPSark92IZbamozB8d7OEI1jJgsrjJhKan0EmRaWVBpHT4xYKdE
u7r09S0JhKyU+52WDmmVQTMpYLrm4Xl7hRxyPyBYkalrozsGmPs8vlhNq3VsVbyB
SMSpEmUaeAa7LLE9/Vh0agJLVFHh1ehYKJpzHnmmBXUqx0Fz3afmDm1NX0sr3O/6
xIx1VSTViT3KNxBYpVH1qjHATLzuxcWmm+75fcJMiPYPSMXVmRb3Q1l91AM4BBeW
hlP3Fbc7gDy0r+s7m0sGS6PT2J2rGog2rUxnJ+zCM11M7DeO0XM2nny4uRYPPk9w
2EXzfvtdvieYU/5RB4RDm5TGxHhGXVZUgac5AgMBAAEwDQYJKoZIhvcNAQELBQAD
ggIBAFt2XGd3k5GpbO1EUm3u60zT1fE6u6pOscp156k5VnsHgaHRHdIAPNLeLNmR
7y5OnrXbh13CrGwU1q84jjJXpv+v14xUCc5i01yopFTQFLr4A7NHp2nNYfNhhIVS
FAgW43EflJflbLEelCJzxLlWb5BoDsZeeNmEQsXIM1mJ26R3r0dzsHBb0uy+8LNR
1gdVqdjhC8BLy3gh4+BWuidyZNt07LveDsSFW5rcj5wRrSx9hXPIyVpjQSljNvY7
MVTouqJzNAAQMsTKkXPkTXldCop9Qo9UPkHRRm0l7LLtdaOoXrct0Ymocf8zxf9b
FNiw9f4WRYQM6sMhzt8+s/oDilo4QhcUgeJEiEPESi6ynYTV62SHA4eMunUJ5dlC
aRnFiR9DTImFa5IRzie326/nW/SPCaKc/yrFIihMMjJoSAPhpTb/K6yHOUG8r+Ki
Qut7NzqGV301pQ9u62dGL5Oi1VXmCFlE2ramZs15BNOUyAo2CBbRJg3jKcdu/8QC
6ojjDvQ863+7LPtn74wJC5RpUJsS0GhQWgq5pAXO3wA61Uobxi6MkOpCC0zBWx/d
4CqpS4j4hFgxWBTXX48ihPu+hIxIF/AxbqtPvqLMExW/xZITn6ArpWyQ9e4SUVr3
n3F33ap1XdDyZ0vwFcm18JQAtsvXT6qCLrWOXnHUgfn/+Viu
-----END CERTIFICATE-----
Note that the last certificate in the attestation_trust_path
is the root certificate itself. According to this spec, this chain is invalid because concatenating the attestation_trust_path
with the root_certificates
results in the chain having duplicate certs, which is invalid according to the RFC 5280:
A certificate MUST NOT appear more than once in a prospective certification path.
However, the chain is in fact valid to OpenSSL
given that, if I understand correctly, it stops building the chain when it finds a self-signed certificate – as stated in the docs:
When a self-signed certificate has been added, chain construction stops. In this case it must fully match a trust anchor, otherwise chain building fails.
Hence our code treats such attestation_trust_path
as valid.
I'm not sure about which approach is correct here to be honest. The following paragraph from the RFC 5280 states that self-signed certificates should not be included in the certification path:
When the trust anchor is provided in the form of a self-signed certificate, this self-signed certificate is not included as part of the prospective certification path. Information about trust anchors is provided as inputs to the certification path validation algorithm (Section 6.1.1). [source]
Not sure how to proceed with this.