Could not create SSL/TLS secure channel - HttpWebRequest

1/8/2018

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.

-- scorpion5211
c#
https
httpwebrequest
kubernetes
ssl

2 Answers

1/9/2018

Thanks for @Jimi's comments i was able to get this to work with adding the following:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
            delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                                    System.Security.Cryptography.X509Certificates.X509Chain chain,
                                    System.Net.Security.SslPolicyErrors sslPolicyErrors)
                {
                    return true; // **** Always accept
                };

NOTE: Im certain this just ignores the SSL validation and continues without it. In our case this may be acceptable.

-- scorpion5211
Source: StackOverflow

1/9/2018

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);
-- silverfox
Source: StackOverflow