0

I have an ssl connection(2 way handshake) and I am unable to understand the why the following code procedures 400(openJdk 11, p12 file & password provided by the server , cer file provided by the server) ,

I have created the jks file from the cer file via the following command:

keytool -importcert -file example-api.cer -keystore example-api.jks

The code

    File keyFile = new File(Objects.requireNonNull(exampleController.class.getClassLoader().
            getResource("example-client-api1.p12")).getFile());
    File trustFile = new File(Objects.requireNonNull(exampleController.class.getClassLoader().
            getResource("example-api.jks")).getFile());
    KeyStore keyStore  = KeyStore.getInstance("PKCS12");
    try(FileInputStream inStream = new FileInputStream(keyFile)) {
        keyStore.load(inStream, "password".toCharArray());
    }
    SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustFile, "password".toCharArray() ,new TrustAllStrategy()).
                            loadKeyMaterial(keyStore , "password".toCharArray()).build();
    HostnameVerifier hostnameVerifier = new NoopHostnameVerifier();
    SSLConnectionSocketFactory socketFactory =
            new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
    CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLHostnameVerifier(hostnameVerifier)
            .setSSLSocketFactory(socketFactory)
            .useSystemProperties()
            .build();
    HttpGet httpget = new HttpGet("https://example-api/link?token=@Secret_Token@");

    System.out.println("executing request" + httpget.getRequestLine());

    return  httpclient.execute(httpget);

The code above always returns 400 (No required SSL certificate was sent).

but the following curl works(on IOS):

curl https://example-api/link?token=@secret_token@ --cacert ./example-api-ca.crt --cert ./example-client-api1.p12:password

Any help would be greatly appreciated

pedrofb
  • 37,271
  • 5
  • 94
  • 142
Roie Beck
  • 1,113
  • 3
  • 15
  • 30
  • It could be that `useSystemProperties()` was using the properties of the system instead of your specific configuration. Try removing it – pedrofb Oct 28 '18 at 17:51
  • @pedrofb hi, no luck it did not help, one thing I want to add, we actually got a .crt file from the server and we converted it to Base 64 .cer file(in windows) then used the cer file,could this cause an issue? do I have to use the crt? – Roie Beck Oct 28 '18 at 19:27
  • It is needed to add the server certificate, or the CA root certificate to the truststore. It is not the issue. You have received an error managed by the server, so the SSL channel has beed stablished, but without presenting a client certificate. This issue is usually produced by a misconfiguration of the keystore containing the client certificate. Check also the file path – pedrofb Oct 28 '18 at 20:05
  • (1) what middleware is your curl build using? check `curl -V` (uppercase vee) (2) run with sysprop `javax.net.debug=ssl` and/or get a wire trace with wireshark or similar and check the CA(s) requested by the server against those in your cert's chain (in the P12 for the latter) (3) most people use suffix `.crt` for both DER and PEM (which is not _exactly_ base64) and `.cer` for DER, but MS uses both for both, and java `keytool -importcert` accepts both, plus `TrustAll` is ignoring your truststore anyway – dave_thompson_085 Oct 28 '18 at 23:17
  • @pedrofb, I have run the following: keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias test -file gravityx-api-ca.cer Warning: use -cacerts option to access cacerts keystore Certificate was added to keystore yet the problem persists. – Roie Beck Oct 29 '18 at 07:02
  • @dave_thompson_085, the working curl -V output: curl -V curl 7.54.0 (x86_64-apple-darwin16.0) libcurl/7.54.0 SecureTransport zlib/1.2.8 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz UnixSockets – Roie Beck Oct 29 '18 at 07:03
  • @dave_thompson_085 In the logs: javax.net.ssl |SunX509KeyManagerImpl.java:164|found key for : Example client api ( "certificate" : { "version" : "v1", "serial number" : "02", "signature algorithm": "SHA1withRSA", "issuer" : "CN=gravity.capital, OU=X, O=Gravity Capital, L=Sydney, C=AU", "not before" : "2018-10-03 17:25:04.000 IDT", "not after" : "2028-09-30 17:25:04.000 IDT", "subject" : "CN=api1, O=1, C=IL", "subject public key" : "RSA"} ) So it looks like it does find my key in the cacerts – Roie Beck Oct 29 '18 at 08:29
  • Update during debug I found(in the log): adding as trusted certificates ( "certificate" : { "version" : "v1", "serial number" : "02", "signature algorithm": "SHA1withRSA", "issuer" : "CN=gravity.capital, OU=X, O=Gravity Capital, L=Sydney, C=AU", "not before" : "2018-10-03 17:25:04.000 IDT", "not after" : "2028-09-30 17:25:04.000 IDT", "subject" : "CN=api1, O=1, C=IL", "subject public key" : "RSA"} ) – Roie Beck Oct 29 '18 at 16:47
  • and then: found key for : gravityx ( "certificate" : { "version" : "v1", "serial number" : "02", "signature algorithm": "SHA1withRSA", "issuer" : "CN=gravity.capital, OU=X, O=Gravity Capital, L=Sydney, C=AU", "not before" : "2018-10-03 17:25:04.000 IDT", "not after" : "2028-09-30 17:25:04.000 IDT", "subject" : "CN=api1, O=1, C=IL", "subject public key" : "RSA"} ) – Roie Beck Oct 29 '18 at 16:48
  • so if he returns a 400(no certificate ) doesn't this imply that the certificate he provided are wrong? – Roie Beck Oct 29 '18 at 16:50
  • Roie: (1) add additional info by editting the question, _especially_ when it needs formatting like these; Stack policy is that comments are transient and may be deleted (2) SecureTransport is not one of the middlewares I know, sorry (3) "found key for" means a key&cert was found in your _keystore_, not your truststore much less the default truststore cacerts -- but that doesn't mean it was _used_; I said to look at the part of the log (or trace) where the server specifies which CA(s) it wants – dave_thompson_085 Oct 30 '18 at 06:47

1 Answers1

0

OK So after Some frustrating days: I do not know the reason why but The problem was with the hyphen char ('-') in the hostName of the URL, removing hyphen sign fix the issue , not sure why , but posting it anyway, maybe someone could explain this phenomenon. Example(using the code above):

example-api -> not working
example.api -> Works OK
Roie Beck
  • 1,113
  • 3
  • 15
  • 30