/* * 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; import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; import lombok.extern.slf4j.Slf4j; /** * Utility for creating and loading key stores. * * @author Paul Ivancsics * @version $Id$ */ @Slf4j 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 with known keyStore type. * * @param is input stream * @param password Password protecting the keyStore * @param keyStoreType Type of the KeyStore * @return loaded KeyStore * @throws IOException In case of a general error * @throws GeneralSecurityException In case of a KeyStore access error */ public static KeyStore loadKeyStore(final InputStream is, final String password, KeyStoreType keyStoreType) throws IOException, GeneralSecurityException { String internalType = KEYSTORE_TYPE_PKCS12; if (keyStoreType.equals(KeyStoreType.JKS)) { internalType = KEYSTORE_TYPE_JKS; } else if (keyStoreType.equals(KeyStoreType.PKCS12)) { internalType = KEYSTORE_TYPE_PKCS12; } return loadKeyStore(internalType, is, password); } /** * 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) { log.warn("Can not load keystore", e); } 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(); } } } } }