[jboss-cvs] JBossAS SVN: r114602 - in projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src: test/java/org/jboss/test and 3 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Dec 17 06:53:32 EST 2013
Author: pskopek
Date: 2013-12-17 06:53:32 -0500 (Tue, 17 Dec 2013)
New Revision: 114602
Added:
projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/security/vault/KeystorePasswordProvider.java
projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/resources/bin/
projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/resources/bin/askpass.sh
Modified:
projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/main/java/org/jboss/security/plugins/vault/PicketBoxSecurityVault.java
projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/SecurityActions.java
projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/security/vault/SecurityVaultUnitTestCase.java
Log:
Support external password for keystore of PicketBoxVault implementation (backport for eap5)
Modified: projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/main/java/org/jboss/security/plugins/vault/PicketBoxSecurityVault.java
===================================================================
--- projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/main/java/org/jboss/security/plugins/vault/PicketBoxSecurityVault.java 2013-12-17 02:09:47 UTC (rev 114601)
+++ projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/main/java/org/jboss/security/plugins/vault/PicketBoxSecurityVault.java 2013-12-17 11:53:32 UTC (rev 114602)
@@ -22,6 +22,7 @@
package org.jboss.security.plugins.vault;
import org.jboss.logging.Logger;
+import org.jboss.security.Util;
import org.jboss.security.plugins.PBEUtils;
import org.jboss.security.util.EncryptionUtil;
import org.jboss.security.util.KeyStoreUtil;
@@ -60,7 +61,20 @@
* The following options are expected in the {@link SecurityVault#init(Map)} call:
* ENC_FILE_DIR: the location where the encoded files will be kept. End with "/" or "\" based on your platform
* KEYSTORE_URL: location where your keystore is located
- * KEYSTORE_PASSWORD: Masked keystore password. Has to be prepended with MASK-
+ * KEYSTORE_PASSWORD: keystore password.
+ * 'plain text' masked password (has to be prepended with MASK-)
+ * '{EXT}...' where the '...' is the exact command
+ * '{EXTC[:expiration_in_millis]}...' where the '...' is the exact command
+ * line that will be passed to the Runtime.exec(String) method to execute a
+ * platform command. The first line of the command output is used as the
+ * password.
+ * EXTC variant will cache the passwords for expiration_in_millis milliseconds.
+ * Default cache expiration is 0 = infinity.
+ * '{CLASS}classname[:ctorargs]' where the '[:ctorargs]' is an optional
+ * string delimited by the ':' from the classname that will be passed to the
+ * classname ctor. The ctorargs itself is a comma delimited list of strings.
+ * The password is obtained from classname by invoking a
+ * 'char[] toCharArray()' method if found, otherwise, the 'String toString()'
* KEYSTORE_ALIAS: Alias where the keypair is located
* SALT: salt of the masked password. Ensured it is 8 characters in length
* ITERATION_COUNT: Iteration Count of the masked password.
@@ -111,6 +125,10 @@
public static final String PASS_MASK_PREFIX = "MASK-";
+ public static final String PASS_CLASS_PREFIX = "{CLASS}";
+
+ public static final String PASS_EXT_PREFIX = "{EXT";
+
public static final String PUBLIC_CERT = "PUBLIC_CERT";
public static final String KEY_SIZE = "KEY_SIZE";
@@ -147,11 +165,13 @@
}
keystoreURL = StringUtil.getSystemPropertyAsString(keystoreURL);
- String maskedPassword = (String) options.get(KEYSTORE_PASSWORD);
- if(maskedPassword == null)
+ String password = (String) options.get(KEYSTORE_PASSWORD);
+ if(password == null)
throw new SecurityVaultException("Option " + KEYSTORE_PASSWORD + "is null or empty");
- if(maskedPassword.startsWith(PASS_MASK_PREFIX) == false)
- throw new SecurityVaultException("Keystore password is not masked");
+ if(password.startsWith(PASS_MASK_PREFIX) == false
+ && password.startsWith(PASS_EXT_PREFIX) == false
+ && password.startsWith(PASS_CLASS_PREFIX) == false)
+ throw new SecurityVaultException("Keystore password should be either masked or prefixed with {EXT} or {CLASS}");
String salt = (String) options.get(SALT);
if(salt == null)
@@ -182,8 +202,7 @@
keyStoreType = (options.get(KEYSTORE_TYPE) != null ? (String) options.get(KEYSTORE_TYPE) : defaultKeyStoreType);
try {
- String keystorePass = decode(maskedPassword, salt, iterationCount);
- keyStorePWD = keystorePass.toCharArray();
+ keyStorePWD = loadKeystorePassword(password, salt, iterationCount);
keystore = getKeyStore(keystoreURL);
checkAndConvertKeyStoreToJCEKS(keystoreURL);
@@ -301,7 +320,21 @@
}
return true;
}
-
+
+ private char[] loadKeystorePassword(String passwordDef, String salt, int iterationCount) throws Exception
+ {
+ final char[] password;
+
+ if( passwordDef.startsWith(PASS_MASK_PREFIX) ){
+ String keystorePass = decode(passwordDef, salt, iterationCount);
+ password = keystorePass.toCharArray();
+ }
+ else
+ password = Util.loadPassword(passwordDef);
+
+ return password;
+ }
+
private String decode(String maskedString, String salt, int iterationCount) throws Exception
{
String pbeAlgo = "PBEwithMD5andDES";
Modified: projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/SecurityActions.java
===================================================================
--- projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/SecurityActions.java 2013-12-17 02:09:47 UTC (rev 114601)
+++ projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/SecurityActions.java 2013-12-17 11:53:32 UTC (rev 114602)
@@ -74,4 +74,49 @@
}
});
}
+
+ interface SystemPropertyAction
+ {
+ SystemPropertyAction PRIVILEGED = new SystemPropertyAction()
+ {
+ public String getProperty(final String name, final String defaultValue)
+ {
+ String prop = AccessController.doPrivileged(
+ new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ return NON_PRIVILEGED.getProperty(name, defaultValue);
+ }
+ }
+ );
+ return prop;
+ }
+ };
+ SystemPropertyAction NON_PRIVILEGED = new SystemPropertyAction()
+ {
+ public String getProperty(final String name, final String defaultValue)
+ {
+ final String prop = System.getProperty(name, defaultValue);
+ return prop;
+ }
+ };
+ String getProperty(final String name, final String defaultValue);
+ }
+
+ public static String getProperty(final String name, final String defaultValue)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ final String prop;
+ if( sm != null )
+ {
+ prop = SystemPropertyAction.PRIVILEGED.getProperty(name, defaultValue);
+ }
+ else
+ {
+ prop = SystemPropertyAction.NON_PRIVILEGED.getProperty(name, defaultValue);
+ }
+ return prop;
+ }
+
}
Added: projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/security/vault/KeystorePasswordProvider.java
===================================================================
--- projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/security/vault/KeystorePasswordProvider.java (rev 0)
+++ projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/security/vault/KeystorePasswordProvider.java 2013-12-17 11:53:32 UTC (rev 114602)
@@ -0,0 +1,14 @@
+package org.jboss.test.security.vault;
+
+/**
+ * Testing password provider for a Vault keystore.
+ *
+ * @author <a href="mailto:istudens at redhat.com">Ivo Studensky</a>
+ */
+public class KeystorePasswordProvider
+{
+ public char[] toCharArray()
+ {
+ return "vault22".toCharArray();
+ }
+}
Modified: projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/security/vault/SecurityVaultUnitTestCase.java
===================================================================
--- projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/security/vault/SecurityVaultUnitTestCase.java 2013-12-17 02:09:47 UTC (rev 114601)
+++ projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/java/org/jboss/test/security/vault/SecurityVaultUnitTestCase.java 2013-12-17 11:53:32 UTC (rev 114602)
@@ -160,6 +160,96 @@
assertFalse(vault.exists(vaultBlock+"1", attributeName+"2"));
}
+ public void testClassBasedKeystorePassword() throws Exception
+ {
+
+ setInitialVaulConditions("src/test/resources/keystore/vault.jks", "target/vaults/vault2/vault.jks",
+ "src/test/resources/keystore/vault_data", "target/vaults/vault2/vault_data");
+
+ Map<String,Object> options = getVaultOptionsMap(
+ "target/vaults/vault2/vault.jks",
+ "target/vaults/vault2/vault_data",
+ "vault", "12438567", 50, "{CLASS}org.jboss.test.security.vault.KeystorePasswordProvider");
+
+ String vaultBlock = "aBlock";
+ String attributeName = "anAttribute";
+
+ char[] attributeValue = "aValue".toCharArray();
+
+ SecurityVault vault = getNewSecurityVaultInstance();
+
+ vault.init(options);
+ assertTrue(vault.isInitialized());
+
+ Map<String,Object> handshakeOptions = new HashMap<String,Object>();
+
+ byte[] sharedKey = vault.handshake(handshakeOptions);
+ assertNotNull(sharedKey);
+
+ vault.store(vaultBlock, attributeName, attributeValue , sharedKey);
+
+ assertTrue(vault.exists(vaultBlock, attributeName));
+ //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());
+
+ assertTrue(vault.remove(vaultBlock+"1", attributeName+"2", sharedKey));
+ assertFalse(vault.exists(vaultBlock+"1", attributeName+"2"));
+ }
+
+ public void testExtCmdBasedKeystorePassword() throws Exception
+ {
+ // since this test uses an external BASH script it is valid for Linux systems only
+ String OS_NAME = SecurityActions.getProperty("os.name", null);
+ if (OS_NAME.startsWith("Linux") == false && OS_NAME.startsWith("LINUX") == false)
+ return;
+
+ setInitialVaulConditions("src/test/resources/keystore/vault.jks", "target/vaults/vault2/vault.jks",
+ "src/test/resources/keystore/vault_data", "target/vaults/vault2/vault_data");
+
+ String absolutePathToAskPass = SecurityVaultUnitTestCase.class.getResource("/bin/askpass.sh").getFile();
+ System.out.println("absolutePathToAskPass: " + absolutePathToAskPass);
+
+ // 'Enter passphrase for *' is hard-coded into kwalletaskpass for example
+ Map<String,Object> options = getVaultOptionsMap(
+ "target/vaults/vault2/vault.jks",
+ "target/vaults/vault2/vault_data",
+ "vault", "12438567", 50, "{EXT}/bin/sh " + absolutePathToAskPass + " Enter passphrase for askpass test");
+
+ String vaultBlock = "aBlock";
+ String attributeName = "anAttribute";
+
+ char[] attributeValue = "aValue".toCharArray();
+
+ SecurityVault vault = getNewSecurityVaultInstance();
+
+ vault.init(options);
+ assertTrue(vault.isInitialized());
+
+ Map<String,Object> handshakeOptions = new HashMap<String,Object>();
+
+ byte[] sharedKey = vault.handshake(handshakeOptions);
+ assertNotNull(sharedKey);
+
+ vault.store(vaultBlock, attributeName, attributeValue , sharedKey);
+
+ assertTrue(vault.exists(vaultBlock, attributeName));
+ //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());
+
+ assertTrue(vault.remove(vaultBlock+"1", attributeName+"2", sharedKey));
+ assertFalse(vault.exists(vaultBlock+"1", attributeName+"2"));
+ }
+
/**
* See src/test/resources/vault-v0/readme.txt for initial vault setup (including secured attributes).
* @throws Exception
@@ -347,6 +437,10 @@
private String getMaskedPassword(String pwd, String salt, int iterationCount) throws Exception
{
+ if (pwd.startsWith(PicketBoxSecurityVault.PASS_EXT_PREFIX)
+ || pwd.startsWith(PicketBoxSecurityVault.PASS_CLASS_PREFIX))
+ return pwd;
+
String algo = "PBEwithMD5andDES";
// Create the PBE secret key
@@ -359,7 +453,7 @@
String maskedPass = PBEUtils.encode64(pwd.getBytes(), algo, cipherKey, cipherSpec);
- return new String(PicketBoxSecurityVault.PASS_MASK_PREFIX) + maskedPass;
+ return PicketBoxSecurityVault.PASS_MASK_PREFIX + maskedPass;
}
Added: projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/resources/bin/askpass.sh
===================================================================
--- projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/resources/bin/askpass.sh (rev 0)
+++ projects/security/security-jboss-sx/branches/Branch_2_0/jbosssx/src/test/resources/bin/askpass.sh 2013-12-17 11:53:32 UTC (rev 114602)
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo vault22
\ No newline at end of file
More information about the jboss-cvs-commits
mailing list