package org.cagrid.dorian.service.ca; import java.io.ByteArrayInputStream; import java.security.Key; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.security.cert.X509Certificate; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.spec.IvParameterSpec; import org.cagrid.core.common.FaultHelper; import org.cagrid.gaards.pki.CertUtil; import org.cagrid.gaards.pki.KeyUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class BaseEracomCertificateAuthority extends CertificateAuthority { public static final String WRAPPER_KEY_ALIAS = "dorian-wrapper-key"; public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA"; public static final String SLOT_PROPERTY = "slot"; public final static Logger logger = LoggerFactory .getLogger(BaseEracomCertificateAuthority.class); private Provider provider; private KeyStore keyStore; private Key wrapper; private boolean isInit = false; public BaseEracomCertificateAuthority( EracomCertificateAuthorityProperties properties) throws CertificateAuthorityException { super(properties); try { isInit = false; int slot = properties.getSlot(); provider = (Provider) Class.forName( "au.com.eracom.crypto.provider.slot" + slot + ".ERACOMProvider").newInstance(); Security.addProvider(provider); keyStore = KeyStore.getInstance("CRYPTOKI", provider.getName()); keyStore.load(null, properties.getCertificateAuthorityPassword() .toCharArray()); } catch (Exception e) { logger.error(e.getMessage(), e); CertificateAuthorityException fault = FaultHelper .createFaultException(CertificateAuthorityException.class, "Error initializing the Dorian Certificate Authority."); FaultHelper.addMessage(fault, e.getMessage()); throw fault; } } public String getSignatureAlgorithm() { return SIGNATURE_ALGORITHM; } public String getCACredentialsProvider() { return getProvider().getName(); } protected Provider getProvider() { return provider; } protected KeyStore getKeyStore() { return keyStore; } protected Key getWrapperKey() { return wrapper; } protected void setInitialized(boolean val) { this.isInit = val; } protected void init() throws CertificateAuthorityException { try { if (!isInit) { if (keyStore.containsAlias(WRAPPER_KEY_ALIAS)) { wrapper = keyStore.getKey(WRAPPER_KEY_ALIAS, null); } else { KeyGenerator generator1 = KeyGenerator.getInstance("AES", provider); generator1.init(256, new SecureRandom()); keyStore.setKeyEntry(WRAPPER_KEY_ALIAS, generator1.generateKey(), null, null); wrapper = keyStore.getKey(WRAPPER_KEY_ALIAS, null); } isInit = true; } } catch (Exception e) { logger.error(e.getMessage(), e); CertificateAuthorityException fault = FaultHelper .createFaultException(CertificateAuthorityException.class, "An unexpected error occurred, could not add certificate."); FaultHelper.addMessage(fault, e.getMessage()); throw fault; } } public PrivateKey unwrap(WrappedKey key) throws CertificateAuthorityException { try { init(); Cipher cipher = Cipher .getInstance("AES/CBC/PKCS5Padding", provider); IvParameterSpec dps = new IvParameterSpec(key.getIV()); cipher.init(Cipher.DECRYPT_MODE, wrapper, dps); byte[] output = cipher.doFinal(key.getWrappedKeyData()); return KeyUtil.loadPrivateKey(new ByteArrayInputStream(output), null); } catch (Exception e) { logger.error(e.getMessage(), e); CertificateAuthorityException fault = FaultHelper .createFaultException(CertificateAuthorityException.class, "An unexpected error occurred unwrapping a key."); FaultHelper.addMessage(fault, e.getMessage()); throw fault; } } public WrappedKey wrap(PrivateKey key) throws CertificateAuthorityException { try { init(); byte[] input = KeyUtil.writePrivateKey(key, (String) null) .getBytes(); Cipher cipher = Cipher .getInstance("AES/CBC/PKCS5Padding", provider); cipher.init(Cipher.ENCRYPT_MODE, wrapper); byte[] wrappedKey = cipher.doFinal(input); byte[] iv = cipher.getIV(); return new WrappedKey(wrappedKey, iv); } catch (Exception e) { logger.error(e.getMessage(), e); CertificateAuthorityException fault = FaultHelper .createFaultException(CertificateAuthorityException.class, "An unexpected error occurred wrapping a key."); FaultHelper.addMessage(fault, e.getMessage()); throw fault; } } protected X509Certificate convert(X509Certificate cert) throws Exception { String str = CertUtil.writeCertificate(cert); return CertUtil.loadCertificate(str); } }