> -----Original Message----- > From: Robert Sulliman [mailto:robert.sulli...@sjrb.ca] > Sent: Monday, November 14, 2016 2:46 PM > To: Tomcat Users List > Subject: RE: Tomcat - Two Way SSL as Server > > Thanks John, > > I am trying to do #2, manually adding client certificates to the trust store. > However it doesn't work unless I add the root certificate to the trust store > as > well, or I get the certificate chain error below. It is a headache to handle > certs > like this, but as a rule of thumb we leave the responsibility for these certs > on the > client themselves. > > I'm pretty sure I'm not going to persuade security to create a new CA for me > just > for this one service... If I use a custom servlet, I lose the ability to do > revocation > checks on the certificates (I'm assuming that Tomcat does this natively, I > haven't > actually tested it yet.) > > Robert Sulliman > > -----Original Message----- > From: john.e.gr...@wellsfargo.com [mailto:john.e.gr...@wellsfargo.com] > Sent: Monday, November 14, 2016 1:24 PM > To: users@tomcat.apache.org > Subject: RE: Tomcat - Two Way SSL as Server > > > > > > > -----Original Message----- > > From: Robert Sulliman [mailto:robert.sulli...@sjrb.ca] > > Sent: Monday, November 14, 2016 12:25 PM > > To: users@tomcat.apache.org > > Subject: Tomcat - Two Way SSL as Server > > > > Hi All, > > > > I'm trying to implement two way SSL on a new web service that we are > > building and I'm having some issues. > > > > First some info on the environment. > > > > Server version: Apache Tomcat/8.0.36 > > Server built: Jun 9 2016 13:55:50 UTC > > Server number: 8.0.36.0 > > OS Name: Linux > > OS Version: 3.10.0-514.el7.x86_64 > > Architecture: amd64 > > JVM Version: 1.8.0_111-b14 > > JVM Vendor: Oracle Corporation > > > > We use an internal certificate authority to sign all of our > > certificates. So all the client certificates are signed by our > > internal root. When I trust the root certificate in the client trust > > store everything works. All client certificates signed by the internal root > > work. > > > > However, if I remove the root certificate from the client trust store, > > and add individual client certificates instead I get a cert chain error. > > ________________________________ > > *** ECDH ServerKeyExchange > > Signature Algorithm SHA512withRSA > > Server key: Sun EC public key, 256 bits > > public x coord: > > > 10710875017633521043383492698333011680577506891922716697438973534 > > 1685270962458 > > public y coord: > > > 93195725734236902743006469378087068209149058097948526490562555560 > > 744449337507 > > parameters: secp256r1 [NIST P-256, X9.62 prime256v1] > > (1.2.840.10045.3.1.7) > > *** CertificateRequest > > Cert Types: RSA, DSS, ECDSA > > Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, > > SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, > > SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, > > SHA1withECDSA, SHA1withRSA, SHA1withDSA Cert Authorities: > > <CN=Client, OU=Information Technology, O=Company, L=Calgary, > > ST=Alberta, C=CA> > > *** ServerHelloDone > > http-nio2-8443-exec-4, WRITE: TLSv1.2 Handshake, length = 4482 > > http-nio2- 8443-exec-2, READ: TLSv1.2 Handshake, length = 7 > > *** Certificate chain > > <Empty> > > *** > > http-nio2-8443-exec-2, fatal error: 42: null cert chain > > javax.net.ssl.SSLHandshakeException: null cert chain %% Invalidated: > > [Session- 2, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256] > > http-nio2-8443-exec-2, SEND TLSv1.2 ALERT: fatal, description = > > bad_certificate http-nio2-8443-exec-2, WRITE: TLSv1.2 Alert, length = > > 2 http- nio2-8443-exec-2, fatal: engine already closed. Rethrowing > > javax.net.ssl.SSLHandshakeException: null cert chain > > http-nio2-8443-exec-2, called closeOutbound() http-nio2-8443-exec-2, > > closeOutboundInternal() ________________________________ This is an > > issue for us as we can't have all the client certificates in the > > company granted access to this endpoint, it kind of defeats the purpose. > > > > The company root certificate is in another trust store used on server > > startup. > > Here are my configs. > > > > Server.xml connector: > > ________________________________ > > <Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol" > > port="8443" maxThreads="24" minSpareThreads="4" > > maxSpareThreads="4" acceptCount="1000" server=" " > > scheme="https" secure="true" SSLEnabled="true" > > keystoreFile="certs/servercert.jks" keystorePass=" > CrazyPasswordHere" > > clientAuth="true" > > truststoreFile="/usr/local/tomcat/certs/clienttrust.jks" > > truststorePass="CrazyPasswordHere" > > sslEnabledProtocols="TLSv1.2" sslProtocol="TLS" > > > > > ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WIT > > H_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, > > > > > TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_C > > BC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA" > > useServerCipherSuitesOrder="true" compression="on" > > compressionMinSize="2048" > > > > compressableMimeType="text/html,text/xml,text/plain,text/css,text/java > > script, application/javascript" /> ________________________________ > > Systemd init: > > ________________________________ > > # Systemd unit file for tomcat > > [Unit] > > Description=Apache Tomcat > > After=syslog.target network.target > > > > [Service] > > Type=forking > > > > Environment=JAVA_HOME=/usr/lib/jvm/jre > > Environment=CATALINA_PID=/usr/local/tomcat/temp/tomcat.pid > > Environment=CATALINA_HOME=/usr/local/tomcat > > Environment=CATALINA_BASE=/usr/local/tomcat > > Environment='CATALINA_OPTS= -Xms2048M -Xmx2048M -server - > > XX:+UseParallelGC \ -Dcom.sun.management.jmxremote \ > > -Dcom.sun.management.jmxremote.port=8090 \ - > > Dcom.sun.management.jmxremote.ssl=false \ - > > Dcom.sun.management.jmxremote.authenticate=true \ - > > > Dcom.sun.management.jmxremote.password.file=/usr/local/tomcat/conf/jmx > > r > > emote.password \ - > > Dcom.sun.management.jmxremote.access.file=/usr/local/tomcat/conf/jmxre > > m ote.access \ -Djavax.net.debug=SSL \ - > > Djavax.net.ssl.trustStore=/usr/local/tomcat/certs/servertrust.jks \ - > > Djavax.net.ssl.trustStorePassword=CrazyPasswordHere \ - > > Djavax.net.ssl.keyStore=/usr/local/tomcat/certs/serverclient.jks \ - > > Djavax.net.ssl.keyStorePassword=CrazyPasswordHere ' > > Environment='JAVA_OPTS=-Djava.awt.headless=true - > > Djava.security.egd=file:/dev/./urandom' > > > > ExecStart=/usr/local/tomcat/bin/startup.sh > > ExecStop=/bin/kill -15 $MAINPID > > > > User=tomcat > > Group=tomcat > > > > [Install] > > WantedBy=multi-user.target > > ________________________________ > > > > Thanks! > > > > Robert Sulliman > > > When you say "we can't have all the client certificates in the company granted > access to this endpoint," it sounds like you're talking about a whitelist on > the > server. I think that's possible with Apache, but not in Tomcat itself that I > know > of. > > What I've seen done instead is use a custom servlet filter that grabs the > subject > from the client certificate and checks it against a DB, config file, etc. > You can > access the client cert using > request.getAttribute("javax.servlet.request.X509Certificate"). It doesn't > have to > be a literal full match. Instead you can have the code enforce a rule like > this: "In > test environments, the subject must contain OU=TEST and the CN can be one of > foo, bar, baz, etc." You can make it as simple or complex as you want. > > You'll still need to set the server to require client auth and will still > need the > server to trust the internal CA that signs the clients' certs. Technically > any client > with a cert signed by that CA will be able to connect, but your servlet filter > should stop the wrong clients from getting any farther. This is definitely > one of > those cases where you want the code to fail closed! > > If you don't want to go this route, other things I can think of are: > > 1. Create a dedicated internal CA for just this purpose and trust it instead > of the > company-wide one. > 2. Add all client certs directly to the server's trust store. Is this what > you were > trying to do? I don't know why it didn't work, but this will be a huge > maintenance headache. Inevitably clients will forget to tell you when they > get > new certs and suddenly they'll be locked out. > > > John > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org
Sorry, I don't know what that error means. Since you mentioned CRLs, I found that Tomcat already supports a connector property called trustManagerClassName. Sounds like this could be your one-stop-shop for checking a CRL and authorizing the client. Doing so could still be based on the subject, or whatever you want, but the code would be in a custom trust manager instead of a servlet filter. I think I actually like this better. --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org