Search code examples
c#.netsslhttpscertificate

"The remote certificate is invalid according to the validation procedure", but only from same server call


TLDR: Webservice call through https works from another computer but from local server (itself) it gives "System.Security.Authentication.AuthenticationException, System.Net.WebException The remote certificate is invalid according to the validation procedure".

I have a website (EDIT: the website itself in not on https, just on http. It is accessed via a dns name that is bound to a website through IIS bindings.) and a webservice, both running on a server with hostname and ip-address. (I'm probably not allowed to disclose the actual names and addresses).
Corporate CA CA issued a certificate, with the following properties (among others):

Issuer: CA
Subject: CN = hostname
Subject Alternative Name: IP Address =  ip-address

I deleted the http binding in IIS for webservice, leaving only the https.

Type Host Name Port IP Address Binding Information
https 443 ip address

Website calls service using url:
https://ip-address/service.asmx
and code:

using (WebResponse webResponse = request.GetResponse()) {
    do stuff...
}

the "GetResponse()" function throws several errors in a row:

Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.Security.Authentication.AuthenticationException' in System.dll
Exception thrown: 'System.ObjectDisposedException' in System.dll
Exception thrown: 'System.Net.WebException' in System.dll
Exception thrown: 'System.Net.WebException' in System.dll

The exception message is:

The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

Inner exception:

The remote certificate is invalid according to the validation procedure.

I have an exact copy of the website - website_local, that makes a call to the same service. That makes it a remote call (from my pc to the server). And it works without exceptions. There is no http binding anymore, so there is no way the connection is not secure.

If I go to "https://ip-address/service.asmx" with Chrome from both my pc and the server it says that the connection is secure and the certificate is valid and trusted (because of CA certificate being present in "Trusted Root")

What i did so far:

  1. On a server put the certificate in both "LocalComputer\Personal" and "LocalComputer\Trusted Root Certification Authorities"
  2. Put the localhost certificate into "LocalComputer\Trusted Root Certification Authorities"(it already is present in "Personal")
  3. Ensured that CA certificate is in "LocalComputer\Trusted Root Certification Authorities"
  4. For certificate in LocalComputer\Personal did: "All tasks -> Manage private keys -> Add -> IIS_IUSRS -> Full control and Read". (localhost certificate already had that setting).
  5. Tried switching url from "https://ip-address/service.asmx" to "https://localhost/service.asmx" and "https://hostname/service.asmx" - not worked in code and Chrome (my pc and server) says, that the connection now is not secure and NET::ERR_CERT_COMMON_NAME_INVALID.

So the question is: Why the call from my local website works to the service (a remote call), but fails when the actual website makes a call to the same service (same server call)?

UPD 1: If I try to call the same service using Postman with SSL verification enabled, it says: "Unable to verify the first certificate". Why does it works in code then?
I can request another certificate from company's CA, but I need specifications.
Can someone please elaborate on that? Current certificate has both hostname and ip-address and should be valid for any service on that website, shouldn't it?


Solution

  • So this is how we finally did it:

    1. Registered a dns-name inside corporate LAN;
    2. Issued a new certificate for that specific name, without binding it to a server's ip-address;
    3. Added the new dns-name as hostname in IIS and added a new certificate.
    4. Changed the connection string to https://dns-name/service.asmx

    And it works!

    My best guess is that @zaitsman was right about why it didn't work from server itself, but worked from my pc.

    Does your certificate also have 127.0.0.1 and ::1 addresses? because most likely >when you're calling self over web underlying TCP stack just loops back after DNS >resolution.