/*
* Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
* cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
* Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
* Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
* compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence
* is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the Licence for the specific language governing permissions and limitations under
* the Licence.
*
* This product combines work with different licenses. See the "NOTICE" text file for details on the
* various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
* works that you distribute must include a readable copy of the "NOTICE" text file.
*/
package at.gv.egiz.eaaf.core.impl.utils;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
/**
* Utility for creating and loading key stores.
*
* @author Paul Ivancsics
* @version $Id$
*/
public class KeyStoreUtils {
/**
* JAVA KeyStore.
*/
private static final String KEYSTORE_TYPE_JKS = "JKS";
/**
* PKCS12 KeyStore.
*/
private static final String KEYSTORE_TYPE_PKCS12 = "PKCS12";
/**
* Loads a key store from file.
*
* @param keystoreType key store type
* @param urlString URL of key store
* @param password password protecting the key store
* @return key store loaded
* @throws IOException thrown while reading the key store from file
* @throws GeneralSecurityException thrown while creating the key store
*/
public static KeyStore loadKeyStore(final String keystoreType, final String urlString,
final String password) throws IOException, GeneralSecurityException {
final URL keystoreUrl = new URL(urlString);
final InputStream in = keystoreUrl.openStream();
return loadKeyStore(keystoreType, in, password);
}
/**
* Load a KeyStore from Filesystem.
*
* @param keyStorePath Path to KeyStore
* @param password KeyStore password
* @return KeyStore
* @throws KeyStoreException In case of a keystore error
* @throws IOException In case of a general read error
*/
public static KeyStore loadKeyStore(final String keyStorePath, final String password)
throws KeyStoreException, IOException {
final URL keystoreUrl = new URL(keyStorePath);
final InputStream in = keystoreUrl.openStream();
final InputStream isBuffered = new BufferedInputStream(in);
return loadKeyStore(isBuffered, password);
}
/**
* Loads a key store from an InputStream
, and closes the
* InputStream
.
*
* @param keystoreType key store type
* @param in input stream
* @param password password protecting the key store
* @return key store loaded
* @throws IOException thrown while reading the key store from the
* stream
* @throws GeneralSecurityException thrown while creating the key store
*/
public static KeyStore loadKeyStore(final String keystoreType, final InputStream in,
final String password) throws IOException, GeneralSecurityException {
char[] chPassword = null;
if (password != null) {
chPassword = password.toCharArray();
}
final KeyStore ks = KeyStore.getInstance(keystoreType);
ks.load(in, chPassword);
in.close();
return ks;
}
/**
* Loads a keyStore without knowing the keyStore type.
*
* @param is input stream
* @param password Password protecting the keyStore
* @return keyStore loaded
* @throws KeyStoreException thrown if keyStore cannot be loaded
* @throws IOException In case of a general error
*/
public static KeyStore loadKeyStore(final InputStream is, final String password)
throws KeyStoreException, IOException {
is.mark(1024 * 1024);
KeyStore ks = null;
try {
try {
ks = loadKeyStore(KEYSTORE_TYPE_PKCS12, is, password);
} catch (final IOException e2) {
is.reset();
ks = loadKeyStore(KEYSTORE_TYPE_JKS, is, password);
}
} catch (final Exception e) {
e.printStackTrace();
}
return ks;
}
/**
* Creates a key store from X509 certificate files, aliasing them with the index
* in the String[]
, starting with "0"
.
*
* @param keyStoreType key store type
* @param certFilenames certificate filenames
* @return key store created
* @throws Exception In case of an error
*/
public static KeyStore createKeyStore(final String keyStoreType, final String[] certFilenames)
throws Exception {
final KeyStore ks = KeyStore.getInstance(keyStoreType);
ks.load(null, null);
for (int i = 0; i < certFilenames.length; i++) {
final Certificate cert = loadCertificate(certFilenames[i]);
ks.setCertificateEntry("" + i, cert);
}
return ks;
}
/**
* Loads an X509 certificate from file.
*
* @param certFilename filename
* @return the certificate loaded
* @throws Exception In case of an IO exception
*/
private static Certificate loadCertificate(final String certFilename)
throws Exception {
FileInputStream in = null;
try {
in = new FileInputStream(certFilename);
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
final Certificate cert = certFactory.generateCertificate(in);
in.close();
return cert;
} catch (final Exception e) {
throw e;
} finally {
if (in != null) {
try {
in.close();
} catch (final IOException e) {
e.printStackTrace();
}
}
}
}
}