5

I'm trying to convert following curl call to a Java call

curl --verbose --cert bobauth.crt --key bobauth.key https://test1.mobileticket.se/api/v1/auth/andreas

The Curl call works as I expect but when I try to do the same call in java I only get error messages. However this is how I have tried to do it, don't know if this is the best approach.

the bobauth cert was created with following command. This is the same bobauth that is used in the curl call.

openssl req -new -x509 -sha256 -days 1000 \
        -newkey rsa:2048 -nodes -keyout bobauth.key \
        -subj "/CN=anders@clonecorps.com" -out bobauth.crt

Then I create a java key store with the following code.

# Create PKCS12 keystore from private key and public certificate.
openssl pkcs12 -export -name myservercert -in bobauth.crt -inkey bobauth.key -out keystore.p12

# Convert PKCS12 keystore into a JKS keystore
keytool -importkeystore -destkeystore mykeystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -alias myservercert

This is the java code I have put together, that do not work fully.

try {
    KeyStore keyStore  = KeyStore.getInstance("JKS");
    java.io.FileInputStream fis = null;
    try {
        fis = new java.io.FileInputStream("mykeystore.jks");
        keyStore.load(fis, "password".toCharArray());
    } finally {
        if (fis != null) {
            fis.close();
        }
    }

    SSLContext sslcontext = SSLContexts.custom()
        .loadKeyMaterial(keyStore, "password".toCharArray())
        .loadTrustMaterial(null, new TrustSelfSignedStrategy())
        .build();

    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslcontext,
        SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    CloseableHttpClient client = HttpClients.custom()
        .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
        .setSSLSocketFactory(sslsf)
        .build();           

    HttpGet httpGet = new HttpGet("https://test1.mobileticket.se/api/v1/auth/andreas");

    CloseableHttpResponse response = client.execute(httpGet);           
    String responseString = new BasicResponseHandler().handleResponse(response);

    //Close and return
    client.close();
}
catch(IOException e){
    log.info("IOException: " + e.getMessage());
}catch(Exception e){
    log.info("Exception: " + e.getMessage());
}

When i run this code i get following error message

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

So if there is anyone how can see what is wrong or point me to an example how to fix it would be very appreciated.


To get access to the API i had to upload my bobauth.crt that i created.

This is what i got from running the command. openssl s_client -connect test1.mobileticket.se/api/v1/auth/andreas:443 -showcerts

CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = test1.mobileticket.se
verify return:1
---
Certificate chain
 0 s:/CN=test1.mobileticket.se
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
-----BEGIN CERTIFICATE-----
xxxx
-----END CERTIFICATE-----
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
-----BEGIN CERTIFICATE-----
xxxx
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=test1.mobileticket.se
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 3060 bytes and written 475 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: B08AD5731BAA93949683F40D6BD0189C346AF455D84985932E891768B63E94C1
    Session-ID-ctx: 
    Master-Key: 7C3EBFA054F4B5C351D3F6579777BF479405529B67AC3590C76B630D39598C118D4439267B06333574C77320108A4CCB
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1501852200
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
closed
user31267
  • 51
  • 4
  • What is the server certificate chain. It looks like you don't have server certificated trusted in cacerts file. It looks like you are using TrustSelfSignedStrategy, so is the server cert is self-signed ? Also can you run -> openssl s_client -connect test.clonecorps.com:443 -showcerts to see what cert chain you are getting from server ? – jatanp Aug 04 '17 at 11:32
  • Maybe help: https://stackoverflow.com/questions/2893819/accept-servers-self-signed-ssl-certificate-in-java-client – K.Nicholas Aug 04 '17 at 13:48
  • @jatanp+ `loadTrustMaterial(null,strategy)` doesn't load cacerts (or any other truststore) so 'self-signed' is the only thing that will work -- although at least in httpclient 4.5 (I haven't downloaded for a while) 'self-signed' doesn't actually check what it says but only received chain length == 1. And f the server uses SNI as many do nowadays, `s_client` also needs `-servername host` – dave_thompson_085 Aug 04 '17 at 13:48
  • @dave_thompson_085 yes I realised that later .. but it is better to check what chain is returned from server – jatanp Aug 04 '17 at 13:53
  • I don't know what server or resource this is, but is it wise to give access certificates and the url to the public? – Herr Derb Aug 04 '17 at 14:25
  • Well in cert chain, the last cert is not self signed but issued by DST. I think your trust policy may not work here. Can you create JKS with the intermediate cert as trusted one and use the jks to create TrustStore. – jatanp Aug 05 '17 at 12:49

0 Answers0