Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Warning
titleNew CAS documentation site

CAS documentation has moved over to jasig.github.io/cas, starting with CAS version 4.x. The wiki will no longer be maintained. For the most recent version of the documentation, please refer to the aforementioned link.

Excerpt

This page consists of an SSL error message troubleshooting reference followed by a discussion of SSL in Java that puts many of the solutions in context.

Troubleshooting SSL Errors

...

Code Block
java
java
titlePKIX Example Stack Trace

Sep 28, 2009 4:13:26 PM org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator retrieveResponseFromServer
SEVERE: javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
      at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
      at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
      at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
      at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
      at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
      at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
      at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
      at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
      at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
      at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
      at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
      at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
      at org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator.retrieveResponseFromServer(AbstractCasProtocolUrlBasedTicketValidator.java:35)
      at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:178)
      at org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:132)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)

PKIX path building errors are by far the most common SSL errors reported on the cas-user@lists.jasig.org mailing list. The problem here is that the CAS client does not trust the certificate presented by the CAS server; most often this occurs because of using a self-signed certificate on the CAS server. To resolve this error, import the CAS server certificate into the system truststore of the CAS client. If the certificate is issued by your own PKI, it is better to import the root certificate of your PKI into the CAS client truststore. See #Import Import Trusted Certificate for examples of importing a trusted certificate into a Java truststore.

If you have multiple java editions installed on your machine, make sure that your app / web server is pointing to the correct jdk/jre version (The one to which the certificate has been exported correctly) One common mistake that occurs while generating self-validated certifcates is that the java_home might be different than that used by the server (especially if it is run within an IDE like Eclipse or Websphere)

No subject alternative names present

Code Block
titleSample Alt Name Stack Trace

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present

...

Code Block
titleSample Wrong Host Name Stack Trace

ava.lang.RuntimeException: java.io.IOException: HTTPS hostname wrong:  should be <eiger.iad.vt.edu>
	org.jasig.cas.client.validation.Saml11TicketValidator.retrieveResponseFromServer(Saml11TicketValidator.java:203)
	org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:185)
	org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:132)
	org.jasig.cas.client.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:102)

The above error occurs most commonly when the CAS client ticket validator attempts to contact the CAS server and is presented a certificate whose CN does not match the fully-qualified host name of the CAS server. There are a few common root causes of this mismatch:

  • CAS client misconfiguration (usually a bad serverName init param)
  • Complex multi-tier server environment (e.g. clustered CAS server)
  • Host name too broad for scope of wildcard certificate

It is also worth checking that the certificate your CAS server is using for SSL encryption matches the one the client is checking against. For example, if your CAS server's ticket validator URL is https://subdomain.correctdomain.com/<something> and you have accidentally configured Tomcat to use the certificate for *.wrongdomain.com in it's SSL connector. You will get a bad certificate warning in the browser on the login page to hint at a problem but you ignore that warning (because you are using self signed certificates during development) and continue. Ticket validation will then fail with "java.security.cert.CertificateException: No name matching subdomain.correctdomain.com found" because the public key the CAS server is providing is for *.wrongdomain.com. The CAS client looks for the *.wrongdomain.com certificate in cacerts and then tries to find a matching CN or alternate within that certificate. It will completely ignore the beautifully crafted *.correctdomain.com certificate you carefully imported into cacerts.

Wildcard Certificates

JSSE support for wildcard certificates is limited to hosts strictly in the same domain as the wildcard. For example, a certificate with CN=.vt.edu matches hosts *a.vt.edu and b.vt.edu, but not a.b.vt.edu.

Simplified Java SSL Guide

The following guide attempts to distill the most important aspects of the Java Secure Socket Extension Reference Guide into a series of brief topics for consideration by CAS deployers. The following content should be considered a general guide with practical application to CAS through discussion and examples that are CAS-specific.

TODO: Write this content before or during the Spring Jasig Conference - MSA.

unrecognized_name Error

Code Block
titleJDK unrecognized_name SSL error
javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name 

 

The above error occurs mainly in Oracle JDK 7 CAS Server installations. In JDK7, SNI (Server Name Indication) is enabled by default. When the HTTPD Server does not send the correct Server Name back, the JDK HTTP Connection refuses to connect and the exception stated above is thrown.

To fix the issue, you must ensure your HTTPD Server is sending back the correct hostname. E.g. in Apache HTTPD, you must set the ServerAlias in the SSL vhost:

Code Block
titleApache HTTPD ServerAlias to fix SNI error
ServerName your.ssl-server.name
ServerAlias your.ssl-server.name

 

Alternatively, you can disable the SNI detection in JDK7, by adding this flag to the Java options of your CAS Servers' application server configuration:

Code Block
titleDisable SNI in JDK7
-Djsse.enableSNIExtension=false

 

Keystore/TrustStore Reference

...

By default the Java system truststore is at $JAVA_HOME/jre/lib/security/cacerts. The certificate to be imported MUST be a DER-encoded file. If the contents of the certificate file are binary, it's likely DER-encoded; if the file begins with the text ----BEGIN CERTIFICATE----, it is PEM-encoded and needs to be converted to DER encoding. The following example demonstrates a conversion command using OpenSSL.

Code Block
titleConvert PEM-encoded Cert to DER Encoding

openssl x509 -in etc/pki/incommon-root-cert.pem -out tmp/incommon-root-cert.der -outform DER

...

Code Block
titleKeytool Import Command

keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -file tmp/incommon-root-cert.der -alias incommon

List Trusted Certificates

Code Block

keytool -v -list -keystore $JAVA_HOME/jre/lib/security/cacerts

...

Code Block
titleSample setenv.sh Tomcat Script

# Uncomment the next 4 lines for custom SSL keystore
# used by all deployed applications
#KEYSTORE="$HOME/path/to/custom.keystore"
#CATALINA_OPTS=$CATALINA_OPTS" -Djavax.net.ssl.keyStore=$KEYSTORE"
#CATALINA_OPTS=$CATALINA_OPTS" -Djavax.net.ssl.keyStoreType=BKS"
#CATALINA_OPTS=$CATALINA_OPTS" -Djavax.net.ssl.keyStorePassword=changeit"

# Uncomment the next 4 lines to allow custom SSL trust store
# used by all deployed applications
#TRUSTSTORE="$HOME/path/to/custom.truststore"
#CATALINA_OPTS=$CATALINA_OPTS" -Djavax.net.ssl.trustStore=$TRUSTSTORE"
#CATALINA_OPTS=$CATALINA_OPTS" -Djavax.net.ssl.trustStoreType=BKS"
#CATALINA_OPTS=$CATALINA_OPTS" -Djavax.net.ssl.trustStorePassword=changeit"

# Uncomment the next line to print SSL debug trace in catalina.out
#CATALINA_OPTS=$CATALINA_OPTS" -Djavax.net.debug=ssl"

export CATALINA_OPTS