Skip to content

Commit

Permalink
[ELY-2496] Add missing hash-charset option to FileSystemEncryptRealmC…
Browse files Browse the repository at this point in the history
…ommand
  • Loading branch information
jessicarod7 committed May 23, 2023
1 parent 051f5ee commit 0bd8c07
Show file tree
Hide file tree
Showing 16 changed files with 87 additions and 86 deletions.
1 change: 1 addition & 0 deletions tool/src/main/java/org/wildfly/security/tool/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ class Params {
static final String FILE_PARAM = "file";
static final String DEBUG_PARAM = "debug";
static final String DIRECTORY_PARAM = "directory";
static final String HASH_CHARSET_PARAM = "hash-charset";
static final String HASH_ENCODING_PARAM = "hash-encoding";
static final String HELP_PARAM = "help";
static final String IMPLEMENTATION_PROPERTIES_PARAM = "properties";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,9 +473,9 @@ public interface ElytronToolMessages extends BasicLogger {
String cmdFileSystemRealmBulkConvertDesc();

@Message(id = NONE, value = "Bulk conversion with options listed in description file. Optional options have default values, required options do not. (Action) %n" +
"The options realm-name, hash-encoding, levels, secret-key, create, and populate are optional. %n" +
"The options realm-name, hash-encoding, hash-charset, levels, secret-key, create, populate, keystore, type, password, password-env, and key-pair are optional. %n" +
"Values are required for the following options: input-location, output-location, and credential-store. %n" +
"The default values of realm-name, hash-encoding, levels, secret-key, create, and populate are encrypted-filesystem-realm, BASE64, 2, key, true, and true respectively. %n" +
"The default values of realm-name, hash-encoding, hash-charset, levels, secret-key, create, and populate are encrypted-filesystem-realm, BASE64, UTF-8, 2, key, true, and true respectively. %n" +
"If one or more these required values are not set, the corresponding block is skipped. %n" +
"Each option must be specified in the following format: <option>:<value>. The order of options does not matter. %n" +
"Blocks of options must be separated by a blank line.")
Expand All @@ -491,6 +491,9 @@ public interface ElytronToolMessages extends BasicLogger {
@Message(id = NONE, value = "Unable to locate Secret Key with Credential Store located at %s. Skipping realm located at %s.")
String cmdFileSystemEncryptionNoSecretKey(String credentialStore, String realmLocation);

@Message(id = NONE, value = "The character set used to convert the password string to a byte array. Defaults to UTF-8.")
String cmdFileSystemRealmIntegrityHashCharsetDesc();

@Message(id = NONE, value = "Suppresses all output except errors and prompts.")
String cmdFileSystemRealmSilentDesc();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import static org.wildfly.security.tool.Params.DIRECTORY_PARAM;
import static org.wildfly.security.tool.Params.ENCODED_PARAM;
import static org.wildfly.security.tool.Params.FILE_PARAM;
import static org.wildfly.security.tool.Params.HASH_CHARSET_PARAM;
import static org.wildfly.security.tool.Params.HASH_ENCODING_PARAM;
import static org.wildfly.security.tool.Params.HELP_PARAM;
import static org.wildfly.security.tool.Params.INPUT_LOCATION_PARAM;
Expand All @@ -41,6 +42,8 @@

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand All @@ -66,7 +69,9 @@
* Elytron-Tool command to convert un-encrypted FileSystemRealms into an encrypted realm with the use of a SecretKey.
* Also, optionally provides a WildFly CLI script to register the FileSystemRealm and corresponding
* security-domain in WildFly.
*
* @author <a href="mailto:[email protected]">Ashpan Raskar</a>
* @author <a href="mailto:[email protected]">Cameron Rodriguez</a>
*/

class FileSystemEncryptRealmCommand extends Command {
Expand Down Expand Up @@ -118,6 +123,10 @@ class FileSystemEncryptRealmCommand extends Command {
option.setArgName(NAME_PARAM);
options.addOption(option);

option = new Option("u", HASH_CHARSET_PARAM, true, ElytronToolMessages.msg.cmdFileSystemRealmIntegrityHashCharsetDesc());
option.setArgName(NAME_PARAM);
options.addOption(option);

option = new Option("f", ENCODED_PARAM, true, ElytronToolMessages.msg.cmdFileSystemEncryptEncodedDesc());
option.setArgName(NAME_PARAM);
options.addOption(option);
Expand Down Expand Up @@ -155,6 +164,7 @@ private static final class Descriptor {
private String secretKeyAlias;
private Integer levels;
private Encoding hashEncoding;
private Charset hashCharset;
private Boolean encoded;
private Boolean createCredentialStore;
private Boolean populate;
Expand All @@ -169,6 +179,7 @@ private static final class Descriptor {
this.hashEncoding = descriptor.hashEncoding;
this.levels = descriptor.levels;
this.encoded = descriptor.encoded;
this.hashCharset = descriptor.hashCharset;
this.createCredentialStore = descriptor.createCredentialStore;
this.secretKeyAlias = descriptor.secretKeyAlias;
this.populate = descriptor.populate;
Expand All @@ -182,6 +193,14 @@ public void setHashEncoding(Encoding hashEncoding) {
this.hashEncoding = hashEncoding;
}

public Charset getHashCharset() {
return hashCharset;
}

public void setHashCharset(Charset hashCharset) {
this.hashCharset = hashCharset;
}

public Integer getLevels() {
return levels;
}
Expand Down Expand Up @@ -262,6 +281,7 @@ void reset() {
this.createCredentialStore = null;
this.secretKeyAlias = null;
this.hashEncoding = null;
this.hashCharset = null;
this.encoded = null;
this.levels = null;
this.populate = null;
Expand Down Expand Up @@ -300,6 +320,7 @@ public void execute(String[] args) throws Exception {
String createCredentialStore = cmdLine.getOptionValue("a");
String secretKeyAliasOption = cmdLine.getOptionValue("s");
String hashEncodingOption = cmdLine.getOptionValue("e");
String hashCharsetOption = cmdLine.getOptionValue("u");
String levelsOption = cmdLine.getOptionValue("l");
String encodedOption = cmdLine.getOptionValue("f");
String bulkConvert = cmdLine.getOptionValue("b");
Expand Down Expand Up @@ -339,6 +360,15 @@ public void execute(String[] args) throws Exception {
errorHandler(e);
}
}
if (hashCharsetOption == null) {
descriptor.setHashCharset(StandardCharsets.UTF_8);
} else {
try {
descriptor.setHashCharset(Charset.forName(hashCharsetOption.toUpperCase()));
} catch (IllegalArgumentException e) {
errorHandler(e);
}
}
if (populateOption == null) {
descriptor.setPopulate(true);
} else {
Expand Down Expand Up @@ -384,7 +414,7 @@ public void execute(String[] args) throws Exception {
checkDescriptorFields(descriptor);
} else if (inputRealmLocationOption != null || outputRealmLocationOption != null || secretKeyAliasOption != null ||
realmNameOption != null || credentialStoreOption != null || createCredentialStore != null ||
hashEncodingOption != null || encodedOption != null || levelsOption != null || populateOption != null) {
hashEncodingOption != null || encodedOption != null || levelsOption != null || populateOption != null || hashCharsetOption != null) {
throw ElytronToolMessages.msg.mutuallyExclusiveOptionsEncryptSpecified();
} else {
if (summaryMode) {
Expand Down Expand Up @@ -562,6 +592,9 @@ private void parseDescriptorFile(String file) throws Exception {
case HASH_ENCODING_PARAM:
descriptor.setHashEncoding(Encoding.valueOf(arg.toUpperCase()));
break;
case HASH_CHARSET_PARAM:
descriptor.setHashCharset(Charset.forName(arg.toUpperCase()));
break;
case ENCODED_PARAM:
descriptor.setEncoded(Boolean.parseBoolean(arg));
break;
Expand Down Expand Up @@ -619,6 +652,9 @@ private void findMissingRequiredValuesAndSetValues(int count, Descriptor descrip
if(descriptor.getHashEncoding() == null) {
descriptor.setHashEncoding(Encoding.BASE64);
}
if(descriptor.getHashCharset() == null) {
descriptor.setHashCharset(StandardCharsets.UTF_8);
}
if(descriptor.getEncoded() == null) {
descriptor.setEncoded(true);
}
Expand Down Expand Up @@ -667,6 +703,7 @@ private void createFileSystemRealm() throws Exception {
.setRoot(Paths.get(descriptor.getInputRealmLocation()))
.setLevels(descriptor.getLevels())
.setHashEncoding(descriptor.getHashEncoding())
.setHashCharset(descriptor.getHashCharset())
.setEncoded(descriptor.getEncoded())
.setProviders(ELYTRON_PASSWORD_PROVIDERS)
.build();
Expand All @@ -676,6 +713,7 @@ private void createFileSystemRealm() throws Exception {
.setSecretKey(key)
.setLevels(descriptor.getLevels())
.setProviders(ELYTRON_PASSWORD_PROVIDERS)
.setHashCharset(descriptor.getHashCharset())
.build();
FileSystemRealmUtil.createEncryptedRealmFromUnencrypted(oldFileSystemRealm, newFileSystemRealm);
}
Expand All @@ -695,7 +733,11 @@ private void createWildFlyScript() throws Exception {
String credentialStore = descriptor.getCredentialStore();
String secretKeyAlias = descriptor.getSecretKeyAlias();
int levels = descriptor.getLevels();
Charset hashCharset = descriptor.getHashCharset();

if (hashCharset == null) {
hashCharset = StandardCharsets.UTF_8;
}
if(secretKeyAlias == null) {
secretKeyAlias = DEFAULT_SECRET_KEY_ALIAS;
}
Expand Down Expand Up @@ -739,8 +781,9 @@ private void createWildFlyScript() throws Exception {
}

List<String> scriptLines = Arrays.asList(
String.format("/subsystem=elytron/secret-key-credential-store=%s:add(path=%s)", "mycredstore"+counter, credentialStore),
String.format("/subsystem=elytron/filesystem-realm=%s:add(path=%s, levels=%s, credential-store=%s, secret-key=%s)", fileSystemRealmName, fullOutputPath+'/'+fileSystemRealmName, levels, "mycredstore"+counter, secretKeyAlias)
String.format("/subsystem=elytron/secret-key-credential-store=%s:add(path=%s)", "mycredstore"+counter, credentialStore),
String.format("/subsystem=elytron/filesystem-realm=%s:add(path=%s, levels=%s, credential-store=%s, secret-key=%s%s)", fileSystemRealmName, fullOutputPath+'/'+fileSystemRealmName, levels, "mycredstore"+counter, secretKeyAlias,
hashCharset != StandardCharsets.UTF_8 ? ", hash-charset="+hashCharset.name() : "")
);

if (overwriteScript) { // Create a new script file, or overwrite the existing one
Expand All @@ -756,8 +799,8 @@ private boolean checkDescriptorFields(Descriptor descriptor) {
if (descriptor.getInputRealmLocation() == null || descriptor.getOutputRealmLocation() == null ||
descriptor.getFileSystemRealmName() == null || descriptor.getCredentialStore() == null ||
descriptor.getCreateCredentialStore() == null || descriptor.getSecretKeyAlias() == null ||
descriptor.getHashEncoding() == null || descriptor.getEncoded() == null ||
descriptor.getLevels() == null || descriptor.getPopulate() == null) {
descriptor.getHashEncoding() == null || descriptor.getHashCharset() == null ||
descriptor.getEncoded() == null || descriptor.getLevels() == null || descriptor.getPopulate() == null) {
warningHandler(ElytronToolMessages.msg.fileSystemEncryptRequiredParametersNotSpecified());
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@
import org.wildfly.security.credential.store.impl.PropertiesCredentialStore;
import org.wildfly.security.evidence.PasswordGuessEvidence;

public class FileSystemEncryptRealmCommandTest extends AbstractCommandTest{
/**
* @author <a href="mailto:[email protected]">Ashpan Raskar</a>
* @author <a href="mailto:[email protected]">Cameron Rodriguez</a>
*/
public class FileSystemEncryptRealmCommandTest extends AbstractCommandTest {

private static final String RELATIVE_BASE_DIR = "./target/test-classes/filesystem-encrypt/";
private static final String CREDENTIAL_STORE_PATH = RELATIVE_BASE_DIR + "mycredstore.cs";
Expand Down Expand Up @@ -107,7 +111,7 @@ public void testHelp() {
public void testBulk() throws Exception {
String descriptorFileLocation = "./target/test-classes/bulk-encryption-conversion-desc";
runCommand(descriptorFileLocation, 0);
String[] files = new String[]{"multiple-credential-types/O/OBWGC2LOKVZWK4Q.xml", "multiple-credential-types/O/ONQWY5DFMRKXGZLS.xml", "multiple-credential-types/O/OVZWK4RUGI.xml", "multiple-credential-types/M/MFXG65DIMVZFK43FOI.xml", "multiple-credential-types/M/MFZWQ4DBNY.xml", "multiple-credential-types/N/NZSXOU3BNR2GKZCVONSXEMQ.xml", "hash-encoding/O/B/OBSXE43PNYZA.xml", "hash-encoding/O/5/O5UWYZDGNR4TO.xml", "hash-encoding/O/V/OVZWK4RR.xml", "hash-encoding/M/J/MJXXSNA.xml", "hash-encoding/M/5/M5UXE3BV.xml", "hash-encoding/M/V/MVQXAOA.xml", "hash-encoding/N/J/NJRG643TGY.xml", "hash-encoding/N/F/NFSGK3TUNF2HSMY.xml", "hash-charset/O/B/OBSXE43PNYZA.xml", "hash-charset/O/5/O5UWYZDGNR4TO.xml", "hash-charset/O/V/OVZWK4RR.xml", "hash-charset/M/J/MJXXSNA.xml", "hash-charset/M/5/M5UXE3BV.xml", "hash-charset/M/V/MVQXAOA.xml", "hash-charset/N/J/NJRG643TGY.xml", "hash-charset/N/F/NFSGK3TUNF2HSMY.xml", "level-4/O/B/S/X/OBSXE43PNYZA.xml", "level-4/O/5/U/W/O5UWYZDGNR4TO.xml", "level-4/O/V/Z/W/OVZWK4RR.xml", "level-4/M/J/X/X/MJXXSNA.xml", "level-4/M/5/U/X/M5UXE3BV.xml", "level-4/M/V/Q/X/MVQXAOA.xml", "level-4/N/J/R/G/NJRG643TGY.xml", "level-4/N/F/S/G/NFSGK3TUNF2HSMY.xml"};
String[] files = new String[]{"multiple-credential-types/O/OBWGC2LOKVZWK4Q.xml", "multiple-credential-types/O/ONQWY5DFMRKXGZLS.xml", "multiple-credential-types/O/OVZWK4RUGI.xml", "multiple-credential-types/M/MFXG65DIMVZFK43FOI.xml", "multiple-credential-types/M/MFZWQ4DBNY.xml", "multiple-credential-types/N/NZSXOU3BNR2GKZCVONSXEMQ.xml", "hash-encoding/O/B/OBSXE43PNYZA.xml", "hash-encoding/O/5/O5UWYZDGNR4TO.xml", "hash-encoding/O/V/OVZWK4RR.xml", "hash-encoding/M/J/MJXXSNA.xml", "hash-encoding/M/5/M5UXE3BV.xml", "hash-encoding/M/V/MVQXAOA.xml", "hash-encoding/N/J/NJRG643TGY.xml", "hash-encoding/N/F/NFSGK3TUNF2HSMY.xml", "hash-charset/M/F/MFWGSY3F.xml", "hash-charset/M/J/MJXWE.xml", "hash-charset/M/N/MNQW2ZLSN5XA.xml", "level-4/O/B/S/X/OBSXE43PNYZA.xml", "level-4/O/5/U/W/O5UWYZDGNR4TO.xml", "level-4/O/V/Z/W/OVZWK4RR.xml", "level-4/M/J/X/X/MJXXSNA.xml", "level-4/M/5/U/X/M5UXE3BV.xml", "level-4/M/V/Q/X/MVQXAOA.xml", "level-4/N/J/R/G/NJRG643TGY.xml", "level-4/N/F/S/G/NFSGK3TUNF2HSMY.xml"};
for (String file: files) {
if(!fileExists("target/test-classes/filesystem-encrypt/fs-encrypted-realms/"+file)){
throw new FileNotFoundException("Missing file from Bulk Descriptor File: " + file);
Expand Down
3 changes: 2 additions & 1 deletion tool/src/test/resources/bulk-encryption-conversion-desc
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ credential-store:target/test-classes/filesystem-encrypt/mycredstore.cs
create:true
levels:4

input-location:target/test-classes/filesystem-encrypt/fs-unencrypted-realms/hashcharset
input-location:target/test-classes/filesystem-encrypt/fs-unencrypted-realms/fsRealmCharset
output-location:target/test-classes/filesystem-encrypt/fs-encrypted-realms
realm-name:hash-charset
hash-charset:ISO-8859-1
credential-store:target/test-classes/filesystem-encrypt/mycredstore.cs
create:true

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" ?>
<identity xmlns="urn:elytron:1.0">
<attributes>
<attribute name="role" value="user"></attribute>
<attribute name="role" value="admin"></attribute>
</attributes>

</identity>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" ?>
<identity xmlns="urn:elytron:1.0">
<credentials>
<password algorithm="clear" format="base64">ASdwYXNzd29yZEh5dsOkw6TDpCc=</password>
</credentials>
</identity>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" ?>
<identity xmlns="urn:elytron:1.0">
<credentials>
<password algorithm="simple-digest-sha-256" format="base64">A3YRu0iebR9tX8reCXbzm6xiKqWEAVnrKLClSLI20Cln</password>
</credentials>
<attributes>
<attribute name="role" value="user"></attribute>
<attribute name="position" value="engineer"></attribute>
</attributes>

</identity>

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit 0bd8c07

Please sign in to comment.