There is a behavioural difference: it you add a self-signed certificate into "Trusted Publishers" on a Windows machine then self-signed certificates are accepted, but on Linux machines they still error.
System.Net.Security.SecureChannel:VerifyRemoteCertificate
If CompleteHandshake fails then the error is thrown:
SR.net_ssl_io_cert_validation "The remote certificate is invalid according to the validation procedure."
CompleteHandshake calls VerifyRemoteCertificate
SecureChannel.VerifyRemoteCertificate returns false if the certificate cannot be validated.
It calls CertificateValidationPal.GetRemoteCertificate and then CertificateValidationPal....
At this point the logic forks depending upon the OS.
CertificateValidationPal.VerifyCertificateProperties is in CertificateValidationPal.Unix.cs.
For Unix, this calls the CertificateValidation.BuildChainAndVerifyProperties.
This is in CertificateValidation.Unix.cs.
The X509Chain is built. It returns a ChainPal and runs BuildChain on it.
A linux ChainPal is returned.
It then runs the OpenSslX509ChainProcessor and runs BuildChain.
This has recursion as it enumerates the chain. It has a timeout to ensure the loading of certificates does not take too long.
The OpenSslX509ChainProcessor is run, and it runs the Pal.Unix/ChainVerifier.cs.
This runs HasUnsuppressedError which checks for errors that have not been surpressed. This includes checking for self-signed certificates.
OpenSSL build_chain will check for self signed certificates which has a return value of 18.
In OpenSSL, a self-signed certificate has a chain of 1.
Running
openssl s_client -showcerts -verify 5 -connect cosmosdb.test:8081
against a server will retun
Debian ca-certificates notes.
Verify return code: 18 (self signed certificate)
In the dotnet core implhementation for Unix, Self-signed is when the subject name is the same as the issuer name (see code). Errors can occur because the peer trust is only supported for Windows certificate stores. Some of this is discussed here.
Having a self-signed certificate raises the X509VerificationFlags.IgnoreRootRevocationUnknown flag which needs to be surpressed, otherwise an error is returned.
This is a subtle difference from the standard Linux implementation of dotnet core; in dotnet core Self-signed is when the subject name is the same as the issuer name (see code).
If you have running Windows and a self-signed certificate in the Trusted Publishers store, then dotnet core will respect it and not throw an error. If you are running the same code on Linux and have installed the self-signed certificate into the ca-certificates store, it will throw an error.
The X509 Store differs by platform.
The LocalMachine\Root store on Linux is an interpretation of the CA bundle in the default path for OpenSSL. The LocalMachine\Intermediate store on Linux is an interpretation of the CA bundle in the default path for OpenSSL. The CurrentUser\Intermediate store on Linux is used as a cache when downloading intermediate CAs by their Authority Information Access records on successful X509Chain builds.
No comments:
Post a Comment