function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
AkoAko 

httprequest to https site throws java error

Hello,
I am the maintainer of a managed package which sends HTTP Posts to an external website configured by the customer using custom settings for the package. The messages provide integration between Salesforce and their external site which hosts scripts we provide.

We have a customer whos website the package is unable to send an httprequest to. It is an https site.

To discover the specific error I attempted a simple post via the developer console. The error is:

System.CalloutException: java.security.cert.CertificateException: No subject alternative DNS name matching customer.website.com found.
(customers website is obviously changed for this example, but I assure you it is the correct URL).

I found a forum post about this type of error here: https://developer.salesforce.com/forums/ForumsMain?id=906F0000000919hIAA

The description said this happens when the sites SSL certificate has its CN (Common Name) set to an IP address, but doesn't have a SAN (Subject Alternative Name) IP Address Record that matches the address in the CN. However after investigating the details of this customers SSL certificate in my browser (chrome), it looks like this customer's CN is NOT an IP address, it is the proper URL ("customer.website.com" in my example). So I'm not sure what the problem is.
I don't know how to tell the customer to fix their certificate, if it's possible.

Our package depends on making an httprequest to a script on an external website in order to achive the integration we provide.
Does anyone know how to prevent this error from happening?

I will paste the full code that I ran anonmously from the developer console when testing. It throws the error mentioned above. I have changed the URL of the customer's site for this example since they probably don't want me posting it in a forum.

HttpRequest req = new HttpRequest(); 
	integer debug=0;
	Map<String,String> headers = new Map<String, String>{};
	headers.put('content-type','application/x-www-form-urlencoded');

	String body='test=1';
	req.setMethod('POST');

	system.debug('content-type is >' +headers.get('content-type'));
	req.setHeader('content-type', headers.get('content-type') );

	req.setBody(body); 
	req.setCompressed(false); // otherwise we hit a limit of 32000
	req.setEndpoint('https://customer.website.com/salesforce/listenerscript.php');

	if ( ! headers.isEmpty() ) { 
		for(string k:headers.keySet() ) { 
			system.debug('setheader ' + k + ' => ' +headers.get(k) ); 
			req.setHeader(k, headers.get(k) ); 
		}
	}

	Http http = new Http();
	HttpResponse res;

	String resultString;
	String resToString;
	String resBody;
	String resStatus;
	Integer resStatusCode=0;
     
	resultString='';
	res = http.send(req);
	resToString=res.toString();
	resBody=res.getBody();
	resStatusCode = res.getStatusCode();
	resStatus = res.getStatus();
	resultString = resBody;
	System.debug(resStatusCode) ;






PrasanntaPrasannta (Salesforce Developers) 
Hi,

When an HTTPS client connects to a server, it verifies that the hostname in the certificate matches the hostname of the server. It's not enough for a certificate to be trusted, it has to match the server you want to talk to too. (As an analogy, even if you trust a passport to be legitimate, you still have to check that it's the one for the person you want to talk to, not just any passport you would trust to be legitimate.)

In HTTP, this is done by checking that:

the certificate contains a DNS subject alternative name (this is a standard extension) entry matching the hostname;

failing that, the last CN of your subject distinguished name (this is the main name if you want) matches the hostname. (See RFC 2818.)
AkoAko
Thanks for the information. From what I can see when viewing the certificate, it meets all these requirements.
The subject CN matches the hostname and the subject alternative DNS name also matches the hostname.
Could the issue be caused by a shared-hosting situation, with multiple sites on one IP address?