views:

1691

answers:

3

I am trying to use the (java) keytool to create a self signed certificate but when I attempt to use it I get the following exception (see bottom for entire exception).

...<5 more exceptions above this>
Caused by: sun.security.validator.ValidatorException: No trusted certificate found
        at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:304)
        at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:107)
        at sun.security.validator.Validator.validate(Validator.java:203)
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
        at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
        ... 22 more

I know that I can by-pass this with this code:

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

HostnameVerifier hv = new HostnameVerifier() {
    public boolean verify(String urlHostName, SSLSession session) {
        System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
        return true;
    }
};

HttpsURLConnection.setDefaultHostnameVerifier(hv);

(source)

But I am not interested in this solutions because I think that it creates a security hole. (please correct me if I am wrong).

Can anyone point me in the right direction? I am testing locally at the moment right now so it is pretty easy to change things. I have access to the server code, client code and to the .keystore file.

Update

I was attempting to use one .keystore file for both the client and server but in hopes of simplifying my issues I have created server.keystore (see below) and client.truststore (see below). I am reasonably confident that the certicates are correct but if someone could verify I would be grateful.

server.keystore

hostname[username:/this/is/a/path][711]% keytool -list -keystore server.keystore -v
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: hostname
Creation date: Feb 4, 2010
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname
Issuer: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname
Serial number: 4b6b0ea7
Valid from: Thu Feb 04 13:15:03 EST 2010 until: Wed May 05 14:15:03 EDT 2010
Certificate fingerprints:
         MD5:  81:C0:3F:EC:AD:5B:7B:C4:DA:08:CC:D7:11:1F:1D:38
         SHA1: F1:78:AD:C8:D0:3A:4C:0C:9A:4F:89:C0:2A:2F:E2:E6:D5:13:96:40
         Signature algorithm name: SHA1withDSA
         Version: 3


*******************************************
*******************************************

client.truststore

hostname[username:/this/is/a/path][713]% keytool -list -keystore client.truststore -v
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: mykey
Creation date: Feb 4, 2010
Entry type: trustedCertEntry

Owner: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname
Issuer: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname
Serial number: 4b6b0ea7
Valid from: Thu Feb 04 13:15:03 EST 2010 until: Wed May 05 14:15:03 EDT 2010
Certificate fingerprints:
         MD5:  81:C0:3F:EC:AD:5B:7B:C4:DA:08:CC:D7:11:1F:1D:38
         SHA1: F1:78:AD:C8:D0:3A:4C:0C:9A:4F:89:C0:2A:2F:E2:E6:D5:13:96:40
         Signature algorithm name: SHA1withDSA
         Version: 3


*******************************************
*******************************************

Update

I thought it could be useful to include the entire exception:

javax.xml.soap.SOAPException: java.io.IOException: Could not transmit message
        at org.jboss.ws.core.soap.SOAPConnectionImpl.callInternal(SOAPConnectionImpl.java:115)
        at org.jboss.ws.core.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:66)
        at com.alcatel.tpapps.common.utils.SOAPClient.execute(SOAPClient.java:193)
        at com.alcatel.tpapps.common.utils.SOAPClient.main(SOAPClient.java:280)
Caused by: java.io.IOException: Could not transmit message
        at org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:192)
        at org.jboss.ws.core.client.SOAPRemotingConnection.invoke(SOAPRemotingConnection.java:77)
        at org.jboss.ws.core.soap.SOAPConnectionImpl.callInternal(SOAPConnectionImpl.java:106)
        ... 3 more
Caused by: org.jboss.remoting.CannotConnectException: Can not connect http client invoker. sun.security.validator.ValidatorException: No trusted certificate found.
        at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:368)
        at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:148)
        at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:141)
        at org.jboss.remoting.Client.invoke(Client.java:1858)
        at org.jboss.remoting.Client.invoke(Client.java:718)
        at org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:171)
        ... 5 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1584)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:877)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1116)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1100)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:402)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:857)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
        at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:288)
        ... 10 more
Caused by: sun.security.validator.ValidatorException: No trusted certificate found
        at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:304)
        at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:107)
        at sun.security.validator.Validator.validate(Validator.java:203)
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
        at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
        ... 22 more
A: 

I don't get it. Are you using the server key store with the client? What is your use case exactly? Are you trying to setup mutual authentication?

If yes, you're on the wrong path here. You'll need a client key store (for the client's self-signed certificate and private key) and a client trust store (for the server's "stand-alone" self-signed certificate i.e. without its private key). Both are different from the server key store.

Pascal Thivent
I thought that I could use the server's keystore with the client for testing. This would ensure that the client has the servers certificate. Although maybe the client does need its own self signed certificate...
sixtyfootersdude
AS I said, it depends on what you want to do (which is not clear to me). If you want to implement mutual authentication, the client needs its certificate too. And in that case, I don't think that you can use the server key store as client trust store.
Pascal Thivent
+1  A: 

You would need to "establish trust" between your server and client (I'm assuming you only need to do server-side authentication). This is because you use self-signed certs. That involves importing your server's cert into the client trust store:

On the server side:

keytool -keystore <keystore file> -alias <alias> -export <certfilename>.cert

Copy the .cert file over to the client side and then:

keytool -keystore <truststore file> -alias <alias> -import <certfilename>.cert
Armadillo
+1: Thanks for the clear answer. I am pretty sure that this what I am doing **Except** I am setting both the client and the server to use the same keystore file. Ie: server.keystore. I beleave that the keystore can act as both a keystore and truststore. I am using mine to be both the server's and the client's keystore and truststore. Is this legal?
sixtyfootersdude
I haven't tried that configuration myself but it *may* work. You would have to use different aliases for the key material and the cert as they serve different purposes (and both have to be there). It seems that you are aware that this setup is only good for testing purposes and not production...
Armadillo
Meaning that I would have to have one trustedCertEntry and one privateKeyEntry in my one .keystore file? If I continue to have problems I will try to create a separate .keystore file for the client. Thanks for your assistance.
sixtyfootersdude
Armadillo, Thanks for the feedback, I added an update in the question. I think it is better to move to a simpler configuration (one keystore for server, one truststore for client) as you suggested. However I am still getting the same exception. Maybe now that I have a clearer example (above) it will be easier to identify my problem.
sixtyfootersdude
Not sure this is the actual problem, but you have clientAuth="true" in your 8443 port connector. That would require trust to also be established in the other direction (client -> server). Your 443 port does not have that. Which is your requirement?
Armadillo
Hi Armadillo, I changed that to false but I still have the same exception. Thanks for the pointer
sixtyfootersdude
OK. So can you post your client code so that I can take a look?Also, can you point your browser at the same port? What do you get? (you should be able to query for the WSDL of your web service)
Armadillo
You question lead me to an interesting observation. My client was attempting to access: https://sco-up:443/common/ws/A2. But I was curious if that was the problem. I changed that address to https://sco-up:443/asdfasdhahdhadsfkjlasd (ie garbage). And I got the same exception. This seems very odd to me. Going to look into this.
sixtyfootersdude
In response to you question if I navigate to https://sco-up:443/common/ws/A2 in a browser I get plain text: "HTTP GET not supported". (Which I think seems logical). If I navigate to https://sco-up:443/asdfasdfkd/asdfads: I get some kind of html table with title: "HTTP Status 404 - /asdfasdfkd/asdfadsf".
sixtyfootersdude
How should I be able to query the WSDL for web service? Should I be able to do this even if it is in httpS ? Thanks and happy friday.
sixtyfootersdude
Actually, I was making a dumb mistake. I was not restarting my server properly so it was not rereading the keystores. Thanks for all the help have a great weekend.
sixtyfootersdude
+1  A: 

You mustn't do that. A keystore is strictly private. If you leak it to anybody you have fatally compromised security. There is no point in doing this kind of thing just to get it working, because it isn't working - it is just a security breach. You have to do it right: export from the server's keystore into the client's truststore, and from the client's keystore if any to the server's keystore.

EJP