Spring SAML Sample application returns Could not initialize class org.apache.commons.ssl.TrustMaterial
You're most likely hitting a bug in the underlying OpenSAML and SSL library which presumes that file JAVA_HOME/lib/security/cacerts
or JAVA_HOME/lib/security/jssecacerts
is present and can be read as a JKS or PKCS12 keystore. In your case the file is probably corrupted.
Please try updating the cacerts file in your JDK with the file from the original installation. Make sure you can read it using keytool -list -keystore cacerts
with either an empty password or password "changeit".
Same issue, upgraded to not-yet-commons-ssl-0.3.16.jar from the bundled 3.9 of saml-sample and it worked.
I'm on a mac with Java 1.6 - here's what I found:
TrustMaterial.java is running static init code ->
String pathToCacerts = javaHome + "/lib/security/cacerts";
String pathToJSSECacerts = javaHome + "/lib/security/jssecacerts";
TrustMaterial cacerts = null;
TrustMaterial jssecacerts = null;
try {
File f = new File(pathToCacerts);
if (f.exists()) {
cacerts = new TrustMaterial(pathToCacerts);
}
}
catch (Exception e) {
e.printStackTrace();
}
try {
File f = new File(pathToJSSECacerts);
if (f.exists()) {
jssecacerts = new TrustMaterial(pathToJSSECacerts);
}
}
catch (Exception e) {
e.printStackTrace();
}
CACERTS = cacerts;
JSSE_CACERTS = jssecacerts;
if (JSSE_CACERTS != null) {
DEFAULT = JSSE_CACERTS;
} else {
DEFAULT = CACERTS;
}
Now, above there is a bug mentioned about assuming JAVA_HOME/lib/security/...
files are valid keystores. If neither of these files are valid keystores both CACERTS and JSSE_CACERTS are null and this line at line 127 causes the NPE because JSSE_CACERTS
is null:
this.jks = CACERTS != null ? CACERTS.jks : JSSE_CACERTS.jks;
So, why are both null?
When I look at mine on my filesystem:
file /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts
I get this:
/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts: broken symbolic link to /System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security/cacerts
That's a symlink to an invalid cacerts keystore. What I did was get a good copy of a JDK1.6 keystore via this command:
sudo find / -name 'cacerts' 2>/dev/null
/some/other/path/to/cacerts
Then, do file /some/other/path/to/cacerts
to make sure you get a valid file:
/some/other/path/to/cacerts: Java KeyStore
Copy that to /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts
to replace your broken symlink and verify it's good:
file /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts
/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts: Java KeyStore
Once that's a valid keystore, this code will work.
What a pain in the ass.