2

When trying to call one of our external web services from Apex code, I get an error stating that it is unable to find valid certification path to requested target.

System.CalloutException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

According to google result, it seems that there is an issue validating the SSL Certificate for our service. I spoke with the admin person for that server and he told me it is not expired, verified CA through Thawte, plus other outside software is accessing it without any issues.

We also tried going to "Certificate and Key Management" in Salesforce and selected "Import from Keystore" but not sure what JKS file to import. I do have the cert file but not sure how Salesforce can use it.

Is there something we need to put into the Keystore and then import it into the organization? Do we have to create a new certificate under "Certificate and Key Management" and then use that as the certificate for our external web service?

The external web service that I'm trying to access is:

  • apps.daikinapplied.com/McQuayToolsSrvc/Authentication.asmx

Some of the operations on this service that I am using are:

  • SalesPortalUrl()
  • ValidateSession(double sessionId)
  • GetUserInfoBySessionId (double sessionId)

It works with all other .NET Applications and I also verified that it works in wcftestclient (Microsoft tool). I added the following Remote Site in Salesforce:

  • apps.daikinapplied.com

On the Developer Console, I tested access with the following code which produces the exception error:

Http h = new Http();  
HttpRequest req = new HttpRequest();  
req.setMethod('POST');  
req.setHeader('Accept-Encoding','gzip,deflate');  
req.setHeader('Content-Type','text/xml;charset=UTF-8');  req.setEndpoint('apps.daikinapplied.com/McQuayToolsSrvc/Authentication.asmx');  

// NOTE: For the requestString variable below the editor here wouldn't let me add the < symbol in front of the tags. Not sure why

String requestString = 'soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' +
  'soap:Body>' +
    'SalesPortalUrl xmlns="http://tempuri.org/" />' +
  '/soap:Body>' +
'/soap:Envelope>';  

req.setHeader('Content-Length',String.valueOf(requestString.length()));   

req.setBody(requestString);  
HttpResponse res = h.send(req);  
string bodyRes=res.getBody();  
System.debug(bodyRes);  

Any help you can provide would be appreciated!

3
  • Please add all this to your question and not as comments. The formatting of the comments makes it extremely difficult to effectively read and understand what you are saying when it comes to the code
    – Eric
    Commented Nov 12, 2015 at 23:18
  • I do not think you understand - ADD IT TO THE QUESTION - not as a comment
    – Eric
    Commented Nov 13, 2015 at 4:47
  • Kent could you update the question to contain the additional info rather than comment ? Commented Nov 13, 2015 at 14:29

2 Answers 2

4

I believe the problem is different. In salesforce you can talk to only those servers which includes digital certificates which are signed by Certificate Authorities to which salesforce trusts. Here certificate authority for your endpoint- https://apps.daikinapplied.com/McQuayToolsSrvc/Authentication.asmx is "Kaspersky Antivirus Personal Root Certificate". This is not listed as trusted certificate in the list provided by Salesforce. https://developer.salesforce.com/page/Outbound_Messaging_SSL_CA_Certificates#addtrustclass1ca Also if you check at https://www.digicert.com/help/

2: https://www.digicert.com/help/ your endpoints certificate is not trusted one. Attached image for your reference. So solution would be to ask your integration party to have a certificate installed which is signed by CA to which salesforce trusts.enter image description here Let me know if this helps.

2
  • Thank you for your answer. I will have the admin for the server check this out as well! Commented Nov 17, 2015 at 18:58
  • Hi Kent, Can you upvote this answer so that other developers could also get benefited. Let me know if you need any help on this. Commented Nov 17, 2015 at 19:02
1

Thank you for posting the hostname of the server you were trying to connect to, it makes debugging this easier.

It looks like the server is currently configured to respond to SSL2, SSL3, and TLS1.0.

This is most likely the reason for your issue. On apex callouts, salesforce will look to connect over TLS1.1 or TLS1.2. Ideally, you would enable TLS1.1 and/or TLS1.2 on this server and disable the other protocols.

The salesforce documentation goes into further detail:

There are two methods to configure the remote endpoints:

  1. Configure TLS settings to support TLS 1.1, TLS 1.2 and SNI. This would be the ideal case and prevent any handshake failures.

  2. If customers can only enable TLS 1.0 and not the higher versions, then the remote endpoints should be configured to respond with a TLS 1.0 ServerHello instead of throwing an error, when it receives a ClientHello from us with one of the higher protocols. This method of re-negotiation is the only option as we do not have any rollback options on the upcoming change.

Salesforce will continue support TLS 1.0, but for TLS 1.0 to be negotiated, the remote server needs to respond as per the second method mentioned above. If the endpoint does not follow TLS standards in this regard and, instead, is configured to respond with an error when it receives a "TLS 1.1/1.2 ClientHello," they will start seeing handshake failures.

1
  • Thank you, I will notify our admin and relay this information to him and see if it works. Commented Nov 13, 2015 at 13:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .