Solving the EVIL java SSL issue

Same 'ol | Website | Work At-Site

Testing web applications in developmental environments that attempt to utilize Https through unsigned certificates can be challenging, especially if you’ve never had the pleasure of working with Sun’s keytool utility and X.509 security certificates.

This issue manifests itself as javax.net.ssl.SSLHandshakeExceptions and sun.security.validator.ValidatorExceptions. For example, attempting to access untrusted Https through Java may yield stack traces with these tidbits:

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
...
Caused by: sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
...
Caused by: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested targetSolving this problem requires two steps. First, the web server’s certificate must be captured. Then, the certificate must be imported with Sun’s keytool utility (which comes with Java).

Obtaining a copy of the certificate in X.509 format requires Microsoft’s Internet Explorer. By placing the https URL into the browser window, a dialog will pop up requesting permission to accept the certificate. Click the View Certificate button and then the Details tab. In this tab, click the Copy to File button, then click Next and select the Base-64 encoded X.509 (.CER) option. After that, click Next to save the resulting file.

Importing the .cer file requires using the keytool utility, which can be found in bin directory of a Java installation. Via this tool, the .cer file is imported into a cacerts file, which is located in the lib/security directory of a Java installation. The easiest thing to do is to copy the .cer file obtained via Internet Explorer to my Java home dir/lib/security.

For example, if using the Java sdk for 1.4.2, the location on windows could be something like: C:\j2sdk1.4.2_05\jre\lib\security.

Once the .cer file has been copied to that directory, open a command prompt and either go to the security directory or use qualified paths. Type the following command:

$ ../../bin/keytool.exe -import -storepass changeit -file mycert.cer
-keystore cacerts -alias mycertThe only aspects requiring changes is the name of the certificate (in this case mycert.cer) and the alias (mycert).
The keytool will issue a series of statements describing the certificate and finally request whether or not to trust the certificate. Type yes and hit enter.

The problem should be solved. Verifying things is as easy as writing a test case. For instance, the following JUnit test verifies an untrusted Https site can be hit via Jakarta’s HttpClient.

package test.com.srv.rls.https.submit;

import junit.framework.TestCase;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;

public class HttpsSubmitTest extends TestCase {

public void testHttpsConnection() throws Exception{
HttpClient httpclient = new HttpClient();
GetMethod httpget =
new GetMethod("https://prf.acme.com:4175/invoke/ir/rve");
try {
httpclient.executeMethod(httpget);
assertEquals("should have been 200",
200, httpget.getStatusLine().getStatusCode());
}finally {
httpget.releaseConnection();
}
}
}Now testing web applications via JUnit extensions like jWebUnit or HttpUnit is a breeze, so long as they run in the VM which contains the updated keystore.

Email this entry4 Comments »
Developer Testing and /Glover03 Apr 2006 06:43 pm
Rerunning of failed tests

Have you ever experienced the frustration of having to rerun an enormous test suite because a few tests failed during the previous run? This can be a time consuming task, especially when test suites contain 100’s of tests!

TestNG, an annotation based testing framework for the Java platform has quite a few features that make it a compelling addition to any development team. One of the more interesting features is its support for rerunning failed tests.

Unlike JUnit, TestNG creates an XML file, dubbed testng-failures.xml, which defines each failed test; moreover, this XML file acts as a test suite which can be invoked at a later point in time (presumably when fixes are applied).

For example, via the command line, TestNG can be invoked like so:

c:>java org.testng.TestNG -sourcedir ./test/java ./test/conf/testng.xmlBy specifying the sourcedir option, TestNG will scan Java 1.4 source files for annotations via JavaDoc-like tags. The last parameter is a path pointing to a suite definition, which essentially defines which tests to run.

===============================================
corp-regression
Total tests run: 1205, Failures: 6, Skips: 0
===============================================If there were 6 failures in a JUnit run, we’d have to rerun the entire suite of 1205 tests to verify any associated fixes. With TestNG, however, a new suite file was generated which contains the information needed to rerun those 6 tests. Because the testng-failures.xml file defines a suite, this file becomes the last parameter when invoking the TestNG runner.

For example the command:

c:>java org.testng.TestNG -sourcedir ./test/java ./o/testng-failures.xmlwill only run 6 tests and produce the following output:

===============================================
Failed Tests suite
Total tests run: 6, Failures: 0, Skips: 0
===============================================JUnit is certainly the industry standard for developer testing in Java; however, TestNG offers a host of compelling features that make it a worthy addition for effective developer testing.