Search code examples
c#sslhttpskuberneteshttpwebrequest

Could not create SSL/TLS secure channel - HttpWebRequest


I am trying to make a connection to my kubernetes api and cant seem to get SSL to work from C#.

When i run the following via curl, everything seems to work as expected:

enter image description here

And I have this for c# to do the same:

try
{
    // use the TLS protocol 
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

    // create HTTP web request with proper content type
    HttpWebRequest request = WebRequest.Create(Constants.K8_API_RC_URI) as HttpWebRequest;
    request.ContentType = "application/json;charset=UTF8";
    request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + Constants.K8_TOKEN);
    // load the X.509 certificate and add to the web request
    X509Certificate cert = new X509Certificate(Constants.K8_CRT);
    request.ClientCertificates.Add(cert);

    // call the web service and get response
    WebResponse response = request.GetResponse();

    Stream responseStream = response.GetResponseStream();

    string jsonContents = new StreamReader(responseStream).ReadToEnd();
}
catch (Exception exc)
{
    // log and print out error
    log.Info(exc.Message);
}

Where

Constants.K8_CRT is the Path to ca.crt

and ca.crt contains the following:

-----BEGIN CERTIFICATE-----
MIIDMDCCAhigAwIBAgIIcwd9rrnaPcowDQYJKoZIhvcNAQELBQAwEzERMA8GA1UEAwwIYWNzazhz
and more letters.......
cwSfuIp7e49KC3HSqcU3Mz4oFNm5bw==
-----END CERTIFICATE-----

I get the following error:

Could not create SSL/TLS secure channel.

P.S. I know there are Kubernetes clients for .Net out there and I have tried just about all of them but since I am integrating this with Azure Functions most of the third party libraries do not work for various reasons.


Solution

  • The CA cert should be used to validate server cert chain, not passed as an ClientCertificate.

    Here is an example.

    ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => {
        if (errors == SslPolicyErrors.None) return true;
        X509Certificate2 serverCert = new X509Certificate2(certificate);
        X509Certificate2 caCert = new X509Certificate2(@"./ca.cert");
        chain.ChainPolicy.ExtraStore.Add(caCert);
        chain.Build(serverCert);
        foreach (var chainStatus in chain.ChainStatus) {
            if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot) continue;
            if (chainStatus.Status != X509ChainStatusFlags.NoError) return false;
        }
        return true;
    };
    
    HttpWebRequest request = WebRequest.CreateHttp("https://master:6443/api/v1");
    request.Headers[HttpRequestHeader.Authorization] = "Bearer " + "SOME_TOKEN";
    
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    var content = new StreamReader(response.GetResponseStream()).ReadToEnd();
    Console.WriteLine(content);