[jboss-cvs] Picketbox SVN: r403 - in branches/embargo/4.0.16.Final-vault: security-jboss-sx/jbosssx/src/main/java/org/picketbox/util and 4 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Apr 16 11:42:36 EDT 2013


Author: pskopek
Date: 2013-04-16 11:42:36 -0400 (Tue, 16 Apr 2013)
New Revision: 403

Added:
   branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/OriginalPicketBoxSecurityVault.java
   branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/SecurityVaultData.java
Modified:
   branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/PicketBoxSecurityVault.java
   branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/EncryptionUtil.java
   branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/KeyStoreUtil.java
   branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/EncryptionUtilUnitTestCase.java
   branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/test/resources/keystore/vault.keystore
   branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/test/resources/long_alias_keystore/vault.jks
   branches/embargo/4.0.16.Final-vault/security-spi/common/src/main/java/org/jboss/security/PicketBoxLogger.java
   branches/embargo/4.0.16.Final-vault/security-spi/common/src/main/java/org/jboss/security/PicketBoxMessages.java
Log:
Security Vault implementation change to use JCEKS as SecretKey storage.

Added: branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/OriginalPicketBoxSecurityVault.java
===================================================================
--- branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/OriginalPicketBoxSecurityVault.java	                        (rev 0)
+++ branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/OriginalPicketBoxSecurityVault.java	2013-04-16 15:42:36 UTC (rev 403)
@@ -0,0 +1,495 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.picketbox.plugins.vault;
+
+import org.jboss.security.PicketBoxLogger;
+import org.jboss.security.PicketBoxMessages;
+import org.jboss.security.plugins.PBEUtils;
+import org.jboss.security.vault.SecurityVault;
+import org.jboss.security.vault.SecurityVaultException;
+import org.picketbox.commons.cipher.Base64;
+import org.picketbox.util.EncryptionUtil;
+import org.picketbox.util.KeyStoreUtil;
+import org.picketbox.util.StringUtil;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.*;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * An instance of {@link SecurityVault} that uses
+ * a {@link KeyStore} 
+ * The shared key just uses a concatenation of a {@link java.util.UUID}
+ * and a keystore alias.
+ * 
+ * The following options are expected in the {@link SecurityVault#init(Map)} call:
+ * ENC_FILE_DIR: the location where the encoded files will be kept. End with "/" or "\" based on your platform
+ * KEYSTORE_URL: location where your keystore is located
+ * KEYSTORE_PASSWORD: Masked keystore password.  Has to be prepended with MASK-
+ * KEYSTORE_ALIAS: Alias where the keypair is located
+ * SALT: salt of the masked password. Ensured it is 8 characters in length
+ * ITERATION_COUNT: Iteration Count of the masked password.
+ * KEY_SIZE: Key size of encryption. Default is 128 bytes.
+ * 
+ * @author Anil.Saldhana at redhat.com
+ * @since Aug 12, 2011
+ */
+public class OriginalPicketBoxSecurityVault implements SecurityVault
+{
+   protected boolean finishedInit = false;
+
+   protected KeyStore keystore = null;
+   
+   private KeyPair keypair = null;
+   
+   protected String encryptionAlgorithm = "AES";
+   
+   protected int keySize = 128;
+   
+   private char[] keyStorePWD = null;
+   
+   protected Map<String,byte[]> theContent= new ConcurrentHashMap<String,byte[]>();
+   
+   protected Map<String,byte[]> sharedKeyMap = new ConcurrentHashMap<String,byte[]>();
+   
+   public static final String ENC_FILE_DIR = "ENC_FILE_DIR";
+   
+   public static final String KEYSTORE_URL = "KEYSTORE_URL";
+   
+   public static final String KEYSTORE_PASSWORD = "KEYSTORE_PASSWORD";
+   
+   public static final String KEYSTORE_ALIAS = "KEYSTORE_ALIAS";
+   
+   public static final String SALT = "SALT";
+   
+   public static final String ITERATION_COUNT = "ITERATION_COUNT";
+   
+   public static final String PASS_MASK_PREFIX = "MASK-";
+   
+   public static final String PUBLIC_CERT = "PUBLIC_CERT";
+   
+   public static final String KEY_SIZE = "KEY_SIZE"; 
+
+   protected static final String ENCODED_FILE = "ENC.dat";
+   protected static final String SHARED_KEY_FILE = "Shared.dat";
+   protected static final String ADMIN_KEY = "ADMIN_KEY";
+   
+   protected String decodedEncFileDir;
+   
+   protected String LINE_BREAK = "LINE_BREAK";
+   
+   /*
+    * @see org.jboss.security.vault.SecurityVault#init(java.util.Map)
+    */
+   @SuppressWarnings("unchecked")
+   public void init(Map<String, Object> options) throws SecurityVaultException
+   {
+      if(options == null || options.isEmpty())
+         throw PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMap("options");
+
+      String keystoreURL = (String) options.get(KEYSTORE_URL);
+      if(keystoreURL == null)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(KEYSTORE_URL));
+
+      if (keystoreURL.contains("${")){
+          keystoreURL = keystoreURL.replaceAll(":", StringUtil.PROPERTY_DEFAULT_SEPARATOR);  // replace single ":" with PL default
+      }
+      keystoreURL = StringUtil.getSystemPropertyAsString(keystoreURL);
+
+      String maskedPassword = (String) options.get(KEYSTORE_PASSWORD);
+      if(maskedPassword == null)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(KEYSTORE_PASSWORD));
+      if(maskedPassword.startsWith(PASS_MASK_PREFIX) == false)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidUnmaskedKeystorePasswordMessage());
+
+      String salt = (String) options.get(SALT);
+      if(salt == null)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(SALT));
+
+      String iterationCountStr = (String) options.get(ITERATION_COUNT);
+      if(iterationCountStr == null)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(ITERATION_COUNT));
+      int iterationCount = Integer.parseInt(iterationCountStr);
+      
+      String alias = (String) options.get(KEYSTORE_ALIAS);
+      if(alias == null)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(KEYSTORE_ALIAS));
+      
+      String keySizeStr = (String) options.get(KEY_SIZE);
+      if(keySizeStr != null)
+      {
+         keySize = Integer.parseInt(keySizeStr);
+      }
+      
+      String encFileDir = (String) options.get(ENC_FILE_DIR);
+      if(encFileDir == null)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(ENC_FILE_DIR));
+
+      FileInputStream fis = null, mapFile = null;
+      ObjectInputStream ois = null;
+      ObjectInputStream mapIS = null;
+      try
+      {
+         if (encFileDir.contains("${)")){
+             encFileDir = encFileDir.replaceAll(":",StringUtil.PROPERTY_DEFAULT_SEPARATOR);
+         }
+         decodedEncFileDir = StringUtil.getSystemPropertyAsString(encFileDir);  // replace single ":" with PL default
+
+         if(directoryExists(decodedEncFileDir) == false)
+            throw new SecurityVaultException(PicketBoxMessages.MESSAGES.fileOrDirectoryDoesNotExistMessage(decodedEncFileDir));
+         
+         if(!(decodedEncFileDir.endsWith("/") || decodedEncFileDir.endsWith("\\")))
+         {
+            throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidDirectoryFormatMessage(decodedEncFileDir));
+         }
+         if(encodedFileExists(decodedEncFileDir) ==false)
+         {
+            setUpVault(decodedEncFileDir);
+         }
+         
+         fis = new FileInputStream(decodedEncFileDir + ENCODED_FILE);
+         ois = new ObjectInputStream(fis);
+         theContent = (Map<String, byte[]>) ois.readObject();
+
+         mapFile = new FileInputStream(decodedEncFileDir + SHARED_KEY_FILE );
+         mapIS = new ObjectInputStream(mapFile);
+         
+         sharedKeyMap = (Map<String, byte[]>) mapIS.readObject();
+      }
+      catch (Exception e)
+      { 
+         throw new SecurityVaultException(e); 
+      }
+      finally
+      {
+    	  safeClose(fis);
+    	  safeClose(mapFile);
+    	  safeClose(ois);
+    	  safeClose(mapIS);
+      }
+
+      try
+      {
+         String keystorePass = decode(maskedPassword, salt, iterationCount);
+         keyStorePWD = keystorePass.toCharArray();
+         keystore = KeyStoreUtil.getKeyStore(keystoreURL, keystorePass.toCharArray()); 
+         keypair = KeyStoreUtil.getPrivateKey(keystore, alias, keystorePass.toCharArray());
+      }
+      catch (Exception e)
+      { 
+         throw new SecurityVaultException(e);
+      }
+      PicketBoxLogger.LOGGER.infoVaultInitialized();
+      finishedInit = true;
+   }
+
+   /*
+    * @see org.jboss.security.vault.SecurityVault#isInitialized()
+    */
+   public boolean isInitialized()
+   {
+      return finishedInit;
+   }
+
+   /*
+    * @see org.jboss.security.vault.SecurityVault#handshake(java.util.Map)
+    */
+   public byte[] handshake(Map<String, Object> handshakeOptions) throws SecurityVaultException
+   {
+      if(handshakeOptions == null || handshakeOptions.isEmpty())
+         throw PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMap("handshakeOptions");
+
+      String publicCert = (String) handshakeOptions.get(PUBLIC_CERT);
+      if(publicCert == null)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(PUBLIC_CERT));
+      
+      try
+      {
+         PublicKey publicKey = KeyStoreUtil.getPublicKey(keystore, publicCert, keyStorePWD);
+         if(publicKey == null)
+            throw new SecurityVaultException(PicketBoxMessages.MESSAGES.failedToRetrievePublicKeyMessage(publicCert));
+          
+      }
+      catch (Exception e)
+      {
+         throw new SecurityVaultException(e);
+      } 
+       
+      
+      StringBuilder uuid = new StringBuilder(UUID.randomUUID().toString());
+      uuid.append("LINE_BREAK");
+      uuid.append(publicCert);
+      
+      return Base64.encodeBytes(uuid.toString().getBytes(), Base64.DONT_BREAK_LINES).getBytes();
+   }
+   
+   /*
+    * @see org.jboss.security.vault.SecurityVault#keyList()
+    */
+   public Set<String> keyList() throws SecurityVaultException
+   {
+      Set<String> keys = theContent.keySet();
+      keys.remove(ADMIN_KEY);
+      return keys;
+   }
+
+   /*
+    * @see org.jboss.security.vault.SecurityVault#store(java.lang.String, java.lang.String, char[], byte[])
+    */
+   public void store(String vaultBlock, String attributeName, char[] attributeValue, byte[] sharedKey)
+         throws SecurityVaultException
+   {
+      if(StringUtil.isNullOrEmpty(vaultBlock))
+         throw PicketBoxMessages.MESSAGES.invalidNullArgument("vaultBlock");
+      if(StringUtil.isNullOrEmpty(attributeName))
+         throw PicketBoxMessages.MESSAGES.invalidNullArgument("attributeName");
+
+      String mapKey = vaultBlock + "_" + attributeName;
+      
+      sharedKeyMap.put(mapKey, sharedKey);
+      
+      String av = new String(attributeValue);
+      
+      //Get Public Key from shared key
+      String decodedSharedKey = new String(Base64.decode(new String(sharedKey)));
+      int index = decodedSharedKey.indexOf(LINE_BREAK);
+      
+      if(index < 0)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidSharedKeyMessage());
+      
+      String alias = decodedSharedKey.substring(index + LINE_BREAK.length());
+      
+      Certificate cert;
+      try
+      {
+         cert = keystore.getCertificate(alias);
+      }
+      catch (KeyStoreException e1)
+      { 
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.failedToRetrieveCertificateMessage(alias), e1);
+      }
+      
+      EncryptionUtil util = new EncryptionUtil(encryptionAlgorithm,keySize);
+      try
+      {
+         byte[] secretKey = theContent.get(ADMIN_KEY);
+         
+         SecretKeySpec sKeySpec = new SecretKeySpec(secretKey,encryptionAlgorithm);
+         byte[] encryptedData = util.encrypt(av.getBytes(), sKeySpec);
+         theContent.put(mapKey, encryptedData);
+      }
+      catch (Exception e1)
+      { 
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.unableToEncryptDataMessage(),e1);
+      }
+      try
+      {
+         writeSharedKeyFile(this.decodedEncFileDir);
+      }
+      catch (IOException e)
+      { 
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.unableToWriteShareKeyFileMessage(), e);
+      }
+      try
+      {
+         writeEncodedFile(this.decodedEncFileDir);
+      }
+      catch (IOException e)
+      { 
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.unableToWriteVaultDataFileMessage(""), e);
+      }
+   }
+
+   /*
+    * @see org.jboss.security.vault.SecurityVault#retrieve(java.lang.String, java.lang.String, byte[])
+    */
+   public char[] retrieve(String vaultBlock, String attributeName, byte[] sharedKey) throws SecurityVaultException
+   {
+      if(StringUtil.isNullOrEmpty(vaultBlock))
+         throw PicketBoxMessages.MESSAGES.invalidNullArgument("vaultBlock");
+      if(StringUtil.isNullOrEmpty(attributeName))
+         throw PicketBoxMessages.MESSAGES.invalidNullArgument("attributeName");
+
+      String mapKey = vaultBlock + "_" + attributeName;
+      byte[] encryptedValue = theContent.get(mapKey);
+       
+      
+      byte[] fromMap = sharedKeyMap.get(mapKey);
+      
+      boolean matches = Arrays.equals(sharedKey, fromMap);
+      if(matches == false)
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.sharedKeyMismatchMessage(vaultBlock, attributeName));
+
+      byte[] secretKey = theContent.get(ADMIN_KEY);
+       
+      SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, encryptionAlgorithm);
+      EncryptionUtil encUtil = new EncryptionUtil(encryptionAlgorithm, keySize);
+      try
+      {
+         return (new String(encUtil.decrypt(encryptedValue, keypair, secretKeySpec))).toCharArray();
+      }
+      catch (Exception e)
+      { 
+         throw new SecurityVaultException(e);
+      } 
+   }
+   /**
+    * @see org.jboss.security.vault.SecurityVault#exists(String, String)
+    */
+   public boolean exists(String vaultBlock, String attributeName) throws SecurityVaultException
+   { 
+      String mapKey = vaultBlock + "_" + attributeName;
+      return theContent.get(mapKey) != null;
+   }
+   
+   /*
+    * @see org.jboss.security.vault.SecurityVault#remove(java.lang.String, java.lang.String, byte[])
+    */
+   public boolean remove(String vaultBlock, String attributeName, byte[] sharedKey)
+		   throws SecurityVaultException 
+   {
+	   String mapKey = vaultBlock + "_" + attributeName;
+	   try
+	   {
+		   theContent.remove(mapKey);
+	   }
+	   catch(Exception e)
+	   {
+		   return false;
+	   }
+	   return true;
+	}
+   
+   private String decode(String maskedString, String salt, int iterationCount) throws Exception
+   {
+      String pbeAlgo = "PBEwithMD5andDES";
+      if (maskedString.startsWith(PASS_MASK_PREFIX))
+      {
+         // Create the PBE secret key 
+         SecretKeyFactory factory = SecretKeyFactory.getInstance(pbeAlgo);
+
+         char[] password = "somearbitrarycrazystringthatdoesnotmatter".toCharArray();
+         PBEParameterSpec cipherSpec = new PBEParameterSpec(salt.getBytes(), iterationCount);
+         PBEKeySpec keySpec = new PBEKeySpec(password);
+         SecretKey cipherKey = factory.generateSecret(keySpec);
+
+         maskedString = maskedString.substring(PASS_MASK_PREFIX.length());
+         String decodedValue = PBEUtils.decode64(maskedString, pbeAlgo, cipherKey, cipherSpec);
+
+         maskedString = decodedValue;
+      }
+      return maskedString;
+   }
+   
+   private void setUpVault(String decodedEncFileDir) throws NoSuchAlgorithmException,IOException
+   { 
+      theContent = new ConcurrentHashMap<String, byte[]>();
+      EncryptionUtil util = new EncryptionUtil(encryptionAlgorithm,keySize);
+      SecretKey secretKey = util.generateKey();
+      theContent.put(ADMIN_KEY, secretKey.getEncoded()); 
+      
+      writeEncodedFile(decodedEncFileDir);
+      writeSharedKeyFile(decodedEncFileDir);
+   }
+   
+   private void writeEncodedFile(String decodedEncFileDir) throws IOException
+   {
+	  FileOutputStream fos = null;
+	  ObjectOutputStream oos = null;
+	  try
+	  {
+	      fos = new FileOutputStream(decodedEncFileDir + ENCODED_FILE);
+	      oos = new ObjectOutputStream(fos);
+	      oos.writeObject(theContent);
+	  }
+	  finally
+	  {
+		  safeClose(oos);
+		  safeClose(fos);
+	  }
+   }
+   
+   private void writeSharedKeyFile(String decodedEncFileDir) throws IOException
+   {
+	   FileOutputStream fos = null;
+	   ObjectOutputStream oos = null;
+	   try
+	   {
+		   fos = new FileOutputStream(decodedEncFileDir + SHARED_KEY_FILE);
+		   oos = new ObjectOutputStream(fos);
+		   oos.writeObject(sharedKeyMap);
+	   }
+      finally
+      {
+    	  safeClose(oos);
+    	  safeClose(fos);
+      } 
+   }
+   
+   private boolean encodedFileExists(String decodedEncFileDir)
+   {
+      File file = new File(decodedEncFileDir + ENCODED_FILE);
+      return file != null && file.exists();
+   }
+   
+   private boolean directoryExists(String dir)
+   {
+      File file = new File(dir);
+      return file != null && file.exists();
+   }
+   
+   private void safeClose(InputStream fis)
+   {
+      try
+      {
+         if(fis != null)
+         {
+            fis.close();
+         }
+      }
+      catch(Exception e)
+      {}
+   }
+
+   private void safeClose(OutputStream os)
+   {
+      try
+      {
+         if(os != null)
+         {
+            os.close();
+         }
+      }
+      catch(Exception e)
+      {}
+   }
+}
\ No newline at end of file

Modified: branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/PicketBoxSecurityVault.java
===================================================================
--- branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/PicketBoxSecurityVault.java	2013-04-12 09:36:17 UTC (rev 402)
+++ branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/PicketBoxSecurityVault.java	2013-04-16 15:42:36 UTC (rev 403)
@@ -26,7 +26,6 @@
 import org.jboss.security.plugins.PBEUtils;
 import org.jboss.security.vault.SecurityVault;
 import org.jboss.security.vault.SecurityVaultException;
-import org.picketbox.commons.cipher.Base64;
 import org.picketbox.util.EncryptionUtil;
 import org.picketbox.util.KeyStoreUtil;
 import org.picketbox.util.StringUtil;
@@ -36,13 +35,21 @@
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.PBEParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
-import java.io.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.nio.channels.FileChannel;
 import java.security.*;
-import java.security.cert.Certificate;
-import java.util.Arrays;
+import java.security.KeyStore.Entry;
 import java.util.Map;
 import java.util.Set;
-import java.util.UUID;
+import java.util.StringTokenizer;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -61,6 +68,7 @@
  * KEY_SIZE: Key size of encryption. Default is 128 bytes.
  * 
  * @author Anil.Saldhana at redhat.com
+ * @author Peter Skopek (pskopek_at_redhat_dot_com)
  * @since Aug 12, 2011
  */
 public class PicketBoxSecurityVault implements SecurityVault
@@ -69,18 +77,18 @@
 
    protected KeyStore keystore = null;
    
-   private KeyPair keypair = null;
-   
    protected String encryptionAlgorithm = "AES";
    
    protected int keySize = 128;
    
    private char[] keyStorePWD = null;
    
-   protected Map<String,byte[]> theContent= new ConcurrentHashMap<String,byte[]>();
+   private String alias = null;
    
-   protected Map<String,byte[]> sharedKeyMap = new ConcurrentHashMap<String,byte[]>();
+   private SecurityVaultData vaultContent = null;
    
+   private SecretKey adminKey;
+   
    public static final String ENC_FILE_DIR = "ENC_FILE_DIR";
    
    public static final String KEYSTORE_URL = "KEYSTORE_URL";
@@ -99,18 +107,21 @@
    
    public static final String KEY_SIZE = "KEY_SIZE"; 
 
-   protected static final String ENCODED_FILE = "ENC.dat";
-   protected static final String SHARED_KEY_FILE = "Shared.dat";
-   protected static final String ADMIN_KEY = "ADMIN_KEY";
+   // backward compatibility constants 
+   private static final String ENCODED_FILE = "ENC.dat";
+   private static final String SHARED_KEY_FILE = "Shared.dat";
+   private static final String ADMIN_KEY = "ADMIN_KEY";
    
-   protected String decodedEncFileDir;
+   // versioned vault data file
+   protected static final String VAULT_CONTENT_FILE = "VAULT.dat";
    
+   private String decodedEncFileDir;
+   
    protected String LINE_BREAK = "LINE_BREAK";
    
    /*
     * @see org.jboss.security.vault.SecurityVault#init(java.util.Map)
     */
-   @SuppressWarnings("unchecked")
    public void init(Map<String, Object> options) throws SecurityVaultException
    {
       if(options == null || options.isEmpty())
@@ -140,7 +151,7 @@
          throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(ITERATION_COUNT));
       int iterationCount = Integer.parseInt(iterationCountStr);
       
-      String alias = (String) options.get(KEYSTORE_ALIAS);
+      this.alias = (String) options.get(KEYSTORE_ALIAS);
       if(alias == null)
          throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(KEYSTORE_ALIAS));
       
@@ -154,60 +165,21 @@
       if(encFileDir == null)
          throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(ENC_FILE_DIR));
 
-      FileInputStream fis = null, mapFile = null;
-      ObjectInputStream ois = null;
-      ObjectInputStream mapIS = null;
       try
       {
-         if (encFileDir.contains("${)")){
-             encFileDir = encFileDir.replaceAll(":",StringUtil.PROPERTY_DEFAULT_SEPARATOR);
-         }
-         decodedEncFileDir = StringUtil.getSystemPropertyAsString(encFileDir);  // replace single ":" with PL default
-
-         if(directoryExists(decodedEncFileDir) == false)
-            throw new SecurityVaultException(PicketBoxMessages.MESSAGES.fileOrDirectoryDoesNotExistMessage(decodedEncFileDir));
-         
-         if(!(decodedEncFileDir.endsWith("/") || decodedEncFileDir.endsWith("\\")))
-         {
-            throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidDirectoryFormatMessage(decodedEncFileDir));
-         }
-         if(encodedFileExists(decodedEncFileDir) ==false)
-         {
-            setUpVault(decodedEncFileDir);
-         }
-         
-         fis = new FileInputStream(decodedEncFileDir + ENCODED_FILE);
-         ois = new ObjectInputStream(fis);
-         theContent = (Map<String, byte[]>) ois.readObject();
-
-         mapFile = new FileInputStream(decodedEncFileDir + SHARED_KEY_FILE );
-         mapIS = new ObjectInputStream(mapFile);
-         
-         sharedKeyMap = (Map<String, byte[]>) mapIS.readObject();
-      }
-      catch (Exception e)
-      { 
-         throw new SecurityVaultException(e); 
-      }
-      finally
-      {
-    	  safeClose(fis);
-    	  safeClose(mapFile);
-    	  safeClose(ois);
-    	  safeClose(mapIS);
-      }
-
-      try
-      {
          String keystorePass = decode(maskedPassword, salt, iterationCount);
          keyStorePWD = keystorePass.toCharArray();
          keystore = KeyStoreUtil.getKeyStore(keystoreURL, keystorePass.toCharArray()); 
-         keypair = KeyStoreUtil.getPrivateKey(keystore, alias, keystorePass.toCharArray());
       }
       catch (Exception e)
       { 
          throw new SecurityVaultException(e);
       }
+      
+      // read and possibly convert vault content 
+      readVaultContent(keystoreURL, encFileDir);
+
+      
       PicketBoxLogger.LOGGER.infoVaultInitialized();
       finishedInit = true;
    }
@@ -223,44 +195,16 @@
    /*
     * @see org.jboss.security.vault.SecurityVault#handshake(java.util.Map)
     */
-   public byte[] handshake(Map<String, Object> handshakeOptions) throws SecurityVaultException
-   {
-      if(handshakeOptions == null || handshakeOptions.isEmpty())
-         throw PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMap("handshakeOptions");
-
-      String publicCert = (String) handshakeOptions.get(PUBLIC_CERT);
-      if(publicCert == null)
-         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidNullOrEmptyOptionMessage(PUBLIC_CERT));
-      
-      try
-      {
-         PublicKey publicKey = KeyStoreUtil.getPublicKey(keystore, publicCert, keyStorePWD);
-         if(publicKey == null)
-            throw new SecurityVaultException(PicketBoxMessages.MESSAGES.failedToRetrievePublicKeyMessage(publicCert));
-          
-      }
-      catch (Exception e)
-      {
-         throw new SecurityVaultException(e);
-      } 
-       
-      
-      StringBuilder uuid = new StringBuilder(UUID.randomUUID().toString());
-      uuid.append("LINE_BREAK");
-      uuid.append(publicCert);
-      
-      return Base64.encodeBytes(uuid.toString().getBytes(), Base64.DONT_BREAK_LINES).getBytes();
+   public byte[] handshake(Map<String, Object> handshakeOptions) throws SecurityVaultException {
+       return new byte[keySize];
    }
    
    /*
     * @see org.jboss.security.vault.SecurityVault#keyList()
     */
-   public Set<String> keyList() throws SecurityVaultException
-   {
-      Set<String> keys = theContent.keySet();
-      keys.remove(ADMIN_KEY);
-      return keys;
-   }
+    public Set<String> keyList() throws SecurityVaultException {
+        return vaultContent.getVaultData().keySet();
+    }
 
    /*
     * @see org.jboss.security.vault.SecurityVault#store(java.lang.String, java.lang.String, char[], byte[])
@@ -273,60 +217,28 @@
       if(StringUtil.isNullOrEmpty(attributeName))
          throw PicketBoxMessages.MESSAGES.invalidNullArgument("attributeName");
 
-      String mapKey = vaultBlock + "_" + attributeName;
+      vaultContent.getVaultData().put(dataKey(vaultBlock, attributeName), sharedKey);
       
-      sharedKeyMap.put(mapKey, sharedKey);
-      
       String av = new String(attributeValue);
       
-      //Get Public Key from shared key
-      String decodedSharedKey = new String(Base64.decode(new String(sharedKey)));
-      int index = decodedSharedKey.indexOf(LINE_BREAK);
-      
-      if(index < 0)
-         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.invalidSharedKeyMessage());
-      
-      String alias = decodedSharedKey.substring(index + LINE_BREAK.length());
-      
-      Certificate cert;
+      EncryptionUtil util = new EncryptionUtil(encryptionAlgorithm, keySize);
       try
       {
-         cert = keystore.getCertificate(alias);
+         SecretKeySpec sKeySpec = new SecretKeySpec(adminKey.getEncoded(), encryptionAlgorithm);
+         byte[] encryptedData = util.encrypt(av.getBytes(), sKeySpec);
+         vaultContent.getVaultData().put(dataKey(vaultBlock, attributeName), encryptedData);
       }
-      catch (KeyStoreException e1)
-      { 
-         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.failedToRetrieveCertificateMessage(alias), e1);
-      }
-      
-      EncryptionUtil util = new EncryptionUtil(encryptionAlgorithm,keySize);
-      try
-      {
-         byte[] secretKey = theContent.get(ADMIN_KEY);
-         
-         SecretKeySpec sKeySpec = new SecretKeySpec(secretKey,encryptionAlgorithm);
-         byte[] encryptedData = util.encrypt(av.getBytes(), cert.getPublicKey(), sKeySpec);
-         theContent.put(mapKey, encryptedData);
-      }
       catch (Exception e1)
       { 
          throw new SecurityVaultException(PicketBoxMessages.MESSAGES.unableToEncryptDataMessage(),e1);
       }
-      try
-      {
-         writeSharedKeyFile(this.decodedEncFileDir);
+      
+      try {
+         writeVaultData();
       }
-      catch (IOException e)
-      { 
-         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.unableToWriteShareKeyFileMessage(), e);
+      catch (IOException e) { 
+         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.unableToWriteVaultDataFileMessage(VAULT_CONTENT_FILE), e);
       }
-      try
-      {
-         writeEncodedFile(this.decodedEncFileDir);
-      }
-      catch (IOException e)
-      { 
-         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.unableToWriteEncodedFileMessage(), e);
-      }
    }
 
    /*
@@ -339,36 +251,25 @@
       if(StringUtil.isNullOrEmpty(attributeName))
          throw PicketBoxMessages.MESSAGES.invalidNullArgument("attributeName");
 
-      String mapKey = vaultBlock + "_" + attributeName;
-      byte[] encryptedValue = theContent.get(mapKey);
+      byte[] encryptedValue = vaultContent.getVaultData().get(dataKey(vaultBlock, attributeName));
        
-      
-      byte[] fromMap = sharedKeyMap.get(mapKey);
-      
-      boolean matches = Arrays.equals(sharedKey, fromMap);
-      if(matches == false)
-         throw new SecurityVaultException(PicketBoxMessages.MESSAGES.sharedKeyMismatchMessage(vaultBlock, attributeName));
-
-      byte[] secretKey = theContent.get(ADMIN_KEY);
-       
-      SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, encryptionAlgorithm);
+      SecretKeySpec secretKeySpec = new SecretKeySpec(adminKey.getEncoded(), encryptionAlgorithm);
       EncryptionUtil encUtil = new EncryptionUtil(encryptionAlgorithm, keySize);
       try
       {
-         return (new String(encUtil.decrypt(encryptedValue, keypair, secretKeySpec))).toCharArray();
+         return (new String(encUtil.decrypt(encryptedValue, secretKeySpec))).toCharArray();
       }
       catch (Exception e)
       { 
          throw new SecurityVaultException(e);
       } 
    }
+
    /**
     * @see org.jboss.security.vault.SecurityVault#exists(String, String)
     */
-   public boolean exists(String vaultBlock, String attributeName) throws SecurityVaultException
-   { 
-      String mapKey = vaultBlock + "_" + attributeName;
-      return theContent.get(mapKey) != null;
+   public boolean exists(String vaultBlock, String attributeName) throws SecurityVaultException { 
+      return vaultContent.getVaultData().get(dataKey(vaultBlock, attributeName)) != null;
    }
    
    /*
@@ -377,13 +278,10 @@
    public boolean remove(String vaultBlock, String attributeName, byte[] sharedKey)
 		   throws SecurityVaultException 
    {
-	   String mapKey = vaultBlock + "_" + attributeName;
-	   try
-	   {
-		   theContent.remove(mapKey);
+	   try {
+		   vaultContent.getVaultData().remove(dataKey(vaultBlock, attributeName));
 	   }
-	   catch(Exception e)
-	   {
+	   catch(Exception e) {
 		   return false;
 	   }
 	   return true;
@@ -410,26 +308,43 @@
       return maskedString;
    }
    
-   private void setUpVault(String decodedEncFileDir) throws NoSuchAlgorithmException,IOException
+   private void setUpVault(String keystoreURL, String decodedEncFileDir) throws NoSuchAlgorithmException, IOException
    { 
-      theContent = new ConcurrentHashMap<String, byte[]>();
-      EncryptionUtil util = new EncryptionUtil(encryptionAlgorithm,keySize);
-      SecretKey secretKey = util.generateKey();
-      theContent.put(ADMIN_KEY, secretKey.getEncoded()); 
+      vaultContent = new SecurityVaultData(new ConcurrentHashMap<String, byte[]>());
+      writeVaultData();
       
-      writeEncodedFile(decodedEncFileDir);
-      writeSharedKeyFile(decodedEncFileDir);
+      SecretKey sk = getAdminKey();
+      if (sk != null) {
+          adminKey = sk; 
+      }
+      else {
+          // try to generate new admin key and store it under specified alias
+          EncryptionUtil util = new EncryptionUtil(encryptionAlgorithm, keySize);
+          sk = util.generateKey();
+          KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(sk);
+          try {
+              keystore.setEntry(alias, skEntry, new KeyStore.PasswordProtection(keyStorePWD));
+              adminKey = sk;
+              saveKeyStoreToFile(keystoreURL);
+          }
+          catch (KeyStoreException e) {
+             throw PicketBoxMessages.MESSAGES.noSecretKeyandAliasAlreadyUsed(alias);
+          }
+          catch (Exception e) {
+             throw PicketBoxMessages.MESSAGES.unableToStoreKeyStoreToFile(e, keystoreURL); 
+          }
+      }
    }
    
-   private void writeEncodedFile(String decodedEncFileDir) throws IOException
+   private void writeVaultData() throws IOException
    {
 	  FileOutputStream fos = null;
 	  ObjectOutputStream oos = null;
 	  try
 	  {
-	      fos = new FileOutputStream(decodedEncFileDir + ENCODED_FILE);
+	      fos = new FileOutputStream(decodedEncFileDir + VAULT_CONTENT_FILE);
 	      oos = new ObjectOutputStream(fos);
-	      oos.writeObject(theContent);
+	      oos.writeObject(vaultContent);
 	  }
 	  finally
 	  {
@@ -438,26 +353,9 @@
 	  }
    }
    
-   private void writeSharedKeyFile(String decodedEncFileDir) throws IOException
+   private boolean vaultFileExists(String fileName)
    {
-	   FileOutputStream fos = null;
-	   ObjectOutputStream oos = null;
-	   try
-	   {
-		   fos = new FileOutputStream(decodedEncFileDir + SHARED_KEY_FILE);
-		   oos = new ObjectOutputStream(fos);
-		   oos.writeObject(sharedKeyMap);
-	   }
-      finally
-      {
-    	  safeClose(oos);
-    	  safeClose(fos);
-      } 
-   }
-   
-   private boolean encodedFileExists(String decodedEncFileDir)
-   {
-      File file = new File(decodedEncFileDir + ENCODED_FILE);
+      File file = new File(this.decodedEncFileDir + fileName);
       return file != null && file.exists();
    }
    
@@ -492,4 +390,215 @@
       catch(Exception e)
       {}
    }
+
+    private void readVaultContent(String keystoreURL, String encFileDir) throws SecurityVaultException {
+
+        try {
+            if (encFileDir.contains("${)")) {
+                encFileDir = encFileDir.replaceAll(":", StringUtil.PROPERTY_DEFAULT_SEPARATOR);
+            }
+            decodedEncFileDir = StringUtil.getSystemPropertyAsString(encFileDir); // replace single ":" with PL default
+
+            if (directoryExists(decodedEncFileDir) == false)
+                throw new SecurityVaultException(
+                        PicketBoxMessages.MESSAGES.fileOrDirectoryDoesNotExistMessage(decodedEncFileDir));
+
+            if (!(decodedEncFileDir.endsWith("/") || decodedEncFileDir.endsWith("\\"))) {
+                decodedEncFileDir = decodedEncFileDir + File.separator;
+            }
+
+            if (vaultFileExists(ENCODED_FILE)) {
+                if (vaultFileExists(VAULT_CONTENT_FILE)) {
+                    PicketBoxLogger.LOGGER.mixedVaultDataFound(VAULT_CONTENT_FILE, ENCODED_FILE, decodedEncFileDir
+                            + ENCODED_FILE);
+                    throw PicketBoxMessages.MESSAGES.mixedVaultDataFound(VAULT_CONTENT_FILE, ENCODED_FILE);
+                } else {
+                    convertVaultContent(keystoreURL, alias);
+                }
+            } else {
+                if (vaultFileExists(VAULT_CONTENT_FILE)) {
+                    readVersionedVaultContent();
+                } else {
+                    setUpVault(keystoreURL, decodedEncFileDir);
+                }
+            }
+
+        } catch (Exception e) {
+            throw new SecurityVaultException(e);
+        }
+
+    }
+
+   @SuppressWarnings("unchecked")
+   private void convertVaultContent(String keystoreURL, String alias) throws Exception {
+       FileInputStream fis = null;
+       ObjectInputStream ois = null;
+       Map<String, byte[]> theContent;
+       
+       try {
+           fis = new FileInputStream(decodedEncFileDir + ENCODED_FILE);
+           ois = new ObjectInputStream(fis);
+           theContent = (Map<String, byte[]>) ois.readObject();
+       } finally {
+           safeClose(fis);
+           safeClose(ois);
+       }
+        
+       Map<String, byte[]> newVault = new ConcurrentHashMap<String, byte[]>();
+       
+       adminKey = null;
+       for (String key: theContent.keySet()) {
+           if (key.equals(ADMIN_KEY)) {
+               byte[] admin_key = theContent.get(key);
+               adminKey = new SecretKeySpec(admin_key, encryptionAlgorithm);
+           }
+           else {
+               if (key.contains("_")) {
+                   StringTokenizer tokenizer = new StringTokenizer(key, "_");
+                   String vaultBlock = tokenizer.nextToken();
+                   String attributeName = tokenizer.nextToken();
+                   if (tokenizer.hasMoreTokens()) {
+                       attributeName = key.substring(vaultBlock.length() + 1);
+                       PicketBoxLogger.LOGGER.ambiguosKeyForSecurityVaultTransformation("_", vaultBlock, attributeName);
+                   }
+                   byte[] encodedAttributeValue = theContent.get(key);
+                   newVault.put(dataKey(vaultBlock, attributeName), encodedAttributeValue);
+               }
+           }
+       }
+       if (adminKey == null) {
+           throw PicketBoxMessages.MESSAGES.missingAdminKeyInOriginalVaultData();
+       }
+       
+       // create new transformed vault data
+       vaultContent = new SecurityVaultData(newVault);
+       
+       // convert keystore to JCEKS format
+       convertKeyStoreToJCEKS();
+       
+       // add secret key (admin_key) to keystore 
+       KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(adminKey);
+       keystore.setEntry(alias, skEntry, new KeyStore.PasswordProtection(keyStorePWD));
+
+       // backup original keystore file
+       copyFile(new File(keystoreURL), new File(keystoreURL + ".original"));
+       // save the current keystore
+       saveKeyStoreToFile(keystoreURL);
+    
+       // backup original vault files
+       copyFile(new File(decodedEncFileDir + ENCODED_FILE), new File(decodedEncFileDir + ENCODED_FILE + ".original"));
+       copyFile(new File(decodedEncFileDir + SHARED_KEY_FILE), new File(decodedEncFileDir + SHARED_KEY_FILE + ".original"));
+
+       // delete original vault files
+       File f = new File(decodedEncFileDir + ENCODED_FILE);
+       if (!f.delete()) {
+           PicketBoxLogger.LOGGER.cannotDeleteOriginalVaultFile(f.getCanonicalPath());
+       }
+       f = new File(decodedEncFileDir + SHARED_KEY_FILE);
+       if (!f.delete()) {
+           PicketBoxLogger.LOGGER.cannotDeleteOriginalVaultFile(f.getCanonicalPath());
+       }
+       
+   }
+
+   private void saveKeyStoreToFile(String keystoreURL) throws Exception {
+       keystore.store(new FileOutputStream(new File(keystoreURL)), keyStorePWD);
+   }
+   
+   
+   private void convertKeyStoreToJCEKS() throws Exception {
+       if (keystore.getType().equalsIgnoreCase("JKS")) {
+           keystore = KeyStore.getInstance("JCEKS");
+           keystore.load(null, keyStorePWD);
+       }
+   }
+   
+   /**
+    * Creates new format for data key in vault. All parameters has to be non-null.
+    * 
+    * @param vaultBlock
+    * @param attributeName
+    * @param alias
+    * @return
+    */
+   public static String dataKey(String vaultBlock, String attributeName) {
+      return vaultBlock + StringUtil.PROPERTY_DEFAULT_SEPARATOR + attributeName; 
+   }
+   
+    private void readVersionedVaultContent() throws Exception {
+        FileInputStream fis = null;
+        ObjectInputStream ois = null;
+        try {
+            fis = new FileInputStream(decodedEncFileDir + VAULT_CONTENT_FILE);
+            ois = new ObjectInputStream(fis);
+            vaultContent = (SecurityVaultData) ois.readObject();
+        } finally {
+            safeClose(fis);
+            safeClose(ois);
+        }
+        
+        adminKey = getAdminKey();
+        if (adminKey == null) {
+            throw PicketBoxMessages.MESSAGES.vaultDoesnotContainSecretKey(alias);
+        }    
+    }
+   
+    /**
+     * Returns SecretKey stored in defined keystore under defined alias.
+     * If no such SecretKey exists returns null.
+     * @return
+     */
+    private SecretKey getAdminKey() {
+        try {
+            Entry e = keystore.getEntry(alias, new KeyStore.PasswordProtection(keyStorePWD));
+            if (e instanceof KeyStore.SecretKeyEntry) {
+                return ((KeyStore.SecretKeyEntry)e).getSecretKey();
+            }
+        }
+        catch (Exception e) {
+            PicketBoxLogger.LOGGER.vaultDoesnotContainSecretKey(alias);
+            return null;
+        }
+        return null;
+    }
+    
+   /**
+    * Copy file method.
+    * 
+    * @param sourceFile
+    * @param destFile
+    * @throws IOException
+    */
+    public static void copyFile(File sourceFile, File destFile) throws IOException {
+        if (!destFile.exists()) {
+            destFile.createNewFile();
+        }
+        FileInputStream fIn = null;
+        FileOutputStream fOut = null;
+        FileChannel source = null;
+        FileChannel destination = null;
+        try {
+            fIn = new FileInputStream(sourceFile);
+            source = fIn.getChannel();
+            fOut = new FileOutputStream(destFile);
+            destination = fOut.getChannel();
+            long transfered = 0;
+            long bytes = source.size();
+            while (transfered < bytes) {
+                transfered += destination.transferFrom(source, 0, source.size());
+                destination.position(transfered);
+            }
+        } finally {
+            if (source != null) {
+                source.close();
+            } else if (fIn != null) {
+                fIn.close();
+            }
+            if (destination != null) {
+                destination.close();
+            } else if (fOut != null) {
+                fOut.close();
+            }
+        }
+    }
 }
\ No newline at end of file

Added: branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/SecurityVaultData.java
===================================================================
--- branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/SecurityVaultData.java	                        (rev 0)
+++ branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/SecurityVaultData.java	2013-04-16 15:42:36 UTC (rev 403)
@@ -0,0 +1,100 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.picketbox.plugins.vault;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.security.PicketBoxLogger;
+import org.jboss.security.PicketBoxMessages;
+
+/**
+ * Security vault data store with version serialized data storage.
+ *  
+ * @author Peter Skopek (pskopek_at_redhat_dot_com)
+ *
+ */
+public class SecurityVaultData implements Serializable {
+
+    /**
+     *  Do not change this suid, it is used for handling different versions of serialized data.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *  Version to denote actual version of SecurityVaultData object.
+     */
+    private static final int VERSION = 1;
+    
+    private transient Map<String, byte[]> vaultData = new ConcurrentHashMap<String,byte[]>();
+    
+    /**
+     * Constructor which fills the vault data.
+     * @param vaultData
+     */
+    public SecurityVaultData(Map<String, byte[]> vaultData) {
+        this.vaultData = vaultData;
+    }
+
+    /**
+     * Default constructor for serialization purpose.
+     * @param vaultData
+     */
+    public SecurityVaultData() {
+    }
+
+    private void writeObject(ObjectOutputStream oos) throws IOException {
+        oos.writeObject(new Integer(VERSION));
+        oos.writeObject(vaultData);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+        int version = (Integer) ois.readObject();
+        
+        if (PicketBoxLogger.LOGGER.isDebugEnabled()) {
+            PicketBoxLogger.LOGGER.securityVaultContentVersion(String.valueOf(version), String.valueOf(VERSION));
+        }
+        
+        if (version == 1) {
+            this.vaultData = (Map<String, byte[]>)ois.readObject();
+        }
+        else {
+            throw PicketBoxMessages.MESSAGES.unrecognizedVaultContentVersion(String.valueOf(version), "1", String.valueOf(VERSION));
+        }
+    }
+
+    /**
+     * Returns vault data internal store.
+     * 
+     * @return
+     */
+    public Map<String, byte[]> getVaultData() {
+        return vaultData;
+    }
+    
+}

Modified: branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/EncryptionUtil.java
===================================================================
--- branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/EncryptionUtil.java	2013-04-12 09:36:17 UTC (rev 402)
+++ branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/EncryptionUtil.java	2013-04-16 15:42:36 UTC (rev 403)
@@ -54,17 +54,15 @@
       return key;
    }
    
-   public byte[] encrypt(byte[] data, PublicKey publicKey, SecretKey key) throws Exception
+   public byte[] encrypt(byte[] data, SecretKey key) throws Exception
    {
+       /*
      // Get the KeyGenerator
       KeyGenerator kgen = KeyGenerator.getInstance(this.encryptionAlgorithm);
       kgen.init(keySize);
- 
-      byte[] publicKeyEncoded = publicKey.getEncoded();
-
+       */
       SecretKeySpec skeySpec = new SecretKeySpec(key.getEncoded(), encryptionAlgorithm);
 
-
       // Instantiate the cipher 
       Cipher cipher = Cipher.getInstance(encryptionAlgorithm);
 
@@ -75,15 +73,14 @@
       return encrypted;
    }
    
-   public byte[] decrypt(byte[] encryptedData, KeyPair keypair, SecretKeySpec keySpec ) throws Exception
+   public byte[] decrypt(byte[] encryptedData, SecretKeySpec keySpec ) throws Exception
    {
+      /*
       // Get the KeyGenerator
       KeyGenerator kgen = KeyGenerator.getInstance(this.encryptionAlgorithm);
       kgen.init(keySize);
- 
-      byte[] publicKeyEncoded = keypair.getPrivate().getEncoded();
- 
-
+      */
+       
       // Instantiate the cipher 
       Cipher cipher = Cipher.getInstance(encryptionAlgorithm);
     

Modified: branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/KeyStoreUtil.java
===================================================================
--- branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/KeyStoreUtil.java	2013-04-12 09:36:17 UTC (rev 402)
+++ branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/KeyStoreUtil.java	2013-04-16 15:42:36 UTC (rev 403)
@@ -137,7 +137,8 @@
    {
       if (ksStream == null)
          throw PicketBoxMessages.MESSAGES.invalidNullArgument("ksStream");
-      KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+      // KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+      KeyStore ks = KeyStore.getInstance("JCEKS");
       ks.load(ksStream, storePass);
       return ks;
    }

Modified: branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/EncryptionUtilUnitTestCase.java
===================================================================
--- branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/EncryptionUtilUnitTestCase.java	2013-04-12 09:36:17 UTC (rev 402)
+++ branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/EncryptionUtilUnitTestCase.java	2013-04-16 15:42:36 UTC (rev 403)
@@ -57,7 +57,7 @@
       
       SecretKey secretKey = encUtil.generateKey();
       
-      byte[] encryptedData = encUtil.encrypt(keyStorePass.getBytes(), publicKey, secretKey);
+      byte[] encryptedData = encUtil.encrypt(keyStorePass.getBytes(), secretKey);
       
       KeyPair keypair = KeyStoreUtil.getPrivateKey(ks, alias, keyStorePass.toCharArray());
       byte[] decryptedData = encUtil.decrypt(encryptedData, keypair, secretKey);

Modified: branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/test/resources/keystore/vault.keystore
===================================================================
(Binary files differ)

Modified: branches/embargo/4.0.16.Final-vault/security-jboss-sx/jbosssx/src/test/resources/long_alias_keystore/vault.jks
===================================================================
(Binary files differ)

Modified: branches/embargo/4.0.16.Final-vault/security-spi/common/src/main/java/org/jboss/security/PicketBoxLogger.java
===================================================================
--- branches/embargo/4.0.16.Final-vault/security-spi/common/src/main/java/org/jboss/security/PicketBoxLogger.java	2013-04-12 09:36:17 UTC (rev 402)
+++ branches/embargo/4.0.16.Final-vault/security-spi/common/src/main/java/org/jboss/security/PicketBoxLogger.java	2013-04-16 15:42:36 UTC (rev 403)
@@ -688,4 +688,25 @@
     @Message(id = 366, value = "Error parsing time out number.")
     void errorParsingTimeoutNumber();
 
+    @LogMessage(level = Logger.Level.DEBUG)
+    @Message(id = 367, value = "Reading security vault data version %s target version is %s")
+    void securityVaultContentVersion(String dataVersion, String targetVersion);
+
+    @LogMessage(level = Logger.Level.ERROR)
+    @Message(id = 368, value = "Security Vault contains both covnerted (%s) and pre-conversion data (%s). Try to delete %s file and start over again.")
+    void mixedVaultDataFound(String vaultDatFile, String encDatFile, String encDatFile2);
+
+    @LogMessage(level = Logger.Level.INFO)
+    @Message(id = 369, value = "Ambiguos vault block and attribute name stored in original security vault. Delimiter (%s) is part of vault block or attribute name. Took the first delimiter. Result vault block (%s) attribute name (%s). Modify security vault manually.")
+    void ambiguosKeyForSecurityVaultTransformation(String delimiter, String vaultBlock, String attributeName);
+
+    @LogMessage(level = Logger.Level.WARN)
+    @Message(id = 370, value = "Cannot delete original security vault file (%s). Delete the file manually before next start, please.")
+    void cannotDeleteOriginalVaultFile(String file);
+
+    @LogMessage(level = Logger.Level.INFO)
+    @Message(id = 371, value = "Security Vault does not contain SecretKey entry under alias (%s)")
+    void vaultDoesnotContainSecretKey(String alias);
+
+
 }
\ No newline at end of file

Modified: branches/embargo/4.0.16.Final-vault/security-spi/common/src/main/java/org/jboss/security/PicketBoxMessages.java
===================================================================
--- branches/embargo/4.0.16.Final-vault/security-spi/common/src/main/java/org/jboss/security/PicketBoxMessages.java	2013-04-12 09:36:17 UTC (rev 402)
+++ branches/embargo/4.0.16.Final-vault/security-spi/common/src/main/java/org/jboss/security/PicketBoxMessages.java	2013-04-16 15:42:36 UTC (rev 403)
@@ -424,8 +424,8 @@
     @Message(id = 129, value = "Unable to write shared key file")
     String unableToWriteShareKeyFileMessage();
 
-    @Message(id = 130, value = "Unable to write encoded file")
-    String unableToWriteEncodedFileMessage();
+    @Message(id = 130, value = "Unable to write vault data file (%s)")
+    String unableToWriteVaultDataFileMessage(String fileName);
 
     @Message(id = 131, value = "Vault mismatch: shared key does not match for vault block %s and attribute name %s")
     String sharedKeyMismatchMessage(String vaultBlock, String attributeName);
@@ -435,4 +435,23 @@
 
     @Message(id = 133, value = "Failed to match %s and %s")
     RuntimeException failedToMatchStrings(String one, String two);
+
+    @Message(id = 134, value = "Unrecognized security vault content version (%s), expecting (from %s to %s)")
+    RuntimeException unrecognizedVaultContentVersion(String readVersion, String fromVersion, String toVersion);
+
+    @Message(id = 135, value = "Security Vault contains both covnerted (%s) and pre-conversion data (%s), failed to load vault")
+    RuntimeException mixedVaultDataFound(String vaultDatFile, String encDatFile);
+
+    @Message(id = 136, value = "Security Vault conversion unsuccessful missing admin key in original vault data")
+    RuntimeException missingAdminKeyInOriginalVaultData();
+
+    @Message(id = 137, value = "Security Vault does not contain SecretKey entry under alias (%s)")
+    RuntimeException vaultDoesnotContainSecretKey(String alias);
+    
+    @Message(id = 138, value = "There is no SecretKey under the alias (%s) and the alias is already used to denote diffrent crypto object in the keystore.")
+    RuntimeException noSecretKeyandAliasAlreadyUsed(String alias);
+
+    @Message(id = 139, value = "Unable to store keystore to file (%s)")
+    RuntimeException unableToStoreKeyStoreToFile(@Cause Throwable throwable, String file);
+
 }
\ No newline at end of file



More information about the jboss-cvs-commits mailing list