1

I am using a custom private CA and want to communicate between two services, both using a custom certificate. However, I am getting an error that I don't understand

So on both services, I have set up a truststore with the private CA and a separate keystore with the certificate it identifies itself as. Going to a simple /hello route in a browser shows that the connection is secure (i.e the issuer is known and the common name is valid). This is the same when I curl -iv https://{address}, it says that the handshake passed saying 'SSL certificate verify ok' and that the domain matched the wildcard name on the certificate.

However, when I try to do a simple GET request from the separate service, which is set up in the exact same way, I get the error listed in the title. The problem is that it says the certificate for the service I'm trying to contact cannot match any of the subject alternative names in its certificate to the domain it is registered on. But that is just absolutely incorrect, the only difference is that it uses a wildcard. This works from a browser AND the curl command which debugs the handshake. It just doesn't from my Java/Spring Boot code on the separate microservice.

Does Java work differently in a stricter way that means it doesn't like to contact servers with wildcard certificates?

EDIT: Adding the line shown below fixes this, so it's failing at hostname verification in Java (but not on a browser or debugging using curl). This is insecure so it's not THE solution.

SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(truststore, null).build();
HostnameVerifier hostnameVerifier = new NoopHostnameVerifier(); // I added this line, but it's advised against as it's insecure
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
E_net4
  • 27,810
  • 13
  • 101
  • 139
Tim
  • 213
  • 3
  • 9
  • Possibly apropos: https://stackoverflow.com/questions/7615645/ssl-handshake-alert-unrecognized-name-error-since-upgrade-to-java-1-7-01 Java is very strict about its SSL implementation. If the server you're trying to connect to doesn't properly and fully support SNI, that can cause this problem. – Andrew Henle Nov 06 '19 at 13:37
  • Is the second square brackets at the end of the exception is a typo? If not, defined SANs needs to be checked on the certificate :) – korayguney Nov 06 '19 at 13:46

1 Answers1

1

So I managed to fix this by adding my own HostnameVerification method. I used this as an example https://raw.githubusercontent.com/masover/wildcard-hostname-verifier/master/src/net/forkbox/weblogic/WildcardHostnameVerifier.java

Tim
  • 213
  • 3
  • 9
  • This seems to take into account only the Subject, and not the SAN extension. – Patrick Mevzek Nov 06 '19 at 17:03
  • @PatrickMevzek this is fine for me. Although the error framed it that way, I dont have any SAN extensions. Just the one common name. – Tim Nov 07 '19 at 13:32
  • Yes, but in many cases, like HTTPS, clients do not care too much/at all with what is in the CN, only the SAN. Said differently: you may encounter certificates where the only useful parts are in the SAN. If things work for you right now, this is great, my comment was just to alert future readers that the following code misses part of the problem and basically does not follow the algorithm outlined at RFC 6125 §6 and notably §6.4.4: "the client MAY as a last resort check for a string whose form matches that of a fully qualified DNS domain name in a Common Name field of the subject field" – Patrick Mevzek Nov 07 '19 at 15:40