Verifying an assumption around possible problem areas in SSL handshake

L

ljnelson

Please tell me if the following set of statements taken together is
true.

When you initiate an HTTPS connection via the JDK, the SSL handshake
dance commences. A certificate is offered up to the client by the
server endpoint of the connection. The client must then determine
whether to trust the certificate. It does so by looking in its
configured keystore, which is cacerts by default. If the certificate
itself, or if the chain of other certificates that vouch for it, is in
this database, then the handshake completes and everyone is happy. If
the certificate or its "vouchers" is not in the cacerts database, then
you get an exception.

Therefore, if I am getting a "no trusted certificate found" exception,
the problem MUST lie in the keystore/cacerts database configured for
the current VM.

(And finally, a corollary:)

There is one configured keystore per VM. Its location may be set via a
system property whose name escapes me at the moment; I think it's
something like javax.net.ssl.keystore. One cannot set a keystore per
connection or anything like that.

Yes?

I ask the question because we are seeing a certificate be accepted just
fine when we run on one server, and be rejected when run on another.
The code and runtime environments are identical. The one thing I can't
vouch for is the trust store in both places. However, I *can* vouch
for the fact that the certificate in question is vouched for by
Verisign, and I was under the impression that Verisign's stuff was
shipped by default as part of the JDK; hence no manual importing would
be needed.

(For whatever it's worth, this is on a JBoss 3.2.6/Tomcat setup; my
current working hypothesis is that setting the keystore on Tomcat
incorrectly sets the *VM wide* notion of where the keystore is, so that
an EJB later on--from which my HTTPS connection is initiating--is
referring to a rather anemic keystore. This is just a wild hunch.)

Thanks,
Laird
 
V

vjg

Please tell me if the following set of statements taken together is
true.

When you initiate an HTTPS connection via the JDK, the SSL handshake
dance commences. A certificate is offered up to the client by the
server endpoint of the connection. The client must then determine
whether to trust the certificate. It does so by looking in its
configured keystore, which is cacerts by default. If the certificate
itself, or if the chain of other certificates that vouch for it, is in
this database, then the handshake completes and everyone is happy. If
the certificate or its "vouchers" is not in the cacerts database, then
you get an exception.

Therefore, if I am getting a "no trusted certificate found" exception,
the problem MUST lie in the keystore/cacerts database configured for
the current VM.

(And finally, a corollary:)

There is one configured keystore per VM. Its location may be set via a
system property whose name escapes me at the moment; I think it's
something like javax.net.ssl.keystore. One cannot set a keystore per
connection or anything like that.

Yes?

I ask the question because we are seeing a certificate be accepted just
fine when we run on one server, and be rejected when run on another.
The code and runtime environments are identical. The one thing I can't
vouch for is the trust store in both places. However, I *can* vouch
for the fact that the certificate in question is vouched for by
Verisign, and I was under the impression that Verisign's stuff was
shipped by default as part of the JDK; hence no manual importing would
be needed.

(For whatever it's worth, this is on a JBoss 3.2.6/Tomcat setup; my
current working hypothesis is that setting the keystore on Tomcat
incorrectly sets the *VM wide* notion of where the keystore is, so that
an EJB later on--from which my HTTPS connection is initiating--is
referring to a rather anemic keystore. This is just a wild hunch.)

Thanks,
Laird
Depending upon the version of the JDK you have installed (I know you
said they were identical... but then you said you couldn't vouch for
identical keystores, so...) you may be running into this problem in
which the Verisign root certificate shipped with certain versions of
the JRE/JVM are expired.

http://sunsolve.sun.com/search/document.do?assetkey=1-26-57436-1
 
L

ljnelson

vjg said:
Depending upon the version of the JDK you have installed (I know you
said they were identical... but then you said you couldn't vouch for
identical keystores, so...) you may be running into this problem in
which the Verisign root certificate shipped with certain versions of
the JRE/JVM are expired.

Thanks; no, that's not the problem. We actually unpack the JDKs into
both servers from the same distribution kit.

Any opinion on the one-keystore-per-VM statement (or the others)?

Thanks again,
Laird
 
E

EJP

... If the certificate itself, or if the chain of other certificates that vouch for it, is in
this database, then the handshake completes and everyone is happy. If
the certificate or its "vouchers" is not in the cacerts database, then
you get an exception.
Yep.

Therefore, if I am getting a "no trusted certificate found" exception,
the problem MUST lie in the keystore/cacerts database configured for
the current VM.

True except that this file is not a keystore, it is a 'truststore'. A
keystore is a source for your *own* certificate when sent to others,
e.g. it is where the server gets *its* certificate from. An incoming
cert is checked against the local *truststore*. It's important to keep
this straight.
There is one configured keystore per VM. Its location may be set via a
system property whose name escapes me at the moment; I think it's
something like javax.net.ssl.keystore. One cannot set a keystore per
connection or anything like that.

*If* you take the system properties approach this is true. The property
names are javax.net.ssl.keystore and javax.net.ssl.truststore depending
on whether you mean the keystore or the truststore: see above.

*However* by initializing your own SSLContext you can use one or more
key/truststores *per context* and each context can be used to form any
number of SSLSockets and SSLServerSockets, which leads to the conclusion
that *via SSLContext.init()* you can use as many key/truststores as you
like. This might or might not be what Tomcat does, I have no
information. In any case using this approach doesn't invalidate the
system-properties approach above, it doesn't affect it in any way.
I ask the question because we are seeing a certificate be accepted just
fine when we run on one server, and be rejected when run on another.
The code and runtime environments are identical. The one thing I can't
vouch for is the trust store in both places. However, I *can* vouch
for the fact that the certificate in question is vouched for by
Verisign, and I was under the impression that Verisign's stuff was
shipped by default as part of the JDK; hence no manual importing would
be needed.

I assume this means you're running the same server code on two different
hosts and only one of them works. This would suggest that there are
different *keystores* in both servers and that they contain *different*
server certificates, only one of which is trusted by your cacerts
file(s). You can look at both keystores with the 'keytool' tool to see
their certs, expiries, signer chains, &c. You can also trace the
keystore activity at the server via -Djava.net.debug=ssl,keymanager, and
the truststore activity at the client via -Djava.net.debug=ssl,trustmanager.

EJP
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top