SSL Notes

We have a (very) old project running on Java 1.4, and today we had to struggle with getting SSL HTTP requests to work on it. Since very few have this problem, we’ll just list down various things that are SSL related that we touched on today.

1. Old Java versions won’t have the latest root certificates, so you will have to add them manually. For example, Java 5 doesn’t have the Comodo Essential SSL certificates, so you can get them from the Comodo Root & Intermediate Certificates download page.

Another way of getting the certificates is to get them from your browser. In IE, go to Tools -> Internet Options -> Certificates. In Firefox, go to Options -> Advanced -> Encryption. In Chrome, go to Settings -> Show advanced settings -> Manage certificates. Look for the certificate you need and do an export.

2. In Windows 7, when you run commands that make changes to files under JRE_HOME, make sure you run cmd.exe as Administrator.

3. When working with keytool and it asks for a password, use the default password “changeit”.

4. To view the certificates inside the keystore, use command keytool -list.

%JRE_HOME%bin/keytool -list -v -keystore %JRE_HOME%libsecuritycacerts

5. To add new root and intermediate certificates, run keytool -import. For example:

%JRE_HOME%binkeytool -import -trustcacerts -alias EssentialSSL -file EssentialSSLCA_2.crt -keystore %JRE_HOME%libsecuritycacerts

To add EssentialSSL to Java 5, we had to import EssentialSSLCA_2.crt, ComodoUTNSGCCA.crt, and UTNAddTrustSGCCA.crt.

6. To add a self-signed certificate, also use keytool -import, without the -trustcacerts option. For example:

%JRE_HOME%binkeytool -import -alias SelfSignedCert -file SelfSignedCert.crt -keystore %JRE_HOME%libsecuritycacerts

7. Here are the most common keytool commands from SSL Shopper.

8. If you wish to use your own keystore file, instead of the default %JRE_HOME%/lib/security/cacerts, use the javax.net.ssl.keyStore system property.

-Djavax.net.ssl.keyStore=/home/user/cacerts

9. If you wish to view the certificate chain for debugging purposes, you can use openssl or sslshopper.com.

openssl s_client -host www.example.com -port 443

http://www.sslshopper.com/ssl-checker.html#hostname=www.example.com

10. To disable certificate validation for testing purposes, use the all trusting X509TrustManager.

import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;

public static void disableX509TrustManager() {
	try {
		SSLContext context = SSLContext.getInstance("SSLv3");
		TrustManager[] trustManagerArray = { new NullX509TrustManager() };
		context.init(null, trustManagerArray, null);
		HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
	} catch (Exception e) {
		e.printStackTrace();
	}
}

private static class NullX509TrustManager implements X509TrustManager {

	public void checkClientTrusted(X509Certificate[] cert, String authType) {
	}

	public void checkServerTrusted(X509Certificate[] cert, String authType) {
	}

	public X509Certificate[] getAcceptedIssuers() {
		return null;
	}
}

mysqldump: Couldn’t execute ‘SELECT @@GTID_MODE’: Unknown system variable ‘GTID_MODE’ (1193)

If you are using the MySQL 5.6 version of mysqldump on an older MySQL database, you might get the error message.

mysqldump: Couldn't execute 'SELECT @@GTID_MODE': Unknown system variable 'GTID_MODE' (1193)

This error is in part due to the introduction of Global Transaction Identifiers (GTIDs) in MySQL 5.6. GTIDs make it simple to track and compare replication across a master-slave topology.

mysqldump tries to query this system variable, which doesn’t exist in earlier versions, and then fails. The solution is to add –set-gtid-purged=OFF in the mysqldump command. It should look something like

mysqldump -h dbHost -u dbuser dbName --set-gtid-purged=OFF

MySQL 5.6 – Specified key was too long; max key length is 767 bytes

We recently upgraded to MySQL 5.6, and one of our web applications started failing our automated tests. We have a test that drops all our tables and recreates them again, all done using Maven and Liquibase. The error we were getting was something like this.

SEVERE 1/1/13 12:00 PM:liquibase: Change Set /liquibase/tableName.sql::6::teamextension failed. Error:
Error executing SQL alter table tableName 
    add index indexName (columnName): Specified key was too long; max key length is 767 bytes

After we few Google searches, the found the issue to be described in the
Upgrading from Previous to Current Unicode Support page on the MySQL website. This boils down to the Unicode changes in MySQL 5.6.

So what’s the fix? We basically were indexing a very long column, and earlier MySQL versions were not complaining. The quickest fix is to tell MySQL to index only the first parts of the column.

    add index indexName (query(255));

But we have another problem. We were using Liquibase, with formatted SQL changelogs, and we cannot just change old changelogs. That will give errors when Liquibase runs. We started looking around the Liquibase documentation and saw the validCheckSum element, which could allow us to update old changelogs. Unfortunately, this only works with the XML changelogs. A little more digging and we came across the runOnChange attribute. Now we changed our changelog to:

--changeset teamextension:6 runOnChange
	alter table tableName
		add index indexName (columName(255));

Now things work again! If anyone has a better solution, please let us know. Thanks.