/* * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.carbon.registry.security.vault; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.cert.CertificateException; import java.util.Properties; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.registry.security.vault.util.SecureVaultConstants; import org.wso2.carbon.registry.security.vault.util.SecureVaultUtil; import org.wso2.securevault.CipherFactory; import org.wso2.securevault.CipherOperationMode; import org.wso2.securevault.DecryptionProvider; import org.wso2.securevault.EncodingType; import org.wso2.securevault.commons.MiscellaneousUtil; import org.wso2.securevault.definition.CipherInformation; import org.wso2.securevault.definition.IdentityKeyStoreInformation; import org.wso2.securevault.definition.KeyStoreInformationFactory; import org.wso2.securevault.definition.TrustKeyStoreInformation; import org.wso2.securevault.keystore.IdentityKeyStoreWrapper; import org.wso2.securevault.keystore.KeyStoreWrapper; import org.wso2.securevault.keystore.TrustKeyStoreWrapper; import org.wso2.securevault.secret.SecretRepository; public class CipherInitializer { private static Log log = LogFactory.getLog(CipherInitializer.class); private static final String LOCATION = "location"; private static final String KEY_STORE = "keyStore"; private static final String DOT = "."; private static final String ALGORITHM = "algorithm"; private static final String DEFAULT_ALGORITHM = "RSA"; private static final String TRUSTED = "trusted"; private static CipherInitializer cipherInitializer = null; // global password provider implementation class if defined in secret // manager conf file private String globalSecretProvider = null; private IdentityKeyStoreWrapper identityKeyStoreWrapper; private TrustKeyStoreWrapper trustKeyStoreWrapper; private DecryptionProvider decryptionProvider = null; private Cipher encryptionProvider = null; private CipherInitializer() { super(); boolean initPro = init(); if (initPro) { initCipherDecryptProvider(); initEncrypt(); } else { log.error("Either Configuration properties can not be loaded or No secret" + " repositories have been configured please check PRODUCT_HOME/repository/conf/security " + " refer links related to configure WSO2 Secure vault"); } } public static CipherInitializer getInstance() { if (cipherInitializer == null) { cipherInitializer = new CipherInitializer(); } return cipherInitializer; } private boolean init() { Properties properties = SecureVaultUtil.loadProperties();// loadProperties(); if (properties == null) { log.error("KeyStore configuration properties cannot be found"); return false; } String configurationFile = MiscellaneousUtil.getProperty(properties, SecureVaultConstants.PROP_SECRET_MANAGER_CONF, SecureVaultConstants.PROP_DEFAULT_CONF_LOCATION); Properties configurationProperties = MiscellaneousUtil.loadProperties(configurationFile); if (configurationProperties == null || configurationProperties.isEmpty()) { if (log.isDebugEnabled()) { log.debug("Configuration properties can not be loaded form : " + configurationFile + " Will use registry properties"); } configurationProperties = properties; } globalSecretProvider = MiscellaneousUtil.getProperty(configurationProperties, SecureVaultConstants.PROP_SECRET_PROVIDER, null); if (globalSecretProvider == null || "".equals(globalSecretProvider)) { if (log.isDebugEnabled()) { log.debug("No global secret provider is configured."); } } String repositoriesString = MiscellaneousUtil.getProperty(configurationProperties, SecureVaultConstants.PROP_SECRET_REPOSITORIES, null); if (repositoriesString == null || "".equals(repositoriesString)) { log.error("No secret repositories have been configured"); return false; } String[] repositories = repositoriesString.split(","); if (repositories == null || repositories.length == 0) { log.error("No secret repositories have been configured"); return false; } // Create a KeyStore Information for private key entry KeyStore IdentityKeyStoreInformation identityInformation = KeyStoreInformationFactory.createIdentityKeyStoreInformation(properties); // Create a KeyStore Information for trusted certificate KeyStore TrustKeyStoreInformation trustInformation = KeyStoreInformationFactory.createTrustKeyStoreInformation(properties); String identityKeyPass = null; String identityStorePass = null; String trustStorePass = null; if (identityInformation != null) { identityKeyPass = identityInformation.getKeyPasswordProvider().getResolvedSecret(); identityStorePass = identityInformation.getKeyStorePasswordProvider() .getResolvedSecret(); } if (trustInformation != null) { trustStorePass = trustInformation.getKeyStorePasswordProvider().getResolvedSecret(); } if (!validatePasswords(identityStorePass, identityKeyPass, trustStorePass)) { log.error("Either Identity or Trust keystore password is mandatory" + " in order to initialized secret manager."); return false; } identityKeyStoreWrapper = new IdentityKeyStoreWrapper(); identityKeyStoreWrapper.init(identityInformation, identityKeyPass); trustKeyStoreWrapper = new TrustKeyStoreWrapper(); if (trustInformation != null) { trustKeyStoreWrapper.init(trustInformation); } SecretRepository currentParent = null; for (String secretRepo : repositories) { StringBuffer sb = new StringBuffer(); sb.append(SecureVaultConstants.PROP_SECRET_REPOSITORIES); sb.append(SecureVaultConstants.DOT); sb.append(secretRepo); String id = sb.toString(); sb.append(SecureVaultConstants.DOT); sb.append(SecureVaultConstants.PROP_PROVIDER); String provider = MiscellaneousUtil.getProperty(configurationProperties, sb.toString(), null); if (provider == null || "".equals(provider)) { handleException("Repository provider cannot be null "); } if (log.isDebugEnabled()) { log.debug("Initiating a File Based Secret Repository"); } } return true; } private boolean validatePasswords(String identityStorePass, String identityKeyPass, String trustStorePass) { boolean isValid = false; if (trustStorePass != null && !"".equals(trustStorePass)) { if (log.isDebugEnabled()) { log.debug("Trust Store Password cannot be found."); } isValid = true; } else { if (identityStorePass != null && !"".equals(identityStorePass) && identityKeyPass != null && !"".equals(identityKeyPass)) { if (log.isDebugEnabled()) { log.debug("Identity Store Password " + "and Identity Store private key Password cannot be found."); } isValid = true; } } return isValid; } protected void initCipherDecryptProvider() { Properties properties = SecureVaultUtil.loadProperties(); StringBuffer sb = new StringBuffer(); // sb.append(id); sb.append(DOT); sb.append(LOCATION); StringBuffer sbTwo = new StringBuffer(); // sbTwo.append(id); sbTwo.append(DOT); sbTwo.append(ALGORITHM); // Load algorithm String algorithm = MiscellaneousUtil.getProperty(properties, sbTwo.toString(), DEFAULT_ALGORITHM); StringBuffer buffer = new StringBuffer(); buffer.append(DOT); buffer.append(KEY_STORE); // Load keyStore String keyStore = MiscellaneousUtil.getProperty(properties, buffer.toString(), null); KeyStoreWrapper keyStoreWrapper; if (TRUSTED.equals(keyStore)) { keyStoreWrapper = trustKeyStoreWrapper; } else { keyStoreWrapper = identityKeyStoreWrapper; } CipherInformation cipherInformation = new CipherInformation(); cipherInformation.setAlgorithm(algorithm); cipherInformation.setCipherOperationMode(CipherOperationMode.DECRYPT); cipherInformation.setInType(EncodingType.BASE64); // TODO decryptionProvider = CipherFactory.createCipher(cipherInformation, keyStoreWrapper); } /** * Initializing the encryption key store which uses to encypt the given * plain text * */ public void initEncrypt() { Properties properties = SecureVaultUtil.loadProperties(); String keyStoreFile = null; String keyType = null; String aliasName = null; String password = null; String provider = null; Cipher cipher = null; keyStoreFile = properties.getProperty("keystore.identity.location"); File keyStore = new File(keyStoreFile); if (!keyStore.exists()) { handleException("Primary Key Store Can not be found at Default location"); } keyType = properties.getProperty("keystore.identity.type"); aliasName = properties.getProperty("keystore.identity.alias"); ; // Create a KeyStore Information for private key entry KeyStore IdentityKeyStoreInformation identityInformation = KeyStoreInformationFactory.createIdentityKeyStoreInformation(properties); password = identityInformation.getKeyPasswordProvider().getResolvedSecret(); try { KeyStore primaryKeyStore = getKeyStore(keyStoreFile, password, keyType, provider); java.security.cert.Certificate certs = primaryKeyStore.getCertificate(aliasName); cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, certs); } catch (InvalidKeyException e) { handleException("Error initializing Cipher ", e); } catch (NoSuchAlgorithmException e) { handleException("Error initializing Cipher ", e); } catch (KeyStoreException e) { handleException("Error initializing Cipher ", e); } catch (NoSuchPaddingException e) { handleException("Error initializing Cipher ", e); } encryptionProvider = cipher; } /** * get the primary key store instant * * @param location * location of key store * @param storePassword * password of key store * @param storeType * key store type * @param provider * key store provider * @return KeyStore instant */ private static KeyStore getKeyStore(String location, String storePassword, String storeType, String provider) { File keyStoreFile = new File(location); if (!keyStoreFile.exists()) { handleException("KeyStore can not be found at ' " + keyStoreFile + " '"); } if (storePassword == null) { handleException("KeyStore password can not be null"); } if (storeType == null) { handleException("KeyStore Type can not be null"); } BufferedInputStream bufferedInputStream = null; try { bufferedInputStream = new BufferedInputStream(new FileInputStream(keyStoreFile)); KeyStore keyStore; if (provider != null) { keyStore = KeyStore.getInstance(storeType, provider); } else { keyStore = KeyStore.getInstance(storeType); } keyStore.load(bufferedInputStream, storePassword.toCharArray()); return keyStore; } catch (KeyStoreException e) { handleException("Error loading keyStore from ' " + location + " ' ", e); } catch (IOException e) { handleException("IOError loading keyStore from ' " + location + " ' ", e); } catch (NoSuchAlgorithmException e) { handleException("Error loading keyStore from ' " + location + " ' ", e); } catch (CertificateException e) { handleException("Error loading keyStore from ' " + location + " ' ", e); } catch (NoSuchProviderException e) { handleException("Error loading keyStore from ' " + location + " ' ", e); } finally { if (bufferedInputStream != null) { try { bufferedInputStream.close(); } catch (IOException ignored) { System.err.println("Error while closing input stream"); } } } return null; } protected static void handleException(String msg, Exception e) { //throw new CipherToolException(msg, e); } protected static void handleException(String msg) { //throw new CipherToolException(msg); } public IdentityKeyStoreWrapper getIdentityKeyStoreWrapper() { return identityKeyStoreWrapper; } public void setIdentityKeyStoreWrapper(IdentityKeyStoreWrapper identityKeyStoreWrapper) { this.identityKeyStoreWrapper = identityKeyStoreWrapper; } public TrustKeyStoreWrapper getTrustKeyStoreWrapper() { return trustKeyStoreWrapper; } public void setTrustKeyStoreWrapper(TrustKeyStoreWrapper trustKeyStoreWrapper) { this.trustKeyStoreWrapper = trustKeyStoreWrapper; } public DecryptionProvider getDecryptionProvider() { return decryptionProvider; } public Cipher getEncryptionProvider() { return encryptionProvider; } }