8

I am trying to consume Client's Web Service from Web API, Below is the code we are currently using to bypass SSL certificate

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

It was working fine, until they disabled TLS 1.0 and TLS 1.1 from their end. Now we have added follwing code to use TLS 1.2 for client server connection

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

Now i am getting "The request was aborted: Could not create SSL/TLS secure channel." Error only when i am hitting the API for first time, and then getting results if i am continuously hitting the API, If i wait for some time like a minute or so, Again getting same error for first time only.

8
  • What framework are you using and where in the application do you set the ServicePointManager.SecurityProtocol? Commented Apr 19, 2019 at 12:41
  • Can you disable ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; and debug the callback to review the sslPolicyErrors? This may give you some insight into the issue. Commented Apr 19, 2019 at 12:47
  • Hi Martennis, i am using framework 4.5.2, we are using proxy class generated from wsdl and setting ServicePointManager.SecurityProtocol just before calling their method. Commented Apr 19, 2019 at 12:55
  • Hi Stinky, Debugging is not an option from us , Only one IP is whitelisted for Service, we do not have dev environment there, though i tried accessing the Service from SOAPUI 5.4.0 , getting below error for first request only there as well ERROR:javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure Commented Apr 19, 2019 at 12:59
  • @Soniya - if can't debug, how are you able to update the ServicePointManager? Commented Apr 19, 2019 at 13:01

3 Answers 3

17

Setting the security protocol type needs to be done before the issuing request is created. So this:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Should appear before this:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

So if you're seeing it work on subsequent requests, it might be that you're setting the protocol too late.

Sign up to request clarification or add additional context in comments.

3 Comments

@RushabhMaster you should accept the answer then so they get credit.
@Shane, The initial question was not initiated by me, I upvoted the answer as it worked in my case, Thanks for your comment though!
This worked for me plus one
4

The following code can be used to help troubleshoot the issue.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback += ValidateServerCertificate;

...

private static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    // If the certificate is a valid, signed certificate, return true to short circuit any add'l processing.
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;
    }
    else
    {
        // cast cert as v2 in order to expose thumbprint prop - if needed
        var requestCertificate = (X509Certificate2)certificate;

        // init string builder for creating a long log entry
        var logEntry = new StringBuilder();

        // capture initial info for the log entry
        logEntry.AppendFormat("SSL Policy Error(s): {0} - Cert Issuer: {1} - SubjectName: {2}",
           sslPolicyErrors.ToString(),
           requestCertificate.Issuer,
           requestCertificate.SubjectName.Name);

        // check for other error types as needed
        if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors) //Root CA problem
        {
            // check chain status and log
            if (chain != null && chain.ChainStatus != null)
            {
                // check errors in chain and add to log entry
                foreach (var chainStatus in chain.ChainStatus)
                {
                    logEntry.AppendFormat("|Chain Status: {0} - {1}", chainStatus.Status.ToString(), chainStatus.StatusInformation.Trim());
                }
            }
        }

        // replace with your logger
        MyLogger.Info(logEntry.ToString().Trim());
    }

    return false;
}

1 Comment

The result of returning false when use in conjunction with HttpWebRequest is a WebException with an associated Status of WebExceptionStatus.TrustFailure.
1

For those running .NET version 4, they can use below

ServicePointManager.SecurityProtocol = CType(768, SecurityProtocolType) Or CType(3072,SecurityProtocolType)
ServicePointManager.Expect100Continue = True

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.