[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