[jboss-cvs] Picketbox SVN: r245 - in trunk: security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins and 8 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Aug 15 19:05:57 EDT 2011


Author: anil.saldhana at jboss.com
Date: 2011-08-15 19:05:57 -0400 (Mon, 15 Aug 2011)
New Revision: 245

Added:
   trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/
   trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/
   trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/PicketBoxSecurityVault.java
   trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/
   trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/EncryptionUtil.java
   trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/KeyStoreUtil.java
   trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/SecurityActions.java
   trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/StringUtil.java
   trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/
   trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/EncryptionUtilUnitTestCase.java
   trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/SecurityVaultUnitTestCase.java
   trunk/security-jboss-sx/jbosssx/src/test/resources/keystore/
   trunk/security-jboss-sx/jbosssx/src/test/resources/keystore/readme.txt
   trunk/security-jboss-sx/jbosssx/src/test/resources/keystore/vault.keystore
   trunk/security-spi/spi/src/main/java/org/jboss/security/vault/
   trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityActions.java
   trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVault.java
   trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVaultException.java
   trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVaultFactory.java
Log:
SECURITY-615: vault to hold attribute values

Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/PicketBoxSecurityVault.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/PicketBoxSecurityVault.java	                        (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/plugins/vault/PicketBoxSecurityVault.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,412 @@
+/*
+ * 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 java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+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;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.jboss.logging.Logger;
+import org.jboss.security.plugins.PBEUtils;
+import org.jboss.security.vault.SecurityVault;
+import org.jboss.security.vault.SecurityVaultException;
+import org.jboss.util.Base64;
+import org.picketbox.util.EncryptionUtil;
+import org.picketbox.util.KeyStoreUtil;
+import org.picketbox.util.StringUtil;
+
+/**
+ * An instance of {@link SecurityVault} that uses
+ * a {@link KeyStore} and the package of the calling class to determine
+ * the shared key
+ * @author Anil.Saldhana at redhat.com
+ * @since Aug 12, 2011
+ */
+public class PicketBoxSecurityVault implements SecurityVault
+{
+   protected static Logger log = Logger.getLogger(PicketBoxSecurityVault.class);
+   
+   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)
+         throw new SecurityVaultException("Options is null");
+      
+      if(options.isEmpty())
+         throw new SecurityVaultException("Options is empty");
+      
+      String keystoreURL = (String) options.get(KEYSTORE_URL);
+      if(keystoreURL == null)
+         throw new SecurityVaultException("Null " + KEYSTORE_URL); 
+      
+      String maskedPassword = (String) options.get(KEYSTORE_PASSWORD);
+      if(maskedPassword == null)
+         throw new SecurityVaultException("Null masked keystore password");
+      if(maskedPassword.startsWith(PASS_MASK_PREFIX) == false)
+         throw new SecurityVaultException("Keystore password is not masked");
+   
+      String salt = (String) options.get(SALT);
+      if(salt == null)
+         throw new SecurityVaultException("Salt is null");
+      
+      String iterationCountStr = (String) options.get(ITERATION_COUNT);
+      if(iterationCountStr == null)
+         throw new SecurityVaultException("Iteration Count is not set");
+      int iterationCount = Integer.parseInt(iterationCountStr);
+      
+      String alias = (String) options.get(KEYSTORE_ALIAS);
+      if(alias == null)
+         throw new SecurityVaultException("Keystore Alias is null");
+      
+      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("Option ENC_FILE_DIR is missing");
+
+      try
+      {
+         decodedEncFileDir = StringUtil.getSystemPropertyAsString(encFileDir);
+         if(directoryExists(decodedEncFileDir) == false)
+            throw new SecurityVaultException(decodedEncFileDir + " does not exist");
+         
+         if(!(decodedEncFileDir.endsWith("/") || decodedEncFileDir.endsWith("\\")))
+         {
+            throw new SecurityVaultException(decodedEncFileDir + "does not end with / or \\");
+         }
+         if(encodedFileExists(decodedEncFileDir) ==false)
+         {
+            setUpVault(decodedEncFileDir);
+         }
+         
+         FileInputStream fis = new FileInputStream(decodedEncFileDir + ENCODED_FILE);
+         ObjectInputStream ois = new ObjectInputStream(fis);
+         theContent = (Map<String, byte[]>) ois.readObject();
+
+         FileInputStream mapFile = new FileInputStream(decodedEncFileDir + SHARED_KEY_FILE );
+         ObjectInputStream mapIS = new ObjectInputStream(mapFile);
+         
+         sharedKeyMap = (Map<String, byte[]>) mapIS.readObject();
+      }
+      catch (Exception e)
+      { 
+         throw new SecurityVaultException(e); 
+      }
+
+      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("Unable to get Keystore:",e);
+      }
+      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)
+         throw new SecurityVaultException("Options is null");
+      
+      if(handshakeOptions.isEmpty())
+         throw new SecurityVaultException("Options is empty");
+      
+      String publicCert = (String) handshakeOptions.get(PUBLIC_CERT);
+      if(publicCert == null)
+         throw new SecurityVaultException("Public Cert is null");
+      
+      try
+      {
+         PublicKey publicKey = KeyStoreUtil.getPublicKey(keystore, publicCert, keyStorePWD);
+         if(publicKey == null)
+            throw new SecurityVaultException("Could not retrieve Public Key from KeyStore for alias:" + 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()).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 new SecurityVaultException("vaultBlock is null");
+      if(StringUtil.isNullOrEmpty(attributeName))
+         throw new SecurityVaultException("attributeName is null");
+      
+      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("Shared Key is invalid");
+      
+      String alias = decodedSharedKey.substring(index + LINE_BREAK.length());
+      
+      Certificate cert;
+      try
+      {
+         cert = keystore.getCertificate(alias);
+      }
+      catch (KeyStoreException e1)
+      { 
+         throw new SecurityVaultException("Cannot get certificate:",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("Unable to encrypt data:",e1);
+      }
+      try
+      {
+         writeSharedKeyFile(this.decodedEncFileDir);
+      }
+      catch (IOException e)
+      { 
+         throw new SecurityVaultException("Unable to write Shared Key File");
+      }
+      try
+      {
+         writeEncodedFile(this.decodedEncFileDir);
+      }
+      catch (IOException e)
+      { 
+         throw new SecurityVaultException("Unable to write Encoded File");
+      }
+   }
+
+   /*
+    * @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 new SecurityVaultException("vaultBlock is null");
+      if(StringUtil.isNullOrEmpty(attributeName))
+         throw new SecurityVaultException("attributeName is null");
+      
+      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("Shared Key does not match for vault block:" + vaultBlock + " and attributeName:" + 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("Decryption of value failed:",e);
+      } 
+   }
+    
+   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 = new FileOutputStream(decodedEncFileDir + ENCODED_FILE);
+      ObjectOutputStream oos = new ObjectOutputStream(fos);
+      oos.writeObject(theContent);
+      oos.close();
+   }
+   
+   private void writeSharedKeyFile(String decodedEncFileDir) throws IOException
+   {
+      FileOutputStream fos = new FileOutputStream(decodedEncFileDir + SHARED_KEY_FILE);
+      ObjectOutputStream oos = new ObjectOutputStream(fos);
+      oos.writeObject(sharedKeyMap);
+      oos.close(); 
+   }
+   
+   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();
+   }
+}
\ No newline at end of file

Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/EncryptionUtil.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/EncryptionUtil.java	                        (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/EncryptionUtil.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,112 @@
+/*
+ * 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.util;
+
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Encryption/Decryption utility
+ * @author Anil.Saldhana at redhat.com
+ * @since Aug 12, 2011
+ */
+public class EncryptionUtil
+{
+   private String encryptionAlgorithm;
+   private int keySize;
+
+   public EncryptionUtil(String encryptionAlgorithm, int keySize)
+   {
+      this.encryptionAlgorithm = encryptionAlgorithm;
+      this.keySize = keySize;
+   }
+   
+   public SecretKey generateKey() throws NoSuchAlgorithmException
+   {
+      KeyGenerator kgen = KeyGenerator.getInstance(encryptionAlgorithm);
+      kgen.init(keySize);
+      SecretKey key = kgen.generateKey();
+      return key;
+   }
+   
+   public byte[] encrypt(byte[] data, PublicKey publicKey, 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);
+
+      cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
+
+      byte[] encrypted =
+        cipher.doFinal( data);
+      return encrypted;
+   }
+   
+   public byte[] decrypt(byte[] encryptedData, KeyPair keypair, 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);
+    
+      cipher.init(Cipher.DECRYPT_MODE, keySpec);
+      byte[] original = cipher.doFinal(encryptedData); 
+      return original;
+   }
+   
+   public byte[] decrypt(byte[] encryptedData, KeyPair keypair, SecretKey key ) throws Exception
+   {
+      // Get the KeyGenerator
+      KeyGenerator kgen = KeyGenerator.getInstance(this.encryptionAlgorithm);
+      kgen.init(keySize);
+ 
+      byte[] publicKeyEncoded = keypair.getPrivate().getEncoded();
+
+      SecretKeySpec skeySpec = new SecretKeySpec(key.getEncoded(), encryptionAlgorithm);
+
+      // Instantiate the cipher 
+      Cipher cipher = Cipher.getInstance(encryptionAlgorithm);
+    
+      cipher.init(Cipher.DECRYPT_MODE, skeySpec);
+      byte[] original = cipher.doFinal(encryptedData); 
+      return original;
+   }
+}
\ No newline at end of file

Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/KeyStoreUtil.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/KeyStoreUtil.java	                        (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/KeyStoreUtil.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,210 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, 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.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.Certificate;
+ 
+
+/**
+ * Utility to handle Java Keystore
+ * @author Anil.Saldhana at redhat.com
+ * @since Jan 12, 2009
+ */
+public class KeyStoreUtil
+{
+   /**
+    * Get the KeyStore
+    * @param keyStoreFile
+    * @param storePass
+    * @return
+    * @throws GeneralSecurityException
+    * @throws IOException
+    */
+   public static KeyStore getKeyStore(File keyStoreFile, char[] storePass) throws GeneralSecurityException, IOException
+   {
+      FileInputStream fis = new FileInputStream(keyStoreFile);
+      return getKeyStore(fis, storePass);
+   }
+
+   /**
+    * Get the Keystore given the url to the keystore file as a string
+    * @param fileURL
+    * @param storePass 
+    * @return
+    * @throws GeneralSecurityException
+    * @throws IOException
+    */
+   public static KeyStore getKeyStore(String fileURL, char[] storePass) throws GeneralSecurityException, IOException
+   {
+      if (fileURL == null)
+         throw new IllegalArgumentException( "Null fileURL");
+
+      File file = new File(fileURL);
+      FileInputStream fis = new FileInputStream(file);
+      return getKeyStore(fis, storePass);
+   }
+
+   /**
+    * Get the Keystore given the URL to the keystore
+    * @param url
+    * @param storePass
+    * @return
+    * @throws GeneralSecurityException
+    * @throws IOException
+    */
+   public static KeyStore getKeyStore(URL url, char[] storePass) throws GeneralSecurityException, IOException
+   {
+      if (url == null)
+         throw new IllegalArgumentException("Null url");
+
+      return getKeyStore(url.openStream(), storePass);
+   }
+
+   /**
+    * Get the Key Store
+    * <b>Note:</b> This method wants the InputStream to be not null. 
+    * @param ksStream
+    * @param storePass
+    * @return
+    * @throws GeneralSecurityException
+    * @throws IOException
+    * @throws IllegalArgumentException if ksStream is null
+    */
+   public static KeyStore getKeyStore(InputStream ksStream, char[] storePass) throws GeneralSecurityException,
+         IOException
+   {
+      if (ksStream == null)
+         throw new IllegalArgumentException( "Null InputStream for the KeyStore");
+      KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+      ks.load(ksStream, storePass);
+      return ks;
+   }
+
+   /**
+    * Generate a Key Pair
+    * @param algo (RSA, DSA etc)
+    * @return
+    * @throws GeneralSecurityException 
+    */
+   public static KeyPair generateKeyPair(String algo) throws GeneralSecurityException
+   {
+      KeyPairGenerator kpg = KeyPairGenerator.getInstance(algo);
+      return kpg.genKeyPair();
+   }
+
+   /**
+    * Get the Public Key from the keystore
+    * @param ks
+    * @param alias
+    * @param password
+    * @return 
+    * @throws GeneralSecurityException  
+    */
+   public static PublicKey getPublicKey(KeyStore ks, String alias, char[] password) throws KeyStoreException,
+         NoSuchAlgorithmException, GeneralSecurityException
+   {
+      PublicKey publicKey = null;
+
+      // Get private key
+      Key key = ks.getKey(alias, password);
+      if (key instanceof PrivateKey)
+      {
+         // Get certificate of public key
+         Certificate cert = ks.getCertificate(alias);
+
+         // Get public key
+         publicKey = cert.getPublicKey();
+      }
+      // if alias is a certificate alias, get the public key from the certificate.
+      if (publicKey == null)
+      {
+         Certificate cert = ks.getCertificate(alias);
+         if (cert != null)
+            publicKey = cert.getPublicKey();
+      }
+      return publicKey;
+   }
+
+   /**
+    * Add a certificate to the KeyStore
+    * @param keystoreFile
+    * @param storePass
+    * @param alias
+    * @param cert
+    * @throws GeneralSecurityException
+    * @throws IOException
+    */
+   public static void addCertificate(File keystoreFile, char[] storePass, String alias, Certificate cert)
+         throws GeneralSecurityException, IOException
+   {
+      KeyStore keystore = getKeyStore(keystoreFile, storePass);
+
+      // Add the certificate
+      keystore.setCertificateEntry(alias, cert);
+
+      // Save the new keystore contents
+      FileOutputStream out = new FileOutputStream(keystoreFile);
+      keystore.store(out, storePass);
+      out.close();
+   }
+
+   /**
+    * Get the key pair from the keystore
+    * @param keystore
+    * @param alias
+    * @param password
+    * @return
+    * @throws Exception
+    */
+   public static KeyPair getPrivateKey(KeyStore keystore, String alias, char[] password) throws Exception
+   { 
+      // Get private key
+      Key key = keystore.getKey(alias, password);
+      if (key instanceof PrivateKey) 
+      {
+         // Get certificate of public key
+         java.security.cert.Certificate cert = keystore.getCertificate(alias);
+
+         // Get public key
+         PublicKey publicKey = cert.getPublicKey();
+
+         // Return a key pair
+         return new KeyPair(publicKey, (PrivateKey)key);
+      }
+      return null;
+   }
+}
\ No newline at end of file

Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/SecurityActions.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/SecurityActions.java	                        (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/SecurityActions.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,134 @@
+/*
+ * 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.util;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * @author Anil.Saldhana at redhat.com
+ * @since Dec 9, 2008
+ */
+class SecurityActions
+{
+   static Class<?> loadClass(final Class<?> theClass, final String fqn)
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<Class<?>>()
+      {
+         public Class<?> run()
+         {
+            ClassLoader classLoader = theClass.getClassLoader();
+
+            Class<?> clazz = loadClass(classLoader, fqn);
+            if (clazz == null)
+            {
+               classLoader = Thread.currentThread().getContextClassLoader();
+               clazz = loadClass(classLoader, fqn);
+            }
+            return clazz;
+         }
+      });
+   }
+
+   static Class<?> loadClass(final ClassLoader cl, final String fqn)
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<Class<?>>()
+      {
+         public Class<?> run()
+         {
+            try
+            {
+               return cl.loadClass(fqn);
+            }
+            catch (ClassNotFoundException e)
+            {
+            }
+            return null;
+         }
+      });
+   }
+
+   /**
+    * Set the system property
+    * @param key
+    * @param defaultValue
+    * @return
+    */
+   static void setSystemProperty(final String key, final String value)
+   {
+      AccessController.doPrivileged(new PrivilegedAction<Object>()
+      {
+         public Object run()
+         {
+            System.setProperty(key, value);
+            return null;
+         }
+      });
+   }
+
+   /**
+    * Get the system property
+    * @param key
+    * @param defaultValue
+    * @return
+    */
+   static String getSystemProperty(final String key, final String defaultValue)
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<String>()
+      {
+         public String run()
+         {
+            return System.getProperty(key, defaultValue);
+         }
+      });
+   }
+
+   /**
+    * Load a resource based on the passed {@link Class} classloader.
+    * Failing which try with the Thread Context CL
+    * @param clazz
+    * @param resourceName
+    * @return
+    */
+   static URL loadResource(final Class<?> clazz, final String resourceName)
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<URL>()
+      {
+         public URL run()
+         {
+            URL url = null;
+            ClassLoader clazzLoader = clazz.getClassLoader();
+            url = clazzLoader.getResource(resourceName);
+
+            if (url == null)
+            {
+               clazzLoader = Thread.currentThread().getContextClassLoader();
+               url = clazzLoader.getResource(resourceName);
+            }
+
+            return url;
+         }
+      });
+   }
+}
\ No newline at end of file

Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/StringUtil.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/StringUtil.java	                        (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/picketbox/util/StringUtil.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,179 @@
+/*
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec; 
+
+import org.jboss.security.plugins.PBEUtils;
+
+/**
+ * Utility dealing with Strings
+ * @author Anil.Saldhana at redhat.com
+ * @since Oct 21, 2009
+ */
+public class StringUtil
+{
+   /**
+    * Check whether the passed string is null or empty
+    * @param str
+    * @return
+    */
+   public static boolean isNotNull(String str)
+   {
+      return str != null && !"".equals(str.trim());
+   }
+
+   /**
+    * Check whether the string is null or empty
+    * @param str
+    * @return
+    */
+   public static boolean isNullOrEmpty(String str)
+   {
+      return str == null || str.isEmpty();
+   }
+
+   /**
+    * <p>
+    * Get the system property value if the string is of the format ${sysproperty}
+    * </p>
+    * <p>
+    * You can insert default value when the system property is not set, by
+    * separating it at the beginning with ::
+    * </p>
+    * <p>
+    * <b>Examples:</b>
+    * </p>
+    * 
+    * <p>
+    * ${idp} should resolve to a value if the system property "idp" is set.
+    * </p>
+    * <p>
+    * ${idp::http://localhost:8080} will resolve to http://localhost:8080 if the system property "idp" is not set.
+    * </p>
+    * @param str
+    * @return
+    */
+   public static String getSystemPropertyAsString(String str)
+   {
+      if (str == null)
+         throw new IllegalArgumentException("Null str");
+      if (str.contains("${"))
+      {
+         Pattern pattern = Pattern.compile("\\$\\{([^}]+)}");
+         Matcher matcher = pattern.matcher(str);
+
+         StringBuffer buffer = new StringBuffer();
+         String sysPropertyValue = null;
+
+         while (matcher.find())
+         {
+            String subString = matcher.group(1);
+            String defaultValue = "";
+
+            //Look for default value
+            if (subString.contains("::"))
+            {
+               int index = subString.indexOf("::");
+               defaultValue = subString.substring(index + 2);
+               subString = subString.substring(0, index);
+            }
+            sysPropertyValue = SecurityActions.getSystemProperty(subString, defaultValue);
+            if (sysPropertyValue.isEmpty())
+            {
+               throw new IllegalArgumentException("System Property missing:" + matcher.group(1));
+            }
+            matcher.appendReplacement(buffer, sysPropertyValue);
+         }
+
+         matcher.appendTail(buffer);
+         str = buffer.toString();
+      }
+      return str;
+   }
+
+   /**
+    * Match two strings else throw a {@link RuntimeException}
+    * @param first
+    * @param second
+    */
+   public static void match(String first, String second)
+   {
+      if (first.equals(second) == false)
+         throw new RuntimeException("Match failed:" + first + " and " + second);
+   }
+
+   /**
+    * Given a comma separated string, get the tokens as a {@link List}
+    * @param str
+    * @return
+    */
+   public static List<String> tokenize(String str)
+   {
+      List<String> list = new ArrayList<String>();
+      StringTokenizer tokenizer = new StringTokenizer(str, ",");
+      while (tokenizer.hasMoreTokens())
+      {
+         list.add(tokenizer.nextToken());
+      }
+      return list;
+   }
+
+   /**
+    * Given a masked password {@link String}, decode it
+    * @param maskedString a password string that is masked
+    * @param salt Salt
+    * @param iterationCount Iteration Count
+    * @return Decoded String
+    * @throws Exception
+    */
+   public static String decode(String maskedString, String salt, int iterationCount) throws Exception
+   {
+      String PASS_MASK_PREFIX = "MASK-";
+      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;
+   }
+}
\ No newline at end of file

Added: trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/EncryptionUtilUnitTestCase.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/EncryptionUtilUnitTestCase.java	                        (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/EncryptionUtilUnitTestCase.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,67 @@
+/*
+ * 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.jboss.test.security.vault;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.PublicKey;
+
+import javax.crypto.SecretKey;
+
+import org.junit.Test;
+import org.picketbox.util.EncryptionUtil;
+import org.picketbox.util.KeyStoreUtil;
+
+/**
+ * Unit test {@link EncryptionUtil}
+ * @author Anil.Saldhana at redhat.com
+ * @since Aug 12, 2011
+ */
+public class EncryptionUtilUnitTestCase
+{
+   String keyStoreURL = "src/test/resources/keystore/vault.keystore";
+   String keyStorePass = "vault22";
+   String alias = "vault";
+   
+   @Test
+   public void testEncryptDecrypt() throws Exception
+   {
+      KeyStore ks = KeyStoreUtil.getKeyStore(keyStoreURL, keyStorePass.toCharArray());
+      assertNotNull(ks);
+      EncryptionUtil encUtil = new EncryptionUtil("AES", 128);
+      
+      PublicKey publicKey = KeyStoreUtil.getPublicKey(ks, "vault", keyStorePass.toCharArray());
+      assertNotNull(publicKey);
+      
+      SecretKey secretKey = encUtil.generateKey();
+      
+      byte[] encryptedData = encUtil.encrypt(keyStorePass.getBytes(), publicKey, secretKey);
+      
+      KeyPair keypair = KeyStoreUtil.getPrivateKey(ks, alias, keyStorePass.toCharArray());
+      byte[] decryptedData = encUtil.decrypt(encryptedData, keypair, secretKey);
+      assertEquals(keyStorePass, new String(decryptedData));
+   }
+
+}
\ No newline at end of file

Added: trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/SecurityVaultUnitTestCase.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/SecurityVaultUnitTestCase.java	                        (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/security/vault/SecurityVaultUnitTestCase.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,195 @@
+/*
+ * 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.jboss.test.security.vault;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+import org.jboss.security.plugins.PBEUtils;
+import org.jboss.security.vault.SecurityVault;
+import org.jboss.security.vault.SecurityVaultException;
+import org.jboss.security.vault.SecurityVaultFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.picketbox.plugins.vault.PicketBoxSecurityVault;
+import org.picketbox.util.StringUtil;
+
+/**
+ * Unit Test the {@link SecurityVault} Implementation
+ * @author Anil.Saldhana at redhat.com
+ * @since Aug 12, 2011
+ */
+public class SecurityVaultUnitTestCase
+{ 
+   String salt = "12438567";
+   int iterationCount = 50; 
+   
+   String keyStorePass = "vault22";
+   
+   String maskedPWD;
+   
+   String dataDir = "${java.io.tmpdir}/enc/";
+   
+   @Before
+   public void setup() throws Exception
+   {
+      String dir = StringUtil.getSystemPropertyAsString(dataDir);
+      File encDir = new File(dir);
+      
+      if(encDir.exists() == false)
+         encDir.mkdirs();
+      
+      File encFile = new File(dir + "/enc.dat");
+      if(encFile.exists())
+         encFile.delete();
+   }
+   
+   @Test
+   public void testDefaultVault() throws Exception
+   {
+      SecurityVault vault = SecurityVaultFactory.get();
+      assertNotNull(vault);
+      assertTrue(vault instanceof PicketBoxSecurityVault);
+      assertFalse(vault.isInitialized());
+   }
+   
+   @Test
+   public void testInitialization() throws Exception
+   {
+      SecurityVault vault = SecurityVaultFactory.get();
+      assertNotNull(vault);
+      assertTrue(vault instanceof PicketBoxSecurityVault);
+      assertFalse(vault.isInitialized());
+      
+      Map<String,Object> options = new HashMap<String,Object>();
+      try
+      {
+         vault.init(options);
+         fail("Should have thrown error"); 
+      }
+      catch(SecurityVaultException sve)
+      {   
+      }
+      maskedPWD = getMaskedPassword(keyStorePass, salt,iterationCount);
+      
+      options.putAll(getMap());
+      vault.init(options);
+      
+      assertTrue(vault.isInitialized());
+   }
+   
+   @Test
+   public void testHandshake() throws Exception
+   {
+      SecurityVault vault = SecurityVaultFactory.get(); 
+      Map<String,Object> options = new HashMap<String,Object>(); 
+      maskedPWD = getMaskedPassword(keyStorePass, salt,iterationCount);
+
+      options.putAll(getMap());
+      
+      vault.init(options);
+      assertTrue(vault.isInitialized());
+      
+      Map<String,Object> handshakeOptions = new HashMap<String,Object>();
+      handshakeOptions.put(PicketBoxSecurityVault.PUBLIC_CERT,"vault");
+      
+      byte[] sharedKey = vault.handshake(handshakeOptions);
+      assertNotNull(sharedKey);
+   }
+   
+   @Test
+   public void testStoreAndRetrieve() throws Exception
+   {
+      String vaultBlock = "SecBean";
+      String attributeName = "theAttribute";
+      
+      char[] attributeValue = "someValue".toCharArray();
+      
+      SecurityVault vault = SecurityVaultFactory.get(); 
+      Map<String,Object> options = new HashMap<String,Object>(); 
+      maskedPWD = getMaskedPassword(keyStorePass, salt,iterationCount);
+
+      options.putAll(getMap());
+      
+      vault.init(options);
+      assertTrue(vault.isInitialized());
+      
+      Map<String,Object> handshakeOptions = new HashMap<String,Object>();
+      handshakeOptions.put(PicketBoxSecurityVault.PUBLIC_CERT,"vault");
+      
+      byte[] sharedKey = vault.handshake(handshakeOptions);
+      assertNotNull(sharedKey);
+      
+      vault.store(vaultBlock, attributeName, attributeValue , sharedKey);
+      
+      //Now retrieve 
+      assertEquals(new String(attributeValue), new String(vault.retrieve(vaultBlock, attributeName, sharedKey))); 
+      
+      vault.store(vaultBlock+"1", attributeName+"2", attributeValue , sharedKey);
+      assertEquals(new String(attributeValue), new String(vault.retrieve(vaultBlock+"1", attributeName+"2", sharedKey))); 
+      
+      System.out.println("Currently storing:" + vault.keyList());
+   }
+   
+   private String getMaskedPassword(String pwd, String salt, int iterationCount) throws Exception
+   {
+      String algo = "PBEwithMD5andDES";
+      
+      // Create the PBE secret key 
+      SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEwithMD5andDES");
+
+      char[] password = "somearbitrarycrazystringthatdoesnotmatter".toCharArray();
+      PBEParameterSpec cipherSpec = new PBEParameterSpec(salt.getBytes(), iterationCount);
+      PBEKeySpec keySpec = new PBEKeySpec(password);
+      SecretKey cipherKey = factory.generateSecret(keySpec);
+      
+      String maskedPass = PBEUtils.encode64(pwd.getBytes(), algo, cipherKey, cipherSpec);
+      
+      return new String(PicketBoxSecurityVault.PASS_MASK_PREFIX) + maskedPass; 
+   }
+   
+   private Map<String,Object> getMap()
+   { 
+      Map<String,Object> options = new HashMap<String,Object>();
+      options.put(PicketBoxSecurityVault.KEYSTORE_URL, "src/test/resources/keystore/vault.keystore");
+      options.put(PicketBoxSecurityVault.KEYSTORE_PASSWORD, maskedPWD);
+      options.put(PicketBoxSecurityVault.KEYSTORE_ALIAS, "vault");
+      options.put(PicketBoxSecurityVault.SALT, salt);
+      options.put(PicketBoxSecurityVault.ITERATION_COUNT, "" + iterationCount);
+
+      options.put(PicketBoxSecurityVault.ENC_FILE_DIR,dataDir);
+      
+      return options;
+   }
+}
\ No newline at end of file

Added: trunk/security-jboss-sx/jbosssx/src/test/resources/keystore/readme.txt
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/test/resources/keystore/readme.txt	                        (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/test/resources/keystore/readme.txt	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,22 @@
+
+anil at localhost:~/picketbox/trunk/security-jboss-sx/jbosssx/src/test/resources/keystore$ keytool -genkey -alias vault -keyalg RSA -keysize 1024  -keystore vault.keystore -storetype JCEKS
+Enter keystore password: vault22 
+Re-enter new password:vault22 
+What is your first and last name?
+  [Unknown]:  Picketbox vault
+What is the name of your organizational unit?
+  [Unknown]:  picketbox
+What is the name of your organization?
+  [Unknown]:  JBoss
+What is the name of your City or Locality?
+  [Unknown]:  chicago
+What is the name of your State or Province?
+  [Unknown]:  il
+What is the two-letter country code for this unit?
+  [Unknown]:  us
+Is CN=Picketbox vault, OU=picketbox, O=JBoss, L=chicago, ST=il, C=us correct?
+  [no]:  yes
+
+Enter key password for <vault>
+        (RETURN if same as keystore password):  
+

Added: trunk/security-jboss-sx/jbosssx/src/test/resources/keystore/vault.keystore
===================================================================
(Binary files differ)


Property changes on: trunk/security-jboss-sx/jbosssx/src/test/resources/keystore/vault.keystore
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityActions.java
===================================================================
--- trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityActions.java	                        (rev 0)
+++ trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityActions.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,64 @@
+/*
+ * 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.jboss.security.vault;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * @author Anil.Saldhana at redhat.com
+ * @since Aug 12, 2011
+ */
+public class SecurityActions
+{
+   static Class<?> loadClass(final Class<?> clazz, final String fqn)
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<Class<?>>()
+      {
+         public Class<?> run()
+         {
+            ClassLoader cl = clazz.getClassLoader();
+            Class<?> loadedClass = null;
+            try
+            {
+               loadedClass = cl.loadClass(fqn);
+            }
+            catch (ClassNotFoundException e)
+            { 
+            }
+            if(loadedClass == null)
+            {
+               try
+               {
+                  loadedClass = Thread.currentThread().getContextClassLoader().loadClass(fqn);
+               }
+               catch (ClassNotFoundException e)
+               {   
+               } 
+            }
+            return loadedClass;
+         }
+      });
+      
+   }
+}
\ No newline at end of file

Added: trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVault.java
===================================================================
--- trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVault.java	                        (rev 0)
+++ trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVault.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,80 @@
+/*
+ * 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.jboss.security.vault;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Vault for secure storage of attributes
+ * @author Anil.Saldhana at redhat.com
+ * @since Aug 12, 2011
+ */
+public interface SecurityVault
+{
+   /**
+    * Initialize the vault
+    * @param options
+    */
+   void init(Map<String,Object> options) throws SecurityVaultException;
+   
+   /**
+    * Determine if the vault is initialized
+    * @return
+    */
+   boolean isInitialized();
+
+   /**
+    * Retrieve the shared key from the vault
+    * @param handshakeOptions a set of options that the vault identifies for handshake
+    * @return
+    * @throws SecurityVaultException
+    */
+   byte[] handshake(Map<String,Object> handshakeOptions) throws SecurityVaultException;
+   
+   /**
+    * Get the currently vaulted VaultBlock_attribute Names
+    * @return
+    * @throws SecurityVaultException
+    */
+   Set<String> keyList() throws SecurityVaultException;
+   
+   /**
+    * Store an attribute value
+    * @param vaultBlock a string value that brings in the uniqueness
+    * @param attributeName name of the attribute
+    * @param attributeValue
+    * @param sharedKey
+    * @throws SecurityVaultException
+    */
+   void store(String vaultBlock, String attributeName,char[] attributeValue, byte[] sharedKey) throws SecurityVaultException;
+
+   /**
+    * Retrieve the attribute value
+    * @param vaultBlock
+    * @param attributeName
+    * @param sharedKey
+    * @return
+    * @throws SecurityVaultException
+    */
+   char[] retrieve(String vaultBlock, String attributeName, byte[] sharedKey) throws SecurityVaultException; 
+}
\ No newline at end of file

Added: trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVaultException.java
===================================================================
--- trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVaultException.java	                        (rev 0)
+++ trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVaultException.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,54 @@
+/*
+ * 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.jboss.security.vault;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * General exception thrown from the vault operations
+ * @author Anil.Saldhana at redhat.com
+ * @since Aug 12, 2011
+ */
+public class SecurityVaultException extends GeneralSecurityException
+{
+   private static final long serialVersionUID = -463686701228652165L;
+
+   public SecurityVaultException()
+   {
+      super(); 
+   }
+
+   public SecurityVaultException(String message, Throwable cause)
+   {
+      super(message, cause); 
+   }
+
+   public SecurityVaultException(String msg)
+   {
+      super(msg); 
+   }
+
+   public SecurityVaultException(Throwable cause)
+   {
+      super(cause); 
+   }
+}
\ No newline at end of file

Added: trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVaultFactory.java
===================================================================
--- trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVaultFactory.java	                        (rev 0)
+++ trunk/security-spi/spi/src/main/java/org/jboss/security/vault/SecurityVaultFactory.java	2011-08-15 23:05:57 UTC (rev 245)
@@ -0,0 +1,70 @@
+/*
+ * 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.jboss.security.vault;
+
+/**
+ * A factory to instantiate a {@link SecurityVault}
+ * @author Anil.Saldhana at redhat.com
+ * @since Aug 12, 2011
+ */
+public class SecurityVaultFactory
+{
+   private static String defaultVault = "org.picketbox.plugins.vault.PicketBoxSecurityVault";
+   private static SecurityVault vault= null;
+   
+   /**
+    * Get an instance of {@link SecurityVault}
+    * Remember to initialize the vault by checking {@link SecurityVault#isInitialized()}
+    * @return an instance of {@link SecurityVault}
+    * @throws SecurityVaultException
+    */
+   public static SecurityVault get() throws SecurityVaultException
+   {
+      return get(defaultVault);
+   }
+   
+   /**
+    * Get an instance of {@link SecurityVault}
+    * Remember to initialize the vault by checking {@link SecurityVault#isInitialized()}
+    * @param fqn fully qualified name of the vault implementation
+    * @return an instance of {@link SecurityVault}
+    * @throws SecurityVaultException
+    */
+   public static SecurityVault get(String fqn) throws SecurityVaultException
+   {
+      if(vault == null)
+      {
+         Class<?> vaultClass = SecurityActions.loadClass(SecurityVaultFactory.class,fqn);
+         if(vaultClass == null)
+            throw new SecurityVaultException("Unable to create vault:class is null");
+         try
+         {
+            vault = (SecurityVault) vaultClass.newInstance();
+         }
+         catch (Exception e)
+         {
+            throw new SecurityVaultException("Unable to create vault:not instantiated",e);
+         }
+      }
+      return vault;
+   }
+}
\ No newline at end of file



More information about the jboss-cvs-commits mailing list