diff options
author | kryssb <52244188+kryssb@users.noreply.github.com> | 2021-03-11 18:41:49 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-11 18:41:49 +0300 |
commit | 1ef655bc0da2477e248492a93e636637f8223d03 (patch) | |
tree | 60c1d44b455359a83f5a0bba04830128b40de201 | |
parent | 568ce9eb9f0e75bd228cccacc13634a0462e8d7e (diff) |
Allow sending intermediate certificates with SslStream.AuthenticateAsServer. (#20863)
* Allow sending intermediate certificates when authenticating as server
When using SslStream.AuthenticateAsServer, the incoming certificate will be an X509Certificate(2). It will never have the "intermediate" certificates attached. The chain of intermediate certificates needs to be rebuilt on the fly.
* Fix missing "using".
* Update MonoBtlsContext.cs
* Fix indentation and whitespace
Co-authored-by: Alexander Köplinger <alex.koeplinger@outlook.com>
-rw-r--r-- | mcs/class/System/Mono.Btls/MonoBtlsContext.cs | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/mcs/class/System/Mono.Btls/MonoBtlsContext.cs b/mcs/class/System/Mono.Btls/MonoBtlsContext.cs index 06136f61156..5b8b725b644 100644 --- a/mcs/class/System/Mono.Btls/MonoBtlsContext.cs +++ b/mcs/class/System/Mono.Btls/MonoBtlsContext.cs @@ -30,6 +30,7 @@ extern alias MonoSecurity; using System; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Security.Cryptography.X509Certificates; @@ -165,12 +166,28 @@ namespace Mono.Btls ssl.SetCertificate (privateCert.X509); ssl.SetPrivateKey (privateCert.NativePrivateKey); var intermediate = privateCert.IntermediateCertificates; - if (intermediate == null) - return; - for (int i = 0; i < intermediate.Count; i++) { - var impl = (X509CertificateImplBtls)intermediate [i]; - Debug ("SetPrivateCertificate - add intermediate: {0}", impl); - ssl.AddIntermediateCertificate (impl.X509); + + if (intermediate == null) { + /* Intermediate certificates are lost in the translation from X509Certificate(2) to X509CertificateImplBtls, so we need to restore them somehow. */ + var chain = new System.Security.Cryptography.X509Certificates.X509Chain (false); + /* Let's try to recover as many as we can. */ + chain.ChainPolicy.RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck; + chain.Build (new System.Security.Cryptography.X509Certificates.X509Certificate2 (privateCert.X509.GetRawData (MonoBtlsX509Format.DER), "")); + var elems = chain.ChainElements; + for (int j = 1; j < elems.Count; j++) + { + var cert = elems[j].Certificate; + /* If self-signed, it's a root and should not be sent. */ + if (cert.SubjectName.RawData.SequenceEqual (cert.IssuerName.RawData)) break; + ssl.AddIntermediateCertificate (MonoBtlsX509.LoadFromData(cert.RawData, MonoBtlsX509Format.DER)); + } + } + else { + for (int i = 0; i < intermediate.Count; i++) { + var impl = (X509CertificateImplBtls)intermediate [i]; + Debug ("SetPrivateCertificate - add intermediate: {0}", impl); + ssl.AddIntermediateCertificate (impl.X509); + } } } |