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 03:35:12 GMT
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