Description
Provides TLS Configuration for Client and Servers. Some properties apply only to servers,
some only to clients. All passwords be obfuscated, see the Jetty documentation on how to do this.
Debugging
-Djavax.net.debug=ssl
-Djavax.net.debug=all
This Link will
explain what's going on.
Common Errors
- PKIX path building failed: unable to find valid certification path to requested target
- There no certificate in the Trust Store matching the server.
- org.eclipse.jetty.http.HttpParser$IllegalCharacterException: 400: Illegal character CNTL=0x15
- One side is using TLS, the other isn't.
- javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching some-domain found
- The certificate CN does not match the host name.
- java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
- java.security.UnrecoverableKeyException: Get Key failed: null
- I got this when the Key Store password was missing.
- java.io.IOException: keystore password was incorrect
- This one is obvious.
Example
Client Accepts any certificate.
<oddjob id="oddjob">
<job>
<sequential>
<jobs>
<properties>
<values>
<value key="work.dir" value="${oddjob.dir}"/>
<file file="${work.dir}/stores" key="ssltest.stores.dir"/>
</values>
</properties>
<sequential name="Setup Keys and Certs">
<jobs>
<delete force="true" name="Delete Any Previous Store Directory">
<files>
<file file="${ssltest.stores.dir}"/>
</files>
</delete>
<mkdir dir="${ssltest.stores.dir}" name="Create Store Directory"/>
<exec dir="${ssltest.stores.dir}" name="Create Server Keystore">keytool -v -genkey -keyalg RSA -keysize 2048 -validity 360 -alias serverkey -keystore server_keystore.p12 -storetype pkcs12 -storepass storepwd -dname "CN=anything"</exec>
</jobs>
</sequential>
<web:server id="server" xmlns:web="oddjob:web">
<handler>
<web:resource base="${oddjob.dir}">
<welcomeFiles>
<list>
<values>
<value value="index.html"/>
</values>
</list>
</welcomeFiles>
</web:resource>
</handler>
<modifiers>
<web:ssl keyStorePassword="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4" keyStorePath="${ssltest.stores.dir}/server_keystore.p12"/>
</modifiers>
</web:server>
<web:client id="client" url="https://localhost:${server.port}" xmlns:web="oddjob:web">
<ssl>
<web:ssl trustAll="true"/>
</ssl>
</web:client>
<echo id="echo">${client.content}></echo>
<check eq="<h1>Hello World</h1>" value="#{client.get('content').trim()}"/>
<stop job="${server}"/>
</jobs>
</sequential>
</job>
</oddjob>
Example
Host Name Verification. The client accepts the host even if it doesn't match the certificate.
<oddjob id="oddjob">
<job>
<sequential>
<jobs>
<properties>
<values>
<value key="work.dir" value="${oddjob.dir}"/>
<file file="${work.dir}/stores" key="ssltest.stores.dir"/>
</values>
</properties>
<sequential name="Setup Keys and Certs">
<jobs>
<delete force="true" name="Delete Any Previous Store Directory">
<files>
<file file="${ssltest.stores.dir}"/>
</files>
</delete>
<mkdir dir="${ssltest.stores.dir}" name="Create Store Directory"/>
<exec dir="${ssltest.stores.dir}" name="Create Server Keystore">keytool -v -genkey -keyalg RSA -keysize 2048 -validity 360 -alias serverkey -keystore server_keystore.p12 -storetype pkcs12 -storepass srvstorepwd -dname "CN=anything"</exec>
<exec dir="${ssltest.stores.dir}" name="Export Server Certificate">
<stdout>
<file file="${ssltest.stores.dir}/server_cert.pem"/>
</stdout>keytool -export -rfc -alias serverkey -keystore server_keystore.p12 -storepass srvstorepwd</exec>
<exec dir="${ssltest.stores.dir}" name="Import Server Certificate into Client Trustore">
<stdin>
<file file="${ssltest.stores.dir}/server_cert.pem"/>
</stdin>keytool -v -import -keystore client_trustore.p12 -storepass clitrustpwd -alias serverkey -noprompt</exec>
</jobs>
</sequential>
<web:server id="server" xmlns:web="oddjob:web">
<handler>
<web:resource base="${oddjob.dir}">
<welcomeFiles>
<list>
<values>
<value value="index.html"/>
</values>
</list>
</welcomeFiles>
</web:resource>
</handler>
<modifiers>
<web:ssl keyStorePassword="srvstorepwd" keyStorePath="${ssltest.stores.dir}/server_keystore.p12"/>
</modifiers>
</web:server>
<web:client id="client" url="https://localhost:${server.port}" xmlns:web="oddjob:web">
<ssl>
<web:ssl trustStorePassword="clitrustpwd" trustStorePath="${ssltest.stores.dir}/client_trustore.p12">
<hostnameVerifier>
<web:hostname-verifier hostname=".*" regex="true"/>
</hostnameVerifier>
</web:ssl>
</ssl>
</web:client>
<echo id="echo">${client.content}></echo>
<check eq="<h1>Hello World</h1>" value="#{client.get('content').trim()}"/>
<stop job="${server}"/>
</jobs>
</sequential>
</job>
</oddjob>
Example
One Way Trust. The client verifies who the server is but the server doesn't care who the client is.
<oddjob id="oddjob">
<job>
<sequential>
<jobs>
<properties>
<values>
<value key="work.dir" value="${oddjob.dir}"/>
<value key="ssltest.hostname" value="#{java.net.InetAddress.getLocalHost().getHostName()}"/>
<file file="${work.dir}/stores" key="ssltest.stores.dir"/>
</values>
</properties>
<sequential name="Setup Keys and Certs">
<jobs>
<delete force="true" name="Delete Any Previous Store Directory">
<files>
<file file="${ssltest.stores.dir}"/>
</files>
</delete>
<mkdir dir="${ssltest.stores.dir}" name="Create Store Directory"/>
<exec dir="${ssltest.stores.dir}" name="Create Server Keystore">keytool -v -genkey -keyalg RSA -keysize 2048 -validity 360 -alias serverkey -keystore server_keystore.p12 -storetype pkcs12 -storepass srvstorepwd -dname "CN=${ssltest.hostname}"</exec>
<exec dir="${ssltest.stores.dir}" name="Export Server Certificate">
<stdout>
<file file="${ssltest.stores.dir}/server_cert.pem"/>
</stdout>keytool -export -rfc -alias serverkey -keystore server_keystore.p12 -storepass srvstorepwd</exec>
<exec dir="${ssltest.stores.dir}" name="Import Server Certificate into Client Trustore">
<stdin>
<file file="${ssltest.stores.dir}/server_cert.pem"/>
</stdin>keytool -v -import -storetype pkcs12 -keystore client_trustore.p12 -storepass clitrustpwd -alias serverkey -noprompt</exec>
</jobs>
</sequential>
<web:server id="server" xmlns:web="oddjob:web">
<handler>
<web:resource base="${oddjob.dir}">
<welcomeFiles>
<list>
<values>
<value value="index.html"/>
</values>
</list>
</welcomeFiles>
</web:resource>
</handler>
<modifiers>
<web:ssl keyStorePassword="srvstorepwd" keyStorePath="${ssltest.stores.dir}/server_keystore.p12" keyStoreType="PKCS12"/>
</modifiers>
</web:server>
<web:client id="client" url="https://${ssltest.hostname}:${server.port}" xmlns:web="oddjob:web">
<ssl>
<web:ssl trustStorePassword="clitrustpwd" trustStorePath="${ssltest.stores.dir}/client_trustore.p12" trustStoreType="PKCS12"/>
</ssl>
</web:client>
<echo id="echo">${client.content}></echo>
<check eq="<h1>Hello World</h1>" value="#{client.get('content').trim()}"/>
<stop job="${server}"/>
</jobs>
</sequential>
</job>
</oddjob>
Example
Two Way Trust. The client verifies who the server is and the server verifies who the client is.
<oddjob id="oddjob">
<job>
<sequential>
<jobs>
<properties>
<values>
<value key="work.dir" value="${oddjob.dir}"/>
<value key="ssltest.hostname" value="#{java.net.InetAddress.getLocalHost().getHostName()}"/>
<file file="${work.dir}/stores" key="ssltest.stores.dir"/>
</values>
</properties>
<sequential name="Setup Keys and Certs">
<jobs>
<delete force="true" name="Delete Any Previous Store Directory">
<files>
<file file="${ssltest.stores.dir}"/>
</files>
</delete>
<mkdir dir="${ssltest.stores.dir}" name="Create Store Directory"/>
<exec dir="${ssltest.stores.dir}" name="Create Server Keystore">keytool -v -genkey -keyalg RSA -keysize 2048 -validity 360 -alias serverkey -keystore server_keystore.p12 -storetype pkcs12 -storepass srvstorepwd -dname "CN=${ssltest.hostname}"</exec>
<exec dir="${ssltest.stores.dir}" name="Export Server Certificate">
<stdout>
<file file="${ssltest.stores.dir}/server_cert.pem"/>
</stdout>keytool -export -rfc -alias serverkey -keystore server_keystore.p12 -storepass srvstorepwd</exec>
<exec dir="${ssltest.stores.dir}" name="Import Server Certificate into Client Trustore">
<stdin>
<file file="${ssltest.stores.dir}/server_cert.pem"/>
</stdin>keytool -v -import -storetype pkcs12 -keystore client_trustore.p12 -storepass clitrustpwd -alias serverkey -noprompt</exec>
<exec dir="${ssltest.stores.dir}" name="Create Client Keystore">keytool -v -genkey -keyalg RSA -keysize 2048 -validity 360 -alias clientkey -keystore client_keystore.p12 -storetype pkcs12 -storepass clistorepwd -dname "CN=anything"</exec>
<exec dir="${ssltest.stores.dir}" name="Export Client Certificate">
<stdout>
<file file="${ssltest.stores.dir}/client_cert.pem"/>
</stdout>keytool -export -rfc -alias clientkey -keystore client_keystore.p12 -storepass clistorepwd</exec>
<exec dir="${ssltest.stores.dir}" name="Import Server Certificate into Client Trustore">
<stdin>
<file file="${ssltest.stores.dir}/client_cert.pem"/>
</stdin>keytool -v -import -storetype pkcs12 -keystore server_trustore.p12 -storepass srvtrustpwd -alias clientkey -noprompt</exec>
</jobs>
</sequential>
<web:server id="server" xmlns:web="oddjob:web">
<handler>
<web:resource base="${oddjob.dir}">
<welcomeFiles>
<list>
<values>
<value value="index.html"/>
</values>
</list>
</welcomeFiles>
</web:resource>
</handler>
<modifiers>
<web:ssl clientAuth="NEED" keyStorePassword="srvstorepwd" keyStorePath="${ssltest.stores.dir}/server_keystore.p12" keyStoreType="PKCS12" trustStorePassword="srvtrustpwd" trustStorePath="${ssltest.stores.dir}/server_trustore.p12" trustStoreType="PKCS12"/>
</modifiers>
</web:server>
<web:client id="client" url="https://${ssltest.hostname}:${server.port}" xmlns:web="oddjob:web">
<ssl>
<web:ssl keyStorePassword="clistorepwd" keyStorePath="${ssltest.stores.dir}/client_keystore.p12" keyStoreType="PKCS12" trustStorePassword="clitrustpwd" trustStorePath="${ssltest.stores.dir}/client_trustore.p12" trustStoreType="PKCS12"/>
</ssl>
</web:client>
<echo id="echo">${client.content}></echo>
<check eq="<h1>Hello World</h1>" value="#{client.get('content').trim()}"/>
<stop job="${server}"/>
</jobs>
</sequential>
</job>
</oddjob>