//$Header: /cvsroot-fuse/mec-as2/39/mendelson/util/security/cert/clientserver/KeystoreStorageImplClientServer.java,v 1.1 2012/04/18 14:10:47 heller Exp $ package de.mendelson.util.security.cert.clientserver; import de.mendelson.util.MecResourceBundle; import de.mendelson.util.clientserver.BaseClient; import de.mendelson.util.clientserver.clients.datatransfer.DownloadRequestFile; import de.mendelson.util.clientserver.clients.datatransfer.DownloadResponseFile; import de.mendelson.util.clientserver.clients.datatransfer.TransferClient; import de.mendelson.util.security.BCCryptoHelper; import de.mendelson.util.security.KeyStoreUtil; import de.mendelson.util.security.cert.KeystoreStorage; import de.mendelson.util.security.cert.ResourceBundleKeystoreStorage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.security.Key; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; /* * Copyright (C) mendelson-e-commerce GmbH Berlin Germany * * This software is subject to the license agreement set forth in the license. * Please read and agree to all terms before using this software. * Other product and brand names are trademarks of their respective owners. */ /** * Keystore storage implementation that relies on a client-server access * @author S.Heller * @version $Revision: 1.1 $ */ public class KeystoreStorageImplClientServer implements KeystoreStorage { private KeyStore keystore = null; private char[] keystorePass = null; private KeyStoreUtil keystoreUtil = new KeyStoreUtil(); private BaseClient baseClient; private String originalFilename; private boolean readOnlyOnServer = false; private String keystoreType = BCCryptoHelper.KEYSTORE_PKCS12; private MecResourceBundle rb; /** * @param keystoreFilename * @param keystorePass * @param keystoreType keystore type as defined in the class BCCryptoHelper */ public KeystoreStorageImplClientServer(BaseClient baseClient, String filename, char[] keystorePass, String keystoreType) throws Exception { //load resource bundle try { this.rb = (MecResourceBundle) ResourceBundle.getBundle( ResourceBundleKeystoreStorage.class.getName()); } catch (MissingResourceException e) { throw new RuntimeException("Oops..resource bundle " + e.getClassName() + " not found."); } this.baseClient = baseClient; this.keystorePass = keystorePass; this.keystoreType = keystoreType; this.loadKeystore(filename); } private void loadKeystore( String filename ) throws Exception{ //request the keystore from the server DownloadRequestFile request = new DownloadRequestFile(); request.setFilename(filename); DownloadResponseFile response = (DownloadResponseFile) baseClient.sendSync(request); if (response == null) { throw new Exception(this.rb.getResourceString("error.nodata")); } this.originalFilename = response.getFullFilename(); byte[] keystoreBytes = response.getDataBytes(); this.readOnlyOnServer = response.isReadOnly(); if (keystoreBytes == null || keystoreBytes.length == 0) { throw new IllegalArgumentException(this.rb.getResourceString("error.empty")); } BCCryptoHelper cryptoHelper = new BCCryptoHelper(); this.keystore = cryptoHelper.createKeyStoreInstance(keystoreType); //load the keystore data from the transfered byte array InputStream inStream = null; try { inStream = new ByteArrayInputStream(keystoreBytes); this.keystore.load(inStream, this.keystorePass); } catch( Exception e ){ throw new Exception( this.rb.getResourceString( "keystore.read.failure", e.getMessage()), e); } finally { if (inStream != null) { inStream.close(); } } } @Override public void save() throws Throwable { //write the current keystore object to a byte array ByteArrayOutputStream out = new ByteArrayOutputStream(); keystore.store(out, this.keystorePass); out.flush(); out.close(); UploadRequestKeystore request = new UploadRequestKeystore(); TransferClient transferClient = new TransferClient(this.baseClient); //send the full data file to the server, chunked ByteArrayInputStream inStream = new ByteArrayInputStream( out.toByteArray()); String uploadHash = transferClient.uploadChunked(inStream); request.setUploadHash(uploadHash); inStream.close(); request.setTargetFilename(this.originalFilename); UploadResponseKeystore response = (UploadResponseKeystore) this.baseClient.sendSync(request); if (response == null) { throw new Exception(this.rb.getResourceString("error.save")); } else if (response != null && response.getException() != null) { throw (response.getException()); } } @Override public Key getKey(String alias) throws Exception { Key key = this.keystore.getKey(alias, this.keystorePass); return (key); } @Override public Certificate[] getCertificateChain(String alias) throws Exception { Certificate[] chain = this.keystore.getCertificateChain(alias); return (chain); } @Override public X509Certificate getCertificate(String alias) throws Exception { return ((X509Certificate) this.keystore.getCertificate(alias)); } @Override public void renameEntry(String oldAlias, String newAlias, char[] keypairPass) throws Exception { KeyStoreUtil keystoreUtility = new KeyStoreUtil(); keystoreUtility.renameEntry(this.keystore, oldAlias, newAlias, keypairPass); } @Override public KeyStore getKeystore() { return (this.keystore); } @Override public char[] getKeystorePass() { return (this.keystorePass); } @Override public void deleteEntry(String alias) throws Exception { if (this.keystore == null) { //internal error, should not happen throw new Exception(this.rb.getResourceString("error.delete.notloaded")); } this.keystore.deleteEntry(alias); } @Override public Map<String, Certificate> loadCertificatesFromKeystore() throws Exception { this.loadKeystore(this.originalFilename); HashMap<String, Certificate> certificateMap = this.keystoreUtil.getCertificatesFromKeystore(this.keystore); return (certificateMap); } @Override public boolean isKeyEntry(String alias) throws Exception { return (this.keystore.isKeyEntry(alias)); } @Override public String getOriginalKeystoreFilename() { return (this.originalFilename); } @Override public boolean canWrite() { return (!this.readOnlyOnServer); } @Override public String getKeystoreType() { return( this.keystoreType); } }