in taverna-credential-manager-impl/src/main/java/org/apache/taverna/security/credentialmanager/impl/CredentialManagerImpl.java [467:655]
private void loadTruststore() throws CMException {
if (truststore == null) {
try {
// Try to create Taverna's Truststore as Bouncy Castle UBER-type
// keystore.
truststore = KeyStore.getInstance("UBER", "BC");
} catch (Exception ex) {
// The requested keystore type is not available from security
// providers.
throw new CMException("Failed to instantiate Taverna's Truststore", ex);
}
if (truststoreFile.exists()) {
// If the Truststore file already exists, open it and load the
// Truststore
try (FileInputStream fis = new FileInputStream(truststoreFile)) {
// Load the Truststore from the file
truststore.load(fis, masterPassword.toCharArray());
// Delete the old revoked or unnecessary BioCatalogue,
// BiodiversityCatalogue and heater's certificates, if present
deleteRevokedCertificates();
} catch (Exception ex) {
/* Clear out things that are useless/hindering now */
truststore = null;
masterPassword = null;
String exMessage = "Failed to load Taverna's Truststore from "
+ truststoreFile.getAbsolutePath()
+ ". Possible reason: incorrect password or corrupted file.";
logger.error(exMessage, ex);
throw new CMException(exMessage, ex);
}
} else {
/*
* Otherwise create a new empty Truststore and load it with
* certs from Java's truststore.
*/
File javaTruststoreFile = new File(
System.getProperty("java.home"), "lib/security/cacerts");
KeyStore javaTruststore = null;
// Java's truststore is of type "JKS" - try to load it
try {
javaTruststore = KeyStore.getInstance("JKS");
} catch (Exception ex) {
// The requested keystore type is not available from the
// provider
throw new CMException("Failed to instantiate a 'JKS'-type keystore "
+ "for reading Java's truststore.", ex);
}
boolean loadedJavaTruststore = false;
/*
* Load Java's truststore from the file - try with the default
* Java truststore passwords.
*/
for (String password : defaultTrustStorePasswords) {
logger.info("Trying to load Java truststore using password: "
+ password);
try (FileInputStream fis = new FileInputStream(
javaTruststoreFile)) {
javaTruststore.load(fis, password.toCharArray());
loadedJavaTruststore = true;
break;
} catch (IOException ioex) {
/*
* If there is an I/O or format problem with the
* keystore data, or if the given password was incorrect
* (Thank you Sun, now I can't know if it is the file or
* the password..)
*/
logger.info(String
.format("Failed to load the Java truststore to copy "
+ "over certificates using default password: "
+ "%s from %s", password,
javaTruststoreFile));
} catch (NoSuchAlgorithmException e) {
logger.error("Unknown encryption algorithm "
+ "while loading Java truststore from "
+ javaTruststoreFile, e);
break;
} catch (CertificateException e) {
logger.error("Certificate error while "
+ "loading Java truststore from "
+ javaTruststoreFile, e);
break;
}
}
/*
* Default Java truststore passwords failed - possibly the user
* has changed it. Ask the Java truststore password providers if
* they can help - this will typically pop up a dialog to ask
* the user if we are in a graphical environment. If not, we
* will simply not copy the default truststore certificates into
* Credential Manager's Truststore.
*/
if (!loadedJavaTruststore)
if (!(loadJavaTruststoreUsingPasswordProviders(
javaTruststore, javaTruststoreFile))) {
String error = "Credential manager failed to load"
+ " certificates from Java's truststore.";
String help = "Try using the system property -D"
+ PROPERTY_TRUSTSTORE_PASSWORD
+ "=TheTrustStorePassword";
logger.error(error + " " + help);
// FIXME Writes to standard error!
System.err.println(error);
System.err.println(help);
}
// Create a new empty Truststore for Taverna
try (FileOutputStream fos = new FileOutputStream(truststoreFile)) {
truststore.load(null, null);
if (loadedJavaTruststore) {
// Copy certificates into Taverna's Truststore from
// Java's truststore.
Enumeration<String> aliases = javaTruststore.aliases();
while (aliases.hasMoreElements()) {
Certificate certificate = javaTruststore
.getCertificate(aliases.nextElement());
if (certificate instanceof X509Certificate)
truststore
.setCertificateEntry(
createTrustedCertificateAlias((X509Certificate) certificate),
certificate);
}
}
// Insert special trusted CA certificates
logger.info("Loading certificates of trusted CAs so as to establish trust into our services such as BioCatalogue, BiodiversityCatalogue, heater, etc.");
CertificateFactory cf = CertificateFactory
.getInstance("X.509");
for (URL trustedCertURL : getSpecialTrustedCertificates())
// Load the certificate (possibly a chain) from the
// stream
try (InputStream stream = trustedCertURL.openStream()) {
for (Certificate c : cf
.generateCertificates(stream))
truststore
.setCertificateEntry(
createTrustedCertificateAlias((X509Certificate) c),
c);
} catch (Exception cex) {
logger.error("Failed to insert trusted certificate entry in the Truststore", cex);
}
// Immediately save the new Truststore to the file
truststore.store(fos, masterPassword.toCharArray());
} catch (Exception ex) {
/*
* make truststore null as it was just created but failed to
* save so we should retry next time
*/
truststore = null;
throw new CMException("Failed to generate new empty Taverna's Truststore", ex);
}
}
/*
* Taverna distro for MAC contains info.plist file with some Java
* system properties set to use the Keychain which clashes with what
* we are setting here so we need to clear them.
*/
System.clearProperty(PROPERTY_TRUSTSTORE_TYPE);
System.clearProperty(PROPERTY_TRUSTSTORE_PROVIDER);
/*
* Not quite sure why we still need to set these two properties
* since we are creating our own SSLSocketFactory with our own
* TrustManager that uses Taverna's Truststore, but seem like after
* Taverna starts up and the first time it needs SSLSocketFactory
* for HTTPS connection it is still using the default Java's
* truststore unless these properties are set. Set the system
* property "javax.net.ssl.Truststore" to use Taverna's truststore.
*/
/*
* Axis 1 likes reading from these properties but seems to work as
* well with Taverna's SSLSocetFactory as well. We do not want to
* expose these as they can be read from Beanshells.
*/
// System.setProperty(PROPERTY_TRUSTSTORE, truststoreFile.getAbsolutePath());
// System.setProperty(PROPERTY_TRUSTSTORE_PASSWORD, masterPassword);
System.clearProperty(PROPERTY_TRUSTSTORE);
System.clearProperty(PROPERTY_TRUSTSTORE_PASSWORD);
}
}