From 6eb55551455ec87925b8d6c22b4129bb9416d0ed Mon Sep 17 00:00:00 2001 From: David Orbelian Date: Wed, 13 Jun 2018 21:55:41 +0400 Subject: [PATCH] Fix issue with X509VerificationFlags.AllowUnknownCertificateAuthority behavior (#174) * Fix issue with X509VerificationFlags.AllowUnknownCertificateAuthority behavior * Add CertificateValidationTests --- src/KubernetesClient/Kubernetes.ConfigInit.cs | 5 +++ .../CertificateValidationTests.cs | 37 +++++++++++++++++++ tests/KubernetesClient.Tests/assets/ca2.crt | 18 +++++++++ 3 files changed, 60 insertions(+) create mode 100644 tests/KubernetesClient.Tests/CertificateValidationTests.cs create mode 100644 tests/KubernetesClient.Tests/assets/ca2.crt diff --git a/src/KubernetesClient/Kubernetes.ConfigInit.cs b/src/KubernetesClient/Kubernetes.ConfigInit.cs index 75d04c5..d991ca8 100644 --- a/src/KubernetesClient/Kubernetes.ConfigInit.cs +++ b/src/KubernetesClient/Kubernetes.ConfigInit.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Net; using System.Net.Http; using System.Net.Security; @@ -181,6 +182,10 @@ namespace k8s chain.ChainPolicy.ExtraStore.Add(caCert); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; var isValid = chain.Build((X509Certificate2) certificate); + + var rootCert = chain.ChainElements[chain.ChainElements.Count - 1].Certificate; + isValid = isValid && rootCert.RawData.SequenceEqual(caCert.RawData); + return isValid; } diff --git a/tests/KubernetesClient.Tests/CertificateValidationTests.cs b/tests/KubernetesClient.Tests/CertificateValidationTests.cs new file mode 100644 index 0000000..c81ae75 --- /dev/null +++ b/tests/KubernetesClient.Tests/CertificateValidationTests.cs @@ -0,0 +1,37 @@ +using System; +using System.IO; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using Xunit; + +namespace k8s.tests +{ + public class CertificateValidationTests + { + [Fact] + public void ValidCert() + { + var caCert = new X509Certificate2("assets/ca.crt"); + var testCert = new X509Certificate2("assets/ca.crt"); + var chain = new X509Chain(); + var errors = SslPolicyErrors.RemoteCertificateChainErrors; + + var result = Kubernetes.CertificateValidationCallBack(this, caCert, testCert, chain, errors); + + Assert.True(result); + } + + [Fact] + public void InvalidCert() + { + var caCert = new X509Certificate2("assets/ca.crt"); + var testCert = new X509Certificate2("assets/ca2.crt"); + var chain = new X509Chain(); + var errors = SslPolicyErrors.RemoteCertificateChainErrors; + + var result = Kubernetes.CertificateValidationCallBack(this, caCert, testCert, chain, errors); + + Assert.False(result); + } + } +} diff --git a/tests/KubernetesClient.Tests/assets/ca2.crt b/tests/KubernetesClient.Tests/assets/ca2.crt new file mode 100644 index 0000000..0878910 --- /dev/null +++ b/tests/KubernetesClient.Tests/assets/ca2.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIQWNOfSGBRn4EUcsj7E1UN8zANBgkqhkiG9w0BAQsFADAZ +MRcwFQYDVQQKEw5EYXZpZCBPcmJlbGlhbjAeFw0xODA2MDgxMjI2MDBaFw0yMTA1 +MjMxMjI2MDBaMBkxFzAVBgNVBAoTDkRhdmlkIE9yYmVsaWFuMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnXGK1ZHqF4fhO3WOtlo5kqVYHHYTasNmzbQh +MJ0IHiFrCVNi6apohleHi0IlzVFCQY5+yab2Lz7J2qcadRVWLlfhskMx4hbSD+eX +H9MDcnV1k4AyFz+9I+dL4rb5DPcK9vNQF0KXtdpaq4qVs+IoRR4Ck00yvzLmOMTs +YvFVjW6XgKPR+y89y8iykW2puiJ/y6DLKlP+2HDGGEI07C+4Tkxps6uRkPz6ySVb +6mhJ6P/+8WmuMc0Ur1kNgA0GEUTFYlRNuF0nNjBvncGBUwOWAUNbsYQgElaqXJKe +XZ6M44+oBvRsCsnf7j3hfKti4u/Qy9nDejJ/15R6I6A5JdYOxwIDAQABoyMwITAO +BgNVHQ8BAf8EBAMCAqwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AQEAU2Rp4T7iWomEsCC8nrQPXh/6AlVnfb/vhC7aCq+g6CF+LvksfM3Uj+JLQ5rM +QNavSXowqe11vNb1Qu7LcQT5ff76XEoK0dKA8uMs60wUkHttfPzXM522rdv+i8EF +QwVirN85W5i2q669MQ2BeJ37gQ6vQAOLvHXTuspDo1qrfT3zkeGiLEXRM4k4d6OT +BnZNYvfdTTZX7OlvHfw5hdcRtoOTBmTAh+UKJvOUIQ2g/Mp2VBxNNC5zhJHTwEXj +ssHyR24e9+GODLviep2H1uB+mHZQ5Yvzxxlkz8NTDx+mUmBSF1gGuDNdmKrCrP92 +bJZY0LcRrXX0aqPymVZrINDvtA== +-----END CERTIFICATE-----