SYMPTOMSWhen using SSL Certificates with Wild Cards in WebLogic Server from weblogic 9.2 to 10.3.5. as below CN=*.<Fully-Qualified-Domain-Name> you can see the following error: Caused by: javax.net.ssl.SSLKeyException: [Security:090504]Certificate chain received from <HOSTNAME> - <IP> failed hostname verification check. Certificate contained *.domain but check expected <HOSTNAME>
CHANGES
CAUSEThis issue is caused due to Default BEA hostname verifier is configured with WLS. Weblogic does not handle/support wildcard certificates out of the box. When weblogic initiates a connection over SSL, it makes a call to the HostnameVerifier. The default BEA hostname verifier matches the hostname you are connecting to and the CN of the certificate. SOLUTIONTo fix this issue there are three solutions: 1. Disable the Default BEA hostname verifier in WLS. 2. Write a custom hostname verifier and configure it with WLS. 3. For some WLS versions there is also patch for Bug 10215257 available for download. Disable the Default BEA hostname verifier in WLSLogin to Admin console --> Click on servers --> SSL --> Advanced --> from the dropdown menu next to Hostname verification select --> None Alternatively, you can add to JAVA_OPTIONS -Dweblogic.security.SSL.ignoreHostnameVerification=true to achieve the same. If you are using Node Manager, please check this document:
WebLogic Server: Procedure for configuring Node Manager with SSL. (Doc ID 1142995.1)
Write a custom hostname verifier and configure it with WLSThis is described in Oracle Documentation: package examples.security.sslclient; import java.io.ByteArrayInputStream; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.net.ssl.SSLSession; public class TestHostnameVerifier implements weblogic.security.SSL.HostnameVerifier { private final static Logger log = Logger.getLogger(TestHostnameVerifier.class.getCanonicalName()); @Override public boolean verify(String hostname, SSLSession session) { try { Certificate cert = session.getPeerCertificates()[0]; byte[] encoded = cert.getEncoded(); CertificateFactory cf = CertificateFactory.getInstance("X.509"); ByteArrayInputStream bais = new ByteArrayInputStream(encoded); X509Certificate xcert = (X509Certificate) cf.generateCertificate(bais); String cn = getCanonicalName(xcert.getSubjectDN().getName()); log.info("CN: '" + cn + "'" + " HOSTNAME: '" + hostname + "'"); // If CN is equals to Hostname then it is approved if (cn.equals(hostname)) { return true; } // Compile regular expression // here we set the wildcard and the rest of the URL inside, could be more generic too. cn = cn.replace(".", "\\."); cn = cn.replace("-", "\\-"); cn = cn.replace("*", "[-.*aA-zZ0-9]+"); Pattern pattern = Pattern.compile(cn); // Determine if there is an exact match CharSequence inputStr = hostname; Matcher matcher = pattern.matcher(inputStr); boolean matchFound = matcher.matches(); if (matchFound==false) { log.info("pattern doesn't match hostname"); } //return boolean value return matchFound; } catch (Exception e) { e.printStackTrace(); } return true; } /** * Returns just the canonical name from the distinguishedName on the cert. * * */ private String getCanonicalName(String subjectDN) { Pattern pattern = Pattern.compile("CN=([-.*aA-zZ0-9]*)"); Matcher matcher = pattern.matcher(subjectDN); if (matcher.find()) { return matcher.group(1); } log.info("Couldn't find match for CN in subject"); return subjectDN; } } To compile and package into a jar file i. Navigate to <WLS_HOME>/user_projects/domains/<DOMAINNAME>/bin ii. Set up an environment by executing: $ . ./setDomainEnv.sh This will include weblogic.jar into classpath, in order to use any of the libraries included under package weblogic.* iii. Compile the class by copying the content of the code above and naming the file as: TestHostnameVerifier.java iv. Run javac to compile the class. $javac TestHostnameVerifier.java v. Package the compiled class into a jar file by executing: $jar cvf TestHostnameVerifier.jar TestHostnameVerifier.class Expected output is: stnameVerifier.class added manifest adding:TestHostnameVerifier.class(in = 363) (out= 363)(stored 0%) vi. This will produce a file called: TestHostnameVerifier.jar
When attempting to use the Custom Hostname Verifier, you might experience the following error: <Error> <WebLogicServer> <AdminServer> <[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'> <> <> <ECID> <BEA-000297> <Inconsistent security configuration, weblogic.utils.NestedRuntimeException: [Security:090563]Cannot create instance of Hostname Verifier WildcardHostnameVerifier.WildcardHostnameVerifier.> <Emergency> <Security> <AdminServer> <[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'> <> <> <ECID> <BEA-090034> <Not listening for SSL, java.io.IOException: [Security:090563]Cannot create instance of Hostname Verifier WildcardHostnameVerifier.WildcardHostnameVerifier..> The issue is caused by Custom Hostname Verifier is not in the classpath. set CLASSPATH=%CUSTOMHOSTNAMEVERIFIERCLASSPATH%;%CLASSPATH% ii. Restart WebLogic Server and re test the issue. For some WLS versions there is also patch for Bug 10215257 available for downloadPatch 10215257 is available to enhance the existing default BEA hostname verifier. This means that you do not need to turn off Hostname verification OR write a custom hostname verifier to use Wildcard certificates from WLS. Once the patch is applied wildcard certificates are accepted by WLS. This patch extends the "default" hostname verifier (SSLWLSHostnameVerifier) to support a certificate's Subject Alternative Name (SAN) field, DNS Name type only. As an example, please go to this URL: https://www.digicert.com/subject-alternative-name.htm and view the certificate using your browser, select the Subject Alternative Name field, to view a list of domains secured by a single SSL certificate. List provided here for convenience (DNS Name=www.digicert.com, DNS Name=www.origin.digicert.com, DNS Name=content.digicert.com, DNS Name=digicert.com). SANs cannot be wildcarded because the standards that define SAN functionality do not support wildcarded values. -Dweblogic.security.SSL.hostnameVerifier=weblogic.security.utils.SSLWLSWildcardHostnameVerifier Additional information can be found in Oracle Documentation:
Patches are available for Bug 10215257:
This issue is fixed in 10.3.6.
REFERENCEShttp://download.oracle.com/docs/cd/E21764_01/web.1111/e13711/ssl_client.htm#i1029782NOTE:1142995.1 - WebLogic Server: Procedure for Configuring Node Manager with SSL http://docs.oracle.com/cd/E21764_01/web.1111/e13711/ssl_client.htm#i1029782 http://docs.oracle.com/cd/E21764_01/apirefs.1111/e13952/taskhelp/security/ConfigureACustomHostNameVerifier.html |
|