tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Don Flinn <fl...@alum.mit.edu>
Subject Re: Trying to understand How Tomcat uses Keystore for SSL
Date Mon, 27 Nov 2017 15:47:04 GMT
Hi Joleen,

My previous mail was cryptic.  Below is a fuller explanation of what I did
to get things running.

First, I'm using Tomcat 9 and the protocol for the Tomcat 8.5 and up has
been expanded.  Chris suggested that I use PKCS12 rather than JDK keystore,
which I have done. I'm also using the APR configuration.  So redirected
connector that I'm using looks like:

<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443" maxThreads="150" SSLEnabled="true">

<SSLHostConfig>
         keystoreType="PKCS12"
<Certificate certificateKeyFile="C:/users/don/Security/domain.key"
certificateFile="C:/users/don/Security/domain-chain.crt"
certificateChainFile="C:/users/don/Security/ICDTrustRoot.crt"
type="RSA" />
</SSLHostConfig>

</Connector>

The domain key is the private key I used when getting the certificates from
letsencrypt.  The certificate I got from letsencrypt I called
domain-chain.crt. Lastly I downloaded the ICDTrustRoot.crt from the
letsencrypt at https://letsencrypt.org/certificates.  You will notice that
I'm using Window's syntax, which is just for the pathname where the
certificates live.  You would use a Linux path syntax if you are running
Linux.  You need three certificates for letsencrypt; a cert for your
domain, one for the intermediate and finally the root certificate.

What I call domain-chain.crt holds two certificates; my domain certificate
and the intermediate.  In order to see what these were I separated them in
a text editor and called them domaincert1.crt and the second domaincert2.crt
Then I used openssl to see what was in them.  For example:

openssl x509 -noout -subject -issuer -in domaincert1.crt
this printed out
subject= /CN=info.finwoks.com
issuer= /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3

So that one was my domain cert issued by the letsencrypt intermediate

The second one certificate gave
subject= /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
issuer= /O=Digital Signature Trust Co./CN=DST Root CA X3

which is the intermediate.

I downloaded the certificates using the java program mentioned in my
previous e-mail. Depending on your particular setup, you can get the four
items using different methods.  I would suggest that you check what the
various certificates contain by using the ssl commands. I've also read that
the order of the certificates should be

Your domain
Intermediate
Known Root

So that's the order I used.  A caution, in my reading I have found some
directions not to be accurate.

If what I have written is not clear, please let me know and I'll try to
clear it up.

Don




On Mon, Nov 27, 2017 at 5:52 AM, Joleen Barker <oldenuf2nobtr@gmail.com>
wrote:

> Hello Don,
>
> I'm trying to understand these as well. I had a question regarding the data
> and commands you used to display the certificate information. You wrote
> that you used the following command to create a pkcs12 store:
>
> openssl pkcs12 -export -in "domain-chain.crt" -inkey "domain.key" -certfile
> "ICDTrustRoot.crt" -out "MM.p12" -name tomcat -passout "pass:changeit"
>
> To display the 2 certs you show one example command to see the first one
> as:
>
> openssl x509 -noout -subject -issuer -in domaincert1.crt subject= /CN=
> info.finwoks.com issuer= /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority
> X3
>
> Where did the "domaincert1.crt" come from? I did not see anything in the
> first command reference this and I was not sure how someone would know this
> name and the second one called domaincert2.crt.
>
> Thank you,
>
> Joleen
>
> On Sun, Nov 26, 2017 at 10:35 PM, Don Flinn <flinn@alum.mit.edu> wrote:
>
> > IT WORKS!!!!
> >
> > My next question is whether the Tomcat team would want this Java program
> > that does the heavy lifting for letsencrypt, which I would be happy to
> > clean up and make available as open source.  The guts of the program
> comes
> > from -  http://acme4j.shredzone.org, which is under the Apache license.
> >
> > I've made a number of enhancements, e;g. a GUI front end; the ability to
> do
> > the letsencrypt authorization without any user intervention; the ability
> to
> > sit on an admin node retrieve and install the retrieved letsencrypt SSL
> > certificates on a remote tomcat node.
> >
> > If the answer is yes, let me know the procedure to make it available as
> > open sourcce.
> >
> > Don
> >
> > On Sun, Nov 26, 2017 at 4:54 PM, Don Flinn <flinn@alum.mit.edu> wrote:
> >
> > > Didn't read closely enough.  The protocol that I used is no longer
> > > applicable for Tomcat 9.
> > >
> > > Don
> > >
> > > On Sun, Nov 26, 2017 at 3:15 PM, Don Flinn <flinn@alum.mit.edu> wrote:
> > >
> > >> Chris
> > >>
> > >> Thank you for your excellent reply and references.
> > >>
> > >> I've been doing a lot of reading on SSL, certificates, keys,
> algorithms,
> > >> etc. Woo!  However I still don't have it correct.
> > >>
> > >> I've retrieved certificates from letsencrypt and following your
> > >> suggestions did the following.
> > >>
> > >> Created a pkcs12 store using the following command line.
> > >> openssl pkcs12 -export -in "domain-chain.crt" -inkey "domain.key"
> > >> -certfile "ICDTrustRoot.crt" -out "MM.p12" -name tomcat -passout
> > >> "pass:changeit"
> > >>
> > >> where the domain-chain.crt contains two certificates  and ICDTrustRoot
> > >> contains one as shown below -
> > >> PS C:\users\don\security\letsenc5> openssl x509 -noout -subject
> -issuer
> > >> -in domaincert1.crt       (the first cert in domain-chain.crt)
> > >> subject= /CN=info.finwoks.com
> > >> issuer= /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
> > >>
> > >> PS C:\users\don\security\letsenc5> openssl x509 -noout -subject
> -issuer
> > >> -in domaincert2.crt     (the second cert in domain-chain.crt)
> > >> subject= /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
> > >> issuer= /O=Digital Signature Trust Co./CN=DST Root CA X3
> > >>
> > >> PS C:\users\don\security\letsenc4> openssl x509 -noout -subject
> -issuer
> > >> -in ICDTrustRoot.crt
> > >> subject= /O=Digital Signature Trust Co./CN=DST Root CA X3
> > >> issuer= /O=Digital Signature Trust Co./CN=DST Root CA X3
> > >> so I have the three certificates and the private key which is shared
> > with
> > >> letsencrypt called domain.key
> > >> My server.xml contains:
> > >> <Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
> > >>            sslImplementationName="org.apache.tomcat.util.net.
> openssl.O
> > >> penSSLImplementation"
> > >>            port="8443"  maxThreads="200"
> > >>    scheme="https" secure="true" SSLEnabled="true"
> keystoreType="PKCS12"
> > >>    keystoreFile="/users/don/Security/MM.p12" keystorePass="changeit"
> > >>                   clientAuth="false" sslProtocol="TLS"
> > >>    />
> > >>
> > >> However when I restart Tomcat is get the following error in the Tomcat
> > >> error log and of course it fails in the handshake with the browser
> > >>
> > >> org.apache.catalina.core.StandardService.initInternal Failed to
> > >> initialize connector [Connector[HTTP/1.1-8443]]
> > >>  org.apache.catalina.LifecycleException: Failed to initialize
> component
> > >> [Connector[HTTP/1.1-8443]]
> > >> at org.apache.catalina.util.LifecycleBase.init(
> LifecycleBase.java:112)
> > >> at org.apache.catalina.core.StandardService.initInternal(Standa
> > >> rdService.java:549)
> > >> at org.apache.catalina.util.LifecycleBase.init(
> LifecycleBase.java:107)
> > >> at org.apache.catalina.core.StandardServer.initInternal(Standar
> > >> dServer.java:873)
> > >> at org.apache.catalina.util.LifecycleBase.init(
> LifecycleBase.java:107)
> > >> at org.apache.catalina.startup.Catalina.load(Catalina.java:606)
> > >> at org.apache.catalina.startup.Catalina.load(Catalina.java:629)
> > >> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > >> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> > >> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> > >> at java.lang.reflect.Method.invoke(Unknown Source)
> > >> at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:311)
> > >> at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:494)
> > >> Caused by: java.lang.UnsatisfiedLinkError:
> > org.apache.tomcat.jni.Pool.cre
> > >> ate(J)J
> > >> at org.apache.tomcat.jni.Pool.create(Native Method)
> > >> at org.apache.tomcat.util.net.openssl.OpenSSLEngine.<clinit>(Op
> > >> enSSLEngine.java:75)
> > >> at org.apache.tomcat.util.net.openssl.OpenSSLUtil.getImplemente
> > >> dProtocols(OpenSSLUtil.java:61)
> > >> at org.apache.tomcat.util.net.SSLUtilBase.<init>(SSLUtilBase.java:46)
> > >> at org.apache.tomcat.util.net.openssl.OpenSSLUtil.<init>(OpenSS
> > >> LUtil.java:41)
> > >> at org.apache.tomcat.util.net.openssl.OpenSSLImplementation.get
> > >> SSLUtil(OpenSSLImplementation.java:36)
> > >> at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSs
> > >> l(AbstractJsseEndpoint.java:82)
> > >> at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:261)
> > >> at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEnd
> > >> point.java:798)
> > >> at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:547)
> > >> at org.apache.coyote.http11.AbstractHttp11Protocol.init(Abstrac
> > >> tHttp11Protocol.java:66)
> > >> at org.apache.catalina.connector.Connector.initInternal(Connect
> > >> or.java:1010)
> > >> at org.apache.catalina.util.LifecycleBase.init(
> LifecycleBase.java:107)
> > >> ... 12 more
> > >>
> > >> I'm running Tomcat 9 in Amazon Web services using Windows Server.  I
> > >> don't know what I'm doing wrong.  Further help will be appreciated. It
> > >> appears I have the pkcs12 wrong.
> > >>
> > >> Don
> > >>
> > >> On Tue, Nov 14, 2017 at 4:33 PM, Christopher Schultz <
> > >> chris@christopherschultz.net> wrote:
> > >>
> > >>> -----BEGIN PGP SIGNED MESSAGE-----
> > >>> Hash: SHA256
> > >>>
> > >>> Don,
> > >>>
> > >>> On 11/14/17 1:57 AM, Don Flinn wrote:
> > >>> > I've done some reading on SSL and understand the protocol is as
> > >>> > follows; Client/Browser sends ClientHello and server Tomcat replies
> > >>> > with ServerHello.  This establishes the protocol they will use.
The
> > >>> > server then sends the certificate and the public key - in the
> > >>> > clear The browser encrypts a message containing the servers domain,
> > >>> > all encrypted with the server's public key to the CA which the
> > >>> > browser trusts.  The public key is in the certificate. The CA
> > >>> > de-crypts the message with the server's private key.  So the
> > >>> > server's name/ domain must be not encrypted. If the server can
> > >>> > decrypt the message it knows the server and it then sends a ack
> > >>> > message back to the browser encrypted with the client's private
> > >>> > key.
> > >>>
> > >>> Most of that is correct (enough) except for the last part: the server
> > >>> never has the client's private key. The handshake is done using
> > >>> public-key/asymmetric encryption and part of that handshake includes
> > >>> establishing the keys to be used for the bulk encryption -- the
> > >>> encryption used after the handshake.
> > >>>
> > >>> > The browser and Tomcat then establish a secret key to send messages
> > >>> > back and forth.
> > >>>
> > >>> That's the bulk encryption key. Note that it can be re-negotiated at
> > >>> intervals during the conversation if necessary.
> > >>>
> > >>> > If I have the above correct, I must have keystore set up
> > >>> > incorrectly, since running my scenario I get an error in the Chrome
> > >>> > debugger,which says
> > >>> >
> > >>> > This page is not secure "Valid certificate The connection to this
> > >>> > site is using a valid, trusted server certificate issued by unknown
> > >>> > name. Secure resources All resources on this page are served
> > >>> > securely. "
> > >>> >
> > >>> > Note the 'the certificate is valid and it is issued by unknown
> > >>> > name"  Why is the issuer unknown, since the issuer's name is in
the
> > >>> > certificate?
> > >>>
> > >>> That message may be misleading. If the certificate is self-signed
> than
> > >>> of course the certificate signer is "known" to the client (Chrome)
> > >>> because it's just identified itself (as itself!). What it means to
be
> > >>> "unknown" is that it is /untrusted/. You haven't told Chrome that you
> > >>> specifically trust the certificate that signed the server's
> > >>> certificate. If you e.g. self-sign then the self-signature isn't
> > >>> recognized as authoritative. If a real CA signs it -- e.g. Verisign,
> > >>> DigiCert, Let's Encrypt, etc. -- then the browser /will/ recognize
> it.
> > >>>
> > >>> > letsencrypt has an online web site from which one can download
a
> > >>> > ca_bundle, a private key and a certificate for your domain
> > >>>
> > >>> Theoretically, you should generate your own private key and then use
> > >>> LE's tools to obtain a signed certificate.
> > >>>
> > >>> > Oracle has an article on keytool which says that keytool  can
not
> > >>> > create a pkcs12 keystore but can read it and to use openssl, which
> > >>> > I did following their instructions.
> > >>>
> > >>> OpenSSL will do DER/PEM files and also PKCS12 keystores, but they are
> > >>> interchangeable and contain the same types of key material... just
in
> > >>> different kinds of packages.
> > >>>
> > >>> > Concatenate the CA cert, the private key and the user cert then
put
> > >>> > these in keystore.
> > >>>
> > >>> Be careful with terms. Concatenation usually means just slamming
> bytes
> > >>> together. This only works with PEM-encoded files like OpenSSL likes
> to
> > >>> use -- the ones that start with e.g. "---- BEGIN CERTIFICATE ----".
> > >>> The other types of files have a very specific format and you can't
> > >>> just slam them together.
> > >>>
> > >>> > The result is shown below.  Tomcat isn't able to use this keystore
> > >>> > to communicate with the browser for some reason. Why? What's
> > >>> > missing or incorrect?
> > >>> >
> > >>> > C:\Users\don\Security\letsenc>%keytool% -list -keystore MMcert.p12
> > >>> > -v -storetype pkcs12 Enter keystore password:
> > >>> >
> > >>> > Keystore type: PKCS12 Keystore provider: SunJSSE
> > >>> >
> > >>> > Your keystore contains 1 entry
> > >>> >
> > >>> > Alias name: tomcat Creation date: Nov 13, 2017 Entry type:
> > >>> > PrivateKeyEntry
> > >>>
> > >>> So this is one of the things that makes me angry about keytool: it
> > >>> tells you there is only a single entry in the keystore and tells you
> > >>> that it's a "private key". Well... there is also a certificate in
> > >>> there and it's got signatures on it and stuff. I'd count that as at
> > >>> least 2 items. Anyway...
> > >>>
> > >>> > Certificate chain length: 1 Certificate[1]: Owner:
> > >>> > CN=info.finwoks.com
> > >>>
> > >>> Okay, this is traditionally called the "subject": info.finworks.com.
> > >>> This is *your certificate*, usually called the "server certificate".
> > >>> It's usually the last link in a chain of trust going from the CA down
> > >>> to the server cert.
> > >>>
> > >>> > Issuer: CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
> > >>>
> > >>> Good: you have a certificate that has been issued (aka signed) by
> > >>> Let's Encrypt.
> > >>>
> > >>> You appear to be missing the Let's Encrypt intermediate certificate
> in
> > >>> your keystore, which will be required for most browsers to trust the
> > >>> certificate (chain).
> > >>>
> > >>> Might I recommend using Qualys's fine SSL server test tool:
> > >>> https://www.ssllabs.com/ssltest/
> > >>>
> > >>> It probably would have told you that you have a single certificate
in
> > >>> your chain and that you need to have an intermediate certificate.
> > >>>
> > >>> It turns out that it's fairly easy to fix this: just import LE's
> > >>> intermediate certificate into your keystore, like this:
> > >>>
> > >>> $ keytool -import -alias [Authority.intermediate] -trustcacerts \
> > >>>    -file [authority's intermediate cert file] \
> > >>>    -keystore yourkeystore.jks
> > >>>
> > >>> Once you add this certificate, you will likely have to restart Tomcat
> > >>> to pick-up the changes.
> > >>>
> > >>> You can do this in a single operation to convert from the PEM-encoded
> > >>> files that LE gives to you into a PKCS12 package like this:
> > >>>
> > >>> $  openssl pkcs12 -export -in "${LE_BASE}/cert.pem" \
> > >>>           -inkey "${LE_BASE}/privkey.pem" \
> > >>>           -certfile "${LE_BASE}/fullchain.pem" \
> > >>>           -out "${CATALINA_BASE}/${HOSTNAME}.p12" -name tomcat \
> > >>>           -passout "pass:changeit"
> > >>>
> > >>> Note that this command imports all 3 items (server key, server
> > >>> certificate, and CA intermediate certs) into a single PKCS12 bundle.
> > >>> Then you can convert that into a Java keystore. Or just use PKCS12
as
> > >>> your keystore type from Tomcat and avoid the use of keytool
> altogether.
> > >>>
> > >>> You might find these two presentations informative:
> > >>> http://people.apache.org/~markt/presentations/2017-05-
> > 16-b-tomcat-ssl.pd
> > >>> f
> > >>> <http://people.apache.org/~markt/presentations/2017-05-
> > 16-b-tomcat-ssl.pdf>
> > >>>
> > >>> http://people.apache.org/~schultz/ApacheCon%20NA%202017/
> > Let's%20Encrypt%
> > >>> 20Apache%20Tomcat.pdf
> > >>> <http://people.apache.org/~schultz/ApacheCon%20NA%202017/
> > Let's%20Encrypt%20Apache%20Tomcat.pdf>
> > >>>
> > >>> Hope that helps,
> > >>> - -chris
> > >>> -----BEGIN PGP SIGNATURE-----
> > >>> Comment: GPGTools - http://gpgtools.org
> > >>> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
> > >>>
> > >>> iQJRBAEBCAA7FiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAloLYUYdHGNocmlzQGNo
> > >>> cmlzdG9waGVyc2NodWx0ei5uZXQACgkQHPApP6U8pFjtxRAAisLpBKPg9VFN5dPH
> > >>> tEeZQs7Bd6hM3NDBjRXE7RYAJhvBlOE2ImDkWXjRkJGedf00nTTQly6zKWHrusbC
> > >>> VlJMoEK+T72XeJIv2y5up3K+VmartQZLK6twMCqDEVZBv0gaEz1T7yfe6WC6/G4W
> > >>> oqGCkcDAF61P2u0K4QXldXBl1I83VCfEWWGpI7Bc1/5u7c/SE3kEN0D/V8Gs0H1r
> > >>> 8/LF2MzPSpGoJqSuRhyPWzklaK/ks+LSv1d7ur+ZrHHobSeMFtIHuhk6KakbheIL
> > >>> 3APEHZw3vHv70SFjvhviYg873CYOT52/x8zfzqpxc1z3X9JC/hAqzZUL7qKHPSMd
> > >>> bbWTSu8Tv7XWARe2BdyRQDKFJSTPnUNFxvyWviekNK5HkJx2sSgcH8iiTJN5lrMQ
> > >>> uEDZ4RukyT/b3VWn0RWtqvHnxZrLmXjWyV3MWNPFI0LYNuorJu6cROy4WnO7NFOV
> > >>> dmvDKC79qJ/XOziOmaGKgL11hNGwqYB2pn/aS7G+VCLCG0UGp8B/64j/5mNd9BL5
> > >>> a4DZXmonIPoKhjO/OP5H7hte2uqQAprrQgVI1JzKlYAb6wV+f4123nctlM+UeFBM
> > >>> ytYYVpwyD/TXxeVr0SnmNpOlyPHnO6RRXPXfmiNEbdsjMef+Inljc4DlcLnlbdvK
> > >>> Fc/zRGoUIB8+LN0T8NxVvXMAGGc=
> > >>> =IHty
> > >>> -----END PGP SIGNATURE-----
> > >>>
> > >>> ------------------------------------------------------------
> ---------
> > >>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> > >>> For additional commands, e-mail: users-help@tomcat.apache.org
> > >>>
> > >>>
> > >>
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message