-
-
Notifications
You must be signed in to change notification settings - Fork 193
Description
It works on Windows, but on Linux there is a different behavior that seems actually normal, see below.
Failed tests:
- CryptoUtilsTests.TestValidateTrustChainSubAnchor() line 66
- AuthenticatorAttestationResponse.VerifyAsync(CredentialCreateOptions originalOptions, Fido2Configuration config, IsCredentialIdUniqueToUserAsyncDelegate isCredentialIdUniqueToUser, IMetadataService metadataService, Byte[] requestTokenBindingId, CancellationToken cancellationToken) line 187
Fido2Tests.TestInvalidU2FAttestationASync() line 624
Message:
Fido2NetLib.Fido2VerificationException : Invalid certificate chain
From:
fido2-net-lib/Src/Fido2/CryptoUtils.cs
Lines 107 to 118 in db931bd
| if (chain.Build(trustPath[0])) | |
| { | |
| // if the chain validates, make sure one of the attestation root certificates is one of the chain elements | |
| foreach (X509Certificate2? attestationRootCertificate in attestationRootCertificates) | |
| { | |
| // skip the first element, as that is the attestation cert | |
| if (chain.ChainElements | |
| .Cast<X509ChainElement>() | |
| .Skip(1) | |
| .Any(x => x.Certificate.Thumbprint == attestationRootCertificate.Thumbprint)) | |
| return true; | |
| } |
What happens in ValidateTrustChain:
-
// try to build a chain with what we've got if (chain.Build(trustPath[0]))
We disable revocation flag and allow unknown CA
On Windows we will get success + Status Untrusted Root (A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.) which is expected.
On Linux we will get success + Status Partial Chain (Unable to find local issuer)
-
// now, verify chain again with all checks turned on if (chain.Build(trustPath[0]))
This one will succeed on Windows but fail on Linux. The required item won't be added to CustomTrustStore on Linux, because "chain.ChainElements[^1].Certificate" doesn't contain it.
So we will have something like this:
if (chain.Build(trustPath[0])) // first chain build
{
if (chain.ChainStatus[0].Status == X509ChainStatusFlags.UntrustedRoot)
{
// if that validated, we should have a root for this chain now, add it to the custom trust store
chain.ChainPolicy.CustomTrustStore.Clear();
chain.ChainPolicy.CustomTrustStore.Add(chain.ChainElements[^1].Certificate);
}
else if (chain.ChainStatus[0].Status == X509ChainStatusFlags.PartialChain)
{
???
Chain is validated but we won't have a root of this chain.
}
..
}
Any ideas on how to handle PartialChain on Linux then?
PartialChain result returned by OpenSSL (which is used under the hood on Linux).
Related discussions:
dotnet/runtime#49615 (comment)
dotnet/runtime#49615
dotnet/dotnet-api-docs#6660
dotnet/runtime#29164
dotnet/runtime#28314