Bläddra i källkod

value type converter refactoring

Jason Rivard 5 år sedan
förälder
incheckning
2386502b5f
64 ändrade filer med 599 tillägg och 500 borttagningar
  1. 33 2
      server/src/main/java/password/pwm/bean/PrivateKeyCertificate.java
  2. 25 325
      server/src/main/java/password/pwm/config/Configuration.java
  3. 1 0
      server/src/main/java/password/pwm/config/PwmSetting.java
  4. 1 0
      server/src/main/java/password/pwm/config/PwmSettingSyntax.java
  5. 1 1
      server/src/main/java/password/pwm/config/function/AbstractUriCertImportFunction.java
  6. 7 4
      server/src/main/java/password/pwm/config/function/ActionCertImportFunction.java
  7. 1 1
      server/src/main/java/password/pwm/config/function/LdapCertImportFunction.java
  8. 1 1
      server/src/main/java/password/pwm/config/function/SmtpCertImportFunction.java
  9. 1 1
      server/src/main/java/password/pwm/config/function/SyslogCertImportFunction.java
  10. 14 13
      server/src/main/java/password/pwm/config/profile/AbstractProfile.java
  11. 5 5
      server/src/main/java/password/pwm/config/profile/ChallengeProfile.java
  12. 1 1
      server/src/main/java/password/pwm/config/profile/ForgottenPasswordProfile.java
  13. 11 6
      server/src/main/java/password/pwm/config/stored/ConfigurationCleaner.java
  14. 1 1
      server/src/main/java/password/pwm/config/stored/ConfigurationReader.java
  15. 1 1
      server/src/main/java/password/pwm/config/stored/StoredConfigData.java
  16. 1 1
      server/src/main/java/password/pwm/config/stored/StoredConfigXmlSerializer.java
  17. 1 1
      server/src/main/java/password/pwm/config/stored/StoredConfigZipJsonSerializer.java
  18. 1 1
      server/src/main/java/password/pwm/config/stored/StoredConfigZipXmlSerializer.java
  19. 1 1
      server/src/main/java/password/pwm/config/stored/StoredConfiguration.java
  20. 1 1
      server/src/main/java/password/pwm/config/stored/StoredConfigurationImpl.java
  21. 1 1
      server/src/main/java/password/pwm/config/stored/StoredConfigurationModifier.java
  22. 1 1
      server/src/main/java/password/pwm/config/stored/StoredConfigurationUtil.java
  23. 0 1
      server/src/main/java/password/pwm/config/value/AbstractValue.java
  24. 0 1
      server/src/main/java/password/pwm/config/value/ActionValue.java
  25. 0 1
      server/src/main/java/password/pwm/config/value/BooleanValue.java
  26. 0 1
      server/src/main/java/password/pwm/config/value/ChallengeValue.java
  27. 0 1
      server/src/main/java/password/pwm/config/value/CustomLinkValue.java
  28. 0 1
      server/src/main/java/password/pwm/config/value/EmailValue.java
  29. 0 1
      server/src/main/java/password/pwm/config/value/FileValue.java
  30. 0 1
      server/src/main/java/password/pwm/config/value/FormValue.java
  31. 0 1
      server/src/main/java/password/pwm/config/value/LocalizedStringArrayValue.java
  32. 0 1
      server/src/main/java/password/pwm/config/value/LocalizedStringValue.java
  33. 0 1
      server/src/main/java/password/pwm/config/value/NamedSecretValue.java
  34. 0 1
      server/src/main/java/password/pwm/config/value/NumericArrayValue.java
  35. 0 1
      server/src/main/java/password/pwm/config/value/NumericValue.java
  36. 0 1
      server/src/main/java/password/pwm/config/value/OptionListValue.java
  37. 0 1
      server/src/main/java/password/pwm/config/value/PasswordValue.java
  38. 2 3
      server/src/main/java/password/pwm/config/value/PrivateKeyValue.java
  39. 0 1
      server/src/main/java/password/pwm/config/value/RemoteWebServiceValue.java
  40. 2 1
      server/src/main/java/password/pwm/config/value/StoredValue.java
  41. 0 1
      server/src/main/java/password/pwm/config/value/StringArrayValue.java
  42. 0 1
      server/src/main/java/password/pwm/config/value/StringValue.java
  43. 0 1
      server/src/main/java/password/pwm/config/value/UserPermissionValue.java
  44. 0 1
      server/src/main/java/password/pwm/config/value/ValueFactory.java
  45. 349 0
      server/src/main/java/password/pwm/config/value/ValueTypeConverter.java
  46. 0 1
      server/src/main/java/password/pwm/config/value/VerificationMethodValue.java
  47. 39 43
      server/src/main/java/password/pwm/config/value/X509CertificateValue.java
  48. 1 1
      server/src/main/java/password/pwm/health/ConfigurationChecker.java
  49. 2 2
      server/src/main/java/password/pwm/http/ContextManager.java
  50. 1 1
      server/src/main/java/password/pwm/http/servlet/configeditor/ConfigEditorServlet.java
  51. 1 1
      server/src/main/java/password/pwm/http/servlet/configeditor/NavTreeHelper.java
  52. 2 2
      server/src/main/java/password/pwm/http/servlet/configguide/ConfigGuideForm.java
  53. 1 1
      server/src/main/java/password/pwm/http/servlet/configguide/ConfigGuideServlet.java
  54. 10 27
      server/src/main/java/password/pwm/http/servlet/configmanager/ConfigManagerCertificatesServlet.java
  55. 1 1
      server/src/main/java/password/pwm/http/servlet/configmanager/DebugItemGenerator.java
  56. 1 0
      server/src/main/java/password/pwm/svc/PwmServiceManager.java
  57. 2 2
      server/src/main/java/password/pwm/svc/sessiontrack/SessionTrackService.java
  58. 16 15
      server/src/main/java/password/pwm/util/LDAPPermissionCalculator.java
  59. 4 4
      server/src/main/java/password/pwm/util/PropertyConfigurationImporter.java
  60. 1 1
      server/src/main/java/password/pwm/util/i18n/ConfigLocaleStats.java
  61. 1 1
      server/src/main/java/password/pwm/util/java/XmlFactory.java
  62. 1 1
      server/src/main/java/password/pwm/util/secure/HttpsServerCertificateManager.java
  63. 47 0
      server/src/main/java/password/pwm/util/secure/X509Utils.java
  64. 4 3
      server/src/test/java/password/pwm/config/PwmSettingTest.java

+ 33 - 2
server/src/main/java/password/pwm/bean/PrivateKeyCertificate.java

@@ -21,15 +21,46 @@
 package password.pwm.bean;
 package password.pwm.bean;
 
 
 import lombok.Value;
 import lombok.Value;
+import password.pwm.util.java.StringUtil;
+import password.pwm.util.secure.X509Utils;
 
 
+import java.io.IOException;
 import java.io.Serializable;
 import java.io.Serializable;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.PrivateKey;
 import java.security.cert.X509Certificate;
 import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.List;
 import java.util.List;
 
 
 @Value
 @Value
 public class PrivateKeyCertificate implements Serializable
 public class PrivateKeyCertificate implements Serializable
 {
 {
-    private List<X509Certificate> certificates;
-    private PrivateKey key;
+    private final List<String> b64certificates;
+    private final String privateKey;
+
+    public PrivateKeyCertificate( final List<X509Certificate> certificates, final PrivateKey privateKey )
+    {
+        this.b64certificates = X509Utils.certificatesToBase64s( certificates );
+        this.privateKey = StringUtil.base64Encode( privateKey.getEncoded() );
+    }
+
+    public List<X509Certificate> getCertificates()
+    {
+        return X509Utils.certificatesFromBase64s( b64certificates );
+    }
+
+    public PrivateKey getKey()
+    {
+        try
+        {
+            final byte[] privateKeyBytes = StringUtil.base64Decode( privateKey );
+            return KeyFactory.getInstance( "RSA" ).generatePrivate( new PKCS8EncodedKeySpec( privateKeyBytes ) );
+        }
+        catch ( final InvalidKeySpecException | NoSuchAlgorithmException | IOException e )
+        {
+            throw new IllegalStateException( "unexpected error converting b64 privateKey to PrivateKey instance: " + e.getMessage() );
+        }
+    }
 }
 }

+ 25 - 325
server/src/main/java/password/pwm/config/Configuration.java

@@ -49,20 +49,9 @@ import password.pwm.config.profile.UpdateProfileProfile;
 import password.pwm.config.stored.StoredConfigItemKey;
 import password.pwm.config.stored.StoredConfigItemKey;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfigurationUtil;
 import password.pwm.config.stored.StoredConfigurationUtil;
-import password.pwm.config.value.BooleanValue;
-import password.pwm.config.value.CustomLinkValue;
 import password.pwm.config.value.FileValue;
 import password.pwm.config.value.FileValue;
-import password.pwm.config.value.FormValue;
-import password.pwm.config.value.LocalizedStringArrayValue;
-import password.pwm.config.value.LocalizedStringValue;
-import password.pwm.config.value.NamedSecretValue;
-import password.pwm.config.value.NumericArrayValue;
-import password.pwm.config.value.NumericValue;
-import password.pwm.config.value.PasswordValue;
-import password.pwm.config.value.RemoteWebServiceValue;
-import password.pwm.config.value.StringArrayValue;
-import password.pwm.config.value.StringValue;
-import password.pwm.config.value.UserPermissionValue;
+import password.pwm.config.value.StoredValue;
+import password.pwm.config.value.ValueTypeConverter;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.config.value.data.NamedSecretData;
 import password.pwm.config.value.data.NamedSecretData;
@@ -85,10 +74,8 @@ import password.pwm.util.secure.SecureService;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.InvocationTargetException;
 import java.security.cert.X509Certificate;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.List;
@@ -131,13 +118,13 @@ public class Configuration implements SettingReader
     public List<FormConfiguration> readSettingAsForm( final PwmSetting setting )
     public List<FormConfiguration> readSettingAsForm( final PwmSetting setting )
     {
     {
         final StoredValue value = readStoredValue( setting );
         final StoredValue value = readStoredValue( setting );
-        return JavaTypeConverter.valueToForm( value );
+        return ValueTypeConverter.valueToForm( value );
     }
     }
 
 
     public List<UserPermission> readSettingAsUserPermission( final PwmSetting setting )
     public List<UserPermission> readSettingAsUserPermission( final PwmSetting setting )
     {
     {
         final StoredValue value = readStoredValue( setting );
         final StoredValue value = readStoredValue( setting );
-        return JavaTypeConverter.valueToUserPermissions( value );
+        return ValueTypeConverter.valueToUserPermissions( value );
     }
     }
 
 
     public Map<String, LdapProfile> getLdapProfiles( )
     public Map<String, LdapProfile> getLdapProfiles( )
@@ -167,7 +154,7 @@ public class Configuration implements SettingReader
     public <E extends Enum<E>> E readSettingAsEnum( final PwmSetting setting, final Class<E> enumClass )
     public <E extends Enum<E>> E readSettingAsEnum( final PwmSetting setting, final Class<E> enumClass )
     {
     {
         final StoredValue value = readStoredValue( setting );
         final StoredValue value = readStoredValue( setting );
-        final E returnValue = JavaTypeConverter.valueToEnum( setting, value, enumClass );
+        final E returnValue = ValueTypeConverter.valueToEnum( setting, value, enumClass );
         if ( MessageSendMethod.class.equals( enumClass ) )
         if ( MessageSendMethod.class.equals( enumClass ) )
         {
         {
             deprecatedSettingException( setting, null, ( MessageSendMethod ) returnValue );
             deprecatedSettingException( setting, null, ( MessageSendMethod ) returnValue );
@@ -178,7 +165,7 @@ public class Configuration implements SettingReader
 
 
     public <E extends Enum<E>> Set<E> readSettingAsOptionList( final PwmSetting setting, final Class<E> enumClass )
     public <E extends Enum<E>> Set<E> readSettingAsOptionList( final PwmSetting setting, final Class<E> enumClass )
     {
     {
-        return JavaTypeConverter.valueToOptionList( setting, readStoredValue( setting ), enumClass );
+        return ValueTypeConverter.valueToOptionList( setting, readStoredValue( setting ), enumClass );
     }
     }
 
 
     public MessageSendMethod readSettingAsTokenSendMethod( final PwmSetting setting )
     public MessageSendMethod readSettingAsTokenSendMethod( final PwmSetting setting )
@@ -188,7 +175,7 @@ public class Configuration implements SettingReader
 
 
     public List<ActionConfiguration> readSettingAsAction( final PwmSetting setting )
     public List<ActionConfiguration> readSettingAsAction( final PwmSetting setting )
     {
     {
-        return JavaTypeConverter.valueToAction( setting, readStoredValue( setting ) );
+        return ValueTypeConverter.valueToAction( setting, readStoredValue( setting ) );
     }
     }
 
 
     public List<String> readSettingAsLocalizedStringArray( final PwmSetting setting, final Locale locale )
     public List<String> readSettingAsLocalizedStringArray( final PwmSetting setting, final Locale locale )
@@ -199,313 +186,27 @@ public class Configuration implements SettingReader
         }
         }
 
 
         final StoredValue value = readStoredValue( setting );
         final StoredValue value = readStoredValue( setting );
-        return JavaTypeConverter.valueToLocalizedStringArray( value, locale );
+        return ValueTypeConverter.valueToLocalizedStringArray( value, locale );
     }
     }
 
 
     public String readSettingAsString( final PwmSetting setting )
     public String readSettingAsString( final PwmSetting setting )
     {
     {
-        return JavaTypeConverter.valueToString( readStoredValue( setting ) );
+        return ValueTypeConverter.valueToString( readStoredValue( setting ) );
     }
     }
 
 
     public List<RemoteWebServiceConfiguration> readSettingAsRemoteWebService( final PwmSetting pwmSetting )
     public List<RemoteWebServiceConfiguration> readSettingAsRemoteWebService( final PwmSetting pwmSetting )
     {
     {
-        return JavaTypeConverter.valueToRemoteWebServiceConfiguration( readStoredValue( pwmSetting ) );
+        return ValueTypeConverter.valueToRemoteWebServiceConfiguration( readStoredValue( pwmSetting ) );
     }
     }
 
 
     public PasswordData readSettingAsPassword( final PwmSetting setting )
     public PasswordData readSettingAsPassword( final PwmSetting setting )
     {
     {
-        return JavaTypeConverter.valueToPassword( readStoredValue( setting ) );
+        return ValueTypeConverter.valueToPassword( readStoredValue( setting ) );
     }
     }
 
 
     public Map<String, NamedSecretData> readSettingAsNamedPasswords( final PwmSetting setting )
     public Map<String, NamedSecretData> readSettingAsNamedPasswords( final PwmSetting setting )
     {
     {
-        return JavaTypeConverter.valueToNamedPassword( readStoredValue( setting ) );
-    }
-
-    public abstract static class JavaTypeConverter
-    {
-        public static long valueToLong( final StoredValue value )
-        {
-            if ( !( value instanceof NumericValue ) )
-            {
-                throw new IllegalArgumentException( "setting value is not readable as number" );
-            }
-            return ( long ) value.toNativeObject();
-        }
-
-        public static List<Long> valueToLongArray( final StoredValue value )
-        {
-            if ( !( value instanceof NumericArrayValue ) )
-            {
-                throw new IllegalArgumentException( "setting value is not readable as number array" );
-            }
-            return ( List<Long> ) value.toNativeObject();
-        }
-
-        public static String valueToString( final StoredValue value )
-        {
-            if ( value == null )
-            {
-                return null;
-            }
-            if ( ( !( value instanceof StringValue ) ) && ( !( value instanceof BooleanValue ) ) )
-            {
-                throw new IllegalArgumentException( "setting value is not readable as string" );
-            }
-            final Object nativeObject = value.toNativeObject();
-            if ( nativeObject == null )
-            {
-                return null;
-            }
-            return nativeObject.toString();
-        }
-
-        public static PasswordData valueToPassword( final StoredValue value )
-        {
-            if ( value == null )
-            {
-                return null;
-            }
-            if ( ( !( value instanceof PasswordValue ) ) )
-            {
-                throw new IllegalArgumentException( "setting value is not readable as password" );
-            }
-            final Object nativeObject = value.toNativeObject();
-            if ( nativeObject == null )
-            {
-                return null;
-            }
-            return ( PasswordData ) nativeObject;
-        }
-
-        public static Map<String, NamedSecretData> valueToNamedPassword( final StoredValue value )
-        {
-            if ( value == null )
-            {
-                return null;
-            }
-            if ( ( !( value instanceof NamedSecretValue ) ) )
-            {
-                throw new IllegalArgumentException( "setting value is not readable as named password" );
-            }
-            final Object nativeObject = value.toNativeObject();
-            if ( nativeObject == null )
-            {
-                return null;
-            }
-            return ( Map<String, NamedSecretData> ) nativeObject;
-        }
-
-        public static List<RemoteWebServiceConfiguration> valueToRemoteWebServiceConfiguration( final StoredValue value )
-        {
-            if ( value == null )
-            {
-                return null;
-            }
-            if ( ( !( value instanceof RemoteWebServiceValue ) ) )
-            {
-                throw new IllegalArgumentException( "setting value is not readable as named password" );
-            }
-            final Object nativeObject = value.toNativeObject();
-            if ( nativeObject == null )
-            {
-                return null;
-            }
-            return ( List<RemoteWebServiceConfiguration> ) nativeObject;
-        }
-
-        public static List<ActionConfiguration> valueToAction( final PwmSetting setting, final StoredValue storedValue )
-        {
-            if ( PwmSettingSyntax.ACTION != setting.getSyntax() )
-            {
-                throw new IllegalArgumentException( "may not read ACTION value for setting: " + setting.toString() );
-            }
-
-            return ( List<ActionConfiguration> ) storedValue.toNativeObject();
-        }
-
-        public static List<X509Certificate> valueToX509Certificates( final PwmSetting setting, final StoredValue storedValue  )
-        {
-            if ( PwmSettingSyntax.X509CERT != setting.getSyntax() )
-            {
-                throw new IllegalArgumentException( "may not read X509CERT value for setting: " + setting.toString() );
-            }
-
-            final Object nativeObject = storedValue.toNativeObject();
-            final X509Certificate[] arrayCerts = ( X509Certificate[] ) nativeObject;
-            return arrayCerts == null ? Collections.emptyList() : Collections.unmodifiableList( Arrays.asList( arrayCerts ) );
-        }
-
-        public static List<FormConfiguration> valueToForm( final StoredValue value )
-        {
-            if ( value == null )
-            {
-                return null;
-            }
-
-            if ( value instanceof CustomLinkValue )
-            {
-                return ( List<FormConfiguration> ) value.toNativeObject();
-            }
-
-            if ( ( !( value instanceof FormValue ) ) )
-            {
-                throw new IllegalArgumentException( "setting value is not readable as form" );
-            }
-
-            return ( List<FormConfiguration> ) value.toNativeObject();
-        }
-
-        public static List<String> valueToStringArray( final StoredValue value )
-        {
-            if ( !( value instanceof StringArrayValue ) )
-            {
-                throw new IllegalArgumentException( "setting value is not readable as string array" );
-            }
-
-            final List<String> results = new ArrayList<>( ( List<String> ) value.toNativeObject() );
-            for ( final Iterator iter = results.iterator(); iter.hasNext(); )
-            {
-                final Object loopString = iter.next();
-                if ( loopString == null || loopString.toString().length() < 1 )
-                {
-                    iter.remove();
-                }
-            }
-            return results;
-        }
-
-        public static List<UserPermission> valueToUserPermissions( final StoredValue value )
-        {
-            if ( value == null )
-            {
-                return Collections.emptyList();
-            }
-
-            if ( !( value instanceof UserPermissionValue ) )
-            {
-                throw new IllegalArgumentException( "setting value is not readable as string array" );
-            }
-
-            final List<UserPermission> results = new ArrayList<>( ( List<UserPermission> ) value.toNativeObject() );
-            for ( final Iterator iter = results.iterator(); iter.hasNext(); )
-            {
-                final Object loopString = iter.next();
-                if ( loopString == null || loopString.toString().length() < 1 )
-                {
-                    iter.remove();
-                }
-            }
-            return results;
-        }
-
-        public static boolean valueToBoolean( final StoredValue value )
-        {
-            if ( !( value instanceof BooleanValue ) )
-            {
-                throw new IllegalArgumentException( "may not read BOOLEAN value for setting" );
-            }
-
-            return ( Boolean ) value.toNativeObject();
-        }
-
-        public static String valueToLocalizedString( final StoredValue value, final Locale locale )
-        {
-            if ( !( value instanceof LocalizedStringValue ) )
-            {
-                throw new IllegalArgumentException( "may not read LOCALIZED_STRING or LOCALIZED_TEXT_AREA values for setting" );
-            }
-
-            final Map<String, String> availableValues = ( Map<String, String> ) value.toNativeObject();
-            final Map<Locale, String> availableLocaleMap = new LinkedHashMap<>();
-            for ( final Map.Entry<String, String> entry : availableValues.entrySet() )
-            {
-                final String localeStr = entry.getKey();
-                availableLocaleMap.put( LocaleHelper.parseLocaleString( localeStr ), entry.getValue() );
-            }
-            final Locale matchedLocale = LocaleHelper.localeResolver( locale, availableLocaleMap.keySet() );
-
-            return availableLocaleMap.get( matchedLocale );
-        }
-
-        public static List<String> valueToLocalizedStringArray( final StoredValue value, final Locale locale )
-        {
-            if ( !( value instanceof LocalizedStringArrayValue ) )
-            {
-                throw new IllegalArgumentException( "may not read LOCALIZED_STRING_ARRAY value" );
-            }
-            final Map<String, List<String>> storedValues = ( Map<String, List<String>> ) value.toNativeObject();
-            final Map<Locale, List<String>> availableLocaleMap = new LinkedHashMap<>();
-            for ( final Map.Entry<String, List<String>> entry : storedValues.entrySet() )
-            {
-                final String localeStr = entry.getKey();
-                availableLocaleMap.put( LocaleHelper.parseLocaleString( localeStr ), entry.getValue() );
-            }
-            final Locale matchedLocale = LocaleHelper.localeResolver( locale, availableLocaleMap.keySet() );
-
-            return availableLocaleMap.get( matchedLocale );
-        }
-
-        public static <E extends Enum<E>> E valueToEnum( final PwmSetting setting, final StoredValue value, final Class<E> enumClass )
-        {
-            if ( PwmSettingSyntax.SELECT != setting.getSyntax() )
-            {
-                throw new IllegalArgumentException( "may not read SELECT enum value for setting: " + setting.toString() );
-            }
-
-            if ( value != null )
-            {
-                final String strValue = ( String ) value.toNativeObject();
-                try
-                {
-                    return ( E ) enumClass.getMethod( "valueOf", String.class ).invoke( null, strValue );
-                }
-                catch ( final InvocationTargetException e1 )
-                {
-                    if ( e1.getCause() instanceof IllegalArgumentException )
-                    {
-                        LOGGER.error( () -> "illegal setting value for option '" + strValue + "' for setting key '" + setting.getKey() + "' is not recognized, will use default" );
-                    }
-                }
-                catch ( final Exception e1 )
-                {
-                    LOGGER.error( () -> "unexpected error", e1 );
-                }
-            }
-
-            return null;
-        }
-
-        public static <E extends Enum<E>> Set<E> valueToOptionList( final PwmSetting setting, final StoredValue value, final Class<E> enumClass )
-        {
-            if ( PwmSettingSyntax.OPTIONLIST != setting.getSyntax() )
-            {
-                throw new IllegalArgumentException( "may not read optionlist value for setting: " + setting.toString() );
-            }
-
-            final Set<E> returnSet = new LinkedHashSet<>();
-            final Set<String> strValues = ( Set<String> ) value.toNativeObject();
-            for ( final String strValue : strValues )
-            {
-                try
-                {
-                    returnSet.add( ( E ) enumClass.getMethod( "valueOf", String.class ).invoke( null, strValue ) );
-                }
-                catch ( final InvocationTargetException e1 )
-                {
-                    if ( e1.getCause() instanceof IllegalArgumentException )
-                    {
-                        LOGGER.error( () -> "illegal setting value for option '" + strValue + "' is not recognized, will use default" );
-                    }
-                }
-                catch ( final Exception e1 )
-                {
-                    LOGGER.error( () -> "unexpected error", e1 );
-                }
-            }
-
-            return Collections.unmodifiableSet( returnSet );
-        }
+        return ValueTypeConverter.valueToNamedPassword( readStoredValue( setting ) );
     }
     }
 
 
     public Map<Locale, String> readLocalizedBundle( final PwmLocaleBundle className, final String keyName )
     public Map<Locale, String> readLocalizedBundle( final PwmLocaleBundle className, final String keyName )
@@ -559,12 +260,12 @@ public class Configuration implements SettingReader
 
 
     public List<Long> readSettingAsLongArray( final PwmSetting setting )
     public List<Long> readSettingAsLongArray( final PwmSetting setting )
     {
     {
-        return JavaTypeConverter.valueToLongArray( readStoredValue( setting ) );
+        return ValueTypeConverter.valueToLongArray( readStoredValue( setting ) );
     }
     }
 
 
     public long readSettingAsLong( final PwmSetting setting )
     public long readSettingAsLong( final PwmSetting setting )
     {
     {
-        return JavaTypeConverter.valueToLong( readStoredValue( setting ) );
+        return ValueTypeConverter.valueToLong( readStoredValue( setting ) );
     }
     }
 
 
     public PwmPasswordPolicy getPasswordPolicy( final String profile, final Locale locale )
     public PwmPasswordPolicy getPasswordPolicy( final String profile, final Locale locale )
@@ -604,20 +305,20 @@ public class Configuration implements SettingReader
                     case DisallowedValues:
                     case DisallowedValues:
                     case CharGroupsValues:
                     case CharGroupsValues:
                         value = StringHelper.stringCollectionToString(
                         value = StringHelper.stringCollectionToString(
-                                JavaTypeConverter.valueToStringArray( storedConfiguration.readSetting( pwmSetting, profile ) ), "\n" );
+                                ValueTypeConverter.valueToStringArray( storedConfiguration.readSetting( pwmSetting, profile ) ), "\n" );
                         break;
                         break;
                     case RegExMatch:
                     case RegExMatch:
                     case RegExNoMatch:
                     case RegExNoMatch:
                         value = StringHelper.stringCollectionToString(
                         value = StringHelper.stringCollectionToString(
-                                JavaTypeConverter.valueToStringArray( storedConfiguration.readSetting( pwmSetting,
+                                ValueTypeConverter.valueToStringArray( storedConfiguration.readSetting( pwmSetting,
                                         profile ) ), ";;;" );
                                         profile ) ), ";;;" );
                         break;
                         break;
                     case ChangeMessage:
                     case ChangeMessage:
-                        value = JavaTypeConverter.valueToLocalizedString(
+                        value = ValueTypeConverter.valueToLocalizedString(
                                 storedConfiguration.readSetting( pwmSetting, profile ), locale );
                                 storedConfiguration.readSetting( pwmSetting, profile ), locale );
                         break;
                         break;
                     case ADComplexityLevel:
                     case ADComplexityLevel:
-                        value = JavaTypeConverter.valueToEnum(
+                        value = ValueTypeConverter.valueToEnum(
                                 pwmSetting, storedConfiguration.readSetting( pwmSetting, profile ),
                                 pwmSetting, storedConfiguration.readSetting( pwmSetting, profile ),
                                 ADPolicyComplexity.class
                                 ADPolicyComplexity.class
                         ).toString();
                         ).toString();
@@ -634,7 +335,7 @@ public class Configuration implements SettingReader
         }
         }
 
 
         // set case sensitivity
         // set case sensitivity
-        final String caseSensitivitySetting = JavaTypeConverter.valueToString( storedConfiguration.readSetting(
+        final String caseSensitivitySetting = ValueTypeConverter.valueToString( storedConfiguration.readSetting(
                 PwmSetting.PASSWORD_POLICY_CASE_SENSITIVITY, null ) );
                 PwmSetting.PASSWORD_POLICY_CASE_SENSITIVITY, null ) );
         if ( !"read".equals( caseSensitivitySetting ) )
         if ( !"read".equals( caseSensitivitySetting ) )
         {
         {
@@ -643,7 +344,7 @@ public class Configuration implements SettingReader
 
 
         // set pwm-specific values
         // set pwm-specific values
         final List<UserPermission> queryMatch = ( List<UserPermission> ) storedConfiguration.readSetting( PwmSetting.PASSWORD_POLICY_QUERY_MATCH, profile ).toNativeObject();
         final List<UserPermission> queryMatch = ( List<UserPermission> ) storedConfiguration.readSetting( PwmSetting.PASSWORD_POLICY_QUERY_MATCH, profile ).toNativeObject();
-        final String ruleText = JavaTypeConverter.valueToLocalizedString( storedConfiguration.readSetting( PwmSetting.PASSWORD_POLICY_RULE_TEXT, profile ), locale );
+        final String ruleText = ValueTypeConverter.valueToLocalizedString( storedConfiguration.readSetting( PwmSetting.PASSWORD_POLICY_RULE_TEXT, profile ), locale );
 
 
         final PwmPasswordPolicy.PolicyMetaData policyMetaData = PwmPasswordPolicy.PolicyMetaData.builder()
         final PwmPasswordPolicy.PolicyMetaData policyMetaData = PwmPasswordPolicy.PolicyMetaData.builder()
                 .profileID( profile )
                 .profileID( profile )
@@ -656,12 +357,12 @@ public class Configuration implements SettingReader
 
 
     public List<String> readSettingAsStringArray( final PwmSetting setting )
     public List<String> readSettingAsStringArray( final PwmSetting setting )
     {
     {
-        return JavaTypeConverter.valueToStringArray( readStoredValue( setting ) );
+        return ValueTypeConverter.valueToStringArray( readStoredValue( setting ) );
     }
     }
 
 
     public String readSettingAsLocalizedString( final PwmSetting setting, final Locale locale )
     public String readSettingAsLocalizedString( final PwmSetting setting, final Locale locale )
     {
     {
-        return JavaTypeConverter.valueToLocalizedString( readStoredValue( setting ), locale );
+        return ValueTypeConverter.valueToLocalizedString( readStoredValue( setting ), locale );
     }
     }
 
 
     public boolean isDefaultValue( final PwmSetting pwmSetting )
     public boolean isDefaultValue( final PwmSetting pwmSetting )
@@ -699,18 +400,17 @@ public class Configuration implements SettingReader
 
 
     public boolean readSettingAsBoolean( final PwmSetting setting )
     public boolean readSettingAsBoolean( final PwmSetting setting )
     {
     {
-        return JavaTypeConverter.valueToBoolean( readStoredValue( setting ) );
+        return ValueTypeConverter.valueToBoolean( readStoredValue( setting ) );
     }
     }
 
 
     public Map<FileValue.FileInformation, FileValue.FileContent> readSettingAsFile( final PwmSetting setting )
     public Map<FileValue.FileInformation, FileValue.FileContent> readSettingAsFile( final PwmSetting setting )
     {
     {
-        final FileValue fileValue = ( FileValue ) storedConfiguration.readSetting( setting, null );
-        return ( Map ) fileValue.toNativeObject();
+        return ValueTypeConverter.valueToFile( setting, readStoredValue( setting ) );
     }
     }
 
 
     public List<X509Certificate> readSettingAsCertificate( final PwmSetting setting )
     public List<X509Certificate> readSettingAsCertificate( final PwmSetting setting )
     {
     {
-        return JavaTypeConverter.valueToX509Certificates( setting, readStoredValue( setting ) );
+        return ValueTypeConverter.valueToX509Certificates( setting, readStoredValue( setting ) );
     }
     }
 
 
     public PrivateKeyCertificate readSettingAsPrivateKey( final PwmSetting setting )
     public PrivateKeyCertificate readSettingAsPrivateKey( final PwmSetting setting )

+ 1 - 0
server/src/main/java/password/pwm/config/PwmSetting.java

@@ -22,6 +22,7 @@ package password.pwm.config;
 
 
 import lombok.Value;
 import lombok.Value;
 import password.pwm.config.value.PasswordValue;
 import password.pwm.config.value.PasswordValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.ValueFactory;
 import password.pwm.config.value.ValueFactory;
 import password.pwm.i18n.Config;
 import password.pwm.i18n.Config;
 import password.pwm.util.i18n.LocaleHelper;
 import password.pwm.util.i18n.LocaleHelper;

+ 1 - 0
server/src/main/java/password/pwm/config/PwmSettingSyntax.java

@@ -36,6 +36,7 @@ import password.pwm.config.value.OptionListValue;
 import password.pwm.config.value.PasswordValue;
 import password.pwm.config.value.PasswordValue;
 import password.pwm.config.value.PrivateKeyValue;
 import password.pwm.config.value.PrivateKeyValue;
 import password.pwm.config.value.RemoteWebServiceValue;
 import password.pwm.config.value.RemoteWebServiceValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.StringArrayValue;
 import password.pwm.config.value.StringArrayValue;
 import password.pwm.config.value.StringValue;
 import password.pwm.config.value.StringValue;
 import password.pwm.config.value.UserPermissionValue;
 import password.pwm.config.value.UserPermissionValue;

+ 1 - 1
server/src/main/java/password/pwm/config/function/AbstractUriCertImportFunction.java

@@ -110,7 +110,7 @@ abstract class AbstractUriCertImportFunction implements SettingUIFunction
     )
     )
             throws PwmOperationalException, PwmUnrecoverableException
             throws PwmOperationalException, PwmUnrecoverableException
     {
     {
-        storedConfiguration.writeSetting( pwmSetting, profile, new X509CertificateValue( certs ), userIdentity );
+        storedConfiguration.writeSetting( pwmSetting, profile, X509CertificateValue.fromX509( certs ), userIdentity );
     }
     }
 
 
 
 

+ 7 - 4
server/src/main/java/password/pwm/config/function/ActionCertImportFunction.java

@@ -25,6 +25,8 @@ import password.pwm.bean.UserIdentity;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.stored.StoredConfigurationModifier;
 import password.pwm.config.stored.StoredConfigurationModifier;
 import password.pwm.config.value.ActionValue;
 import password.pwm.config.value.ActionValue;
+import password.pwm.config.value.StoredValue;
+import password.pwm.config.value.ValueTypeConverter;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmError;
@@ -55,8 +57,9 @@ public class ActionCertImportFunction extends AbstractUriCertImportFunction
         {
         {
         } );
         } );
 
 
-        final ActionValue actionValue = ( ActionValue ) modifier.newStoredConfiguration().readSetting( pwmSetting, profile );
-        final ActionConfiguration action = ( actionValue.toNativeObject() ).get( extraDataMap.get( KEY_ITERATION ) );
+        final StoredValue actionValue = modifier.newStoredConfiguration().readSetting( pwmSetting, profile );
+        final List<ActionConfiguration> actionConfigurations = ValueTypeConverter.valueToAction( pwmSetting, actionValue );
+        final ActionConfiguration action = actionConfigurations.get( extraDataMap.get( KEY_ITERATION ) );
         final ActionConfiguration.WebAction webAction = action.getWebActions().get( extraDataMap.get( KEY_WEB_ACTION_ITERATION ) );
         final ActionConfiguration.WebAction webAction = action.getWebActions().get( extraDataMap.get( KEY_WEB_ACTION_ITERATION ) );
 
 
         final String uriString = webAction.getUrl();
         final String uriString = webAction.getUrl();
@@ -97,8 +100,8 @@ public class ActionCertImportFunction extends AbstractUriCertImportFunction
         {
         {
         } );
         } );
 
 
-        final ActionValue actionValue = ( ActionValue ) storedConfiguration.newStoredConfiguration().readSetting( pwmSetting, profile );
-        final List<ActionConfiguration> actionConfigurations = actionValue.toNativeObject();
+        final StoredValue actionValue = storedConfiguration.newStoredConfiguration().readSetting( pwmSetting, profile );
+        final List<ActionConfiguration> actionConfigurations = ValueTypeConverter.valueToAction( pwmSetting, actionValue );
         final ActionConfiguration action = actionConfigurations.get( extraDataMap.get( KEY_ITERATION ) );
         final ActionConfiguration action = actionConfigurations.get( extraDataMap.get( KEY_ITERATION ) );
         final ActionConfiguration.WebAction webAction = action.getWebActions().get( extraDataMap.get( KEY_WEB_ACTION_ITERATION ) );
         final ActionConfiguration.WebAction webAction = action.getWebActions().get( extraDataMap.get( KEY_WEB_ACTION_ITERATION ) );
 
 

+ 1 - 1
server/src/main/java/password/pwm/config/function/LdapCertImportFunction.java

@@ -62,7 +62,7 @@ public class LdapCertImportFunction implements SettingUIFunction
         }
         }
 
 
         final UserIdentity userIdentity = pwmSession.isAuthenticated() ? pwmSession.getUserInfo().getUserIdentity() : null;
         final UserIdentity userIdentity = pwmSession.isAuthenticated() ? pwmSession.getUserInfo().getUserIdentity() : null;
-        modifier.writeSetting( setting, profile, new X509CertificateValue( resultCertificates ), userIdentity );
+        modifier.writeSetting( setting, profile, X509CertificateValue.fromX509( resultCertificates ), userIdentity );
         return Message.getLocalizedMessage( pwmSession.getSessionStateBean().getLocale(), Message.Success_Unknown, pwmApplication.getConfig() );
         return Message.getLocalizedMessage( pwmSession.getSessionStateBean().getLocale(), Message.Success_Unknown, pwmApplication.getConfig() );
     }
     }
 
 

+ 1 - 1
server/src/main/java/password/pwm/config/function/SmtpCertImportFunction.java

@@ -55,7 +55,7 @@ public class SmtpCertImportFunction implements SettingUIFunction
         if ( !JavaHelper.isEmpty( certs ) )
         if ( !JavaHelper.isEmpty( certs ) )
         {
         {
             final UserIdentity userIdentity = pwmSession.isAuthenticated() ? pwmSession.getUserInfo().getUserIdentity() : null;
             final UserIdentity userIdentity = pwmSession.isAuthenticated() ? pwmSession.getUserInfo().getUserIdentity() : null;
-            modifier.writeSetting( PwmSetting.EMAIL_SERVER_CERTS, profile, new X509CertificateValue( certs ), userIdentity );
+            modifier.writeSetting( PwmSetting.EMAIL_SERVER_CERTS, profile, X509CertificateValue.fromX509( certs ), userIdentity );
         }
         }
 
 
         return Message.getLocalizedMessage( pwmSession.getSessionStateBean().getLocale(), Message.Success_Unknown, pwmRequest.getConfig() );
         return Message.getLocalizedMessage( pwmSession.getSessionStateBean().getLocale(), Message.Success_Unknown, pwmRequest.getConfig() );

+ 1 - 1
server/src/main/java/password/pwm/config/function/SyslogCertImportFunction.java

@@ -98,7 +98,7 @@ public class SyslogCertImportFunction implements SettingUIFunction
         if ( !error )
         if ( !error )
         {
         {
             final UserIdentity userIdentity = pwmSession.isAuthenticated() ? pwmSession.getUserInfo().getUserIdentity() : null;
             final UserIdentity userIdentity = pwmSession.isAuthenticated() ? pwmSession.getUserInfo().getUserIdentity() : null;
-            modifier.writeSetting( setting, null, new X509CertificateValue( resultCertificates ), userIdentity );
+            modifier.writeSetting( setting, null, X509CertificateValue.fromX509( resultCertificates ), userIdentity );
             return Message.getLocalizedMessage( pwmSession.getSessionStateBean().getLocale(), Message.Success_Unknown, pwmApplication.getConfig() );
             return Message.getLocalizedMessage( pwmSession.getSessionStateBean().getLocale(), Message.Success_Unknown, pwmApplication.getConfig() );
         }
         }
         else
         else

+ 14 - 13
server/src/main/java/password/pwm/config/profile/AbstractProfile.java

@@ -23,10 +23,11 @@ package password.pwm.config.profile;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.SettingReader;
 import password.pwm.config.SettingReader;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.option.IdentityVerificationMethod;
 import password.pwm.config.option.IdentityVerificationMethod;
 import password.pwm.config.option.MessageSendMethod;
 import password.pwm.config.option.MessageSendMethod;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
+import password.pwm.config.value.ValueTypeConverter;
 import password.pwm.config.value.VerificationMethodValue;
 import password.pwm.config.value.VerificationMethodValue;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.config.value.data.FormConfiguration;
@@ -65,37 +66,37 @@ public abstract class AbstractProfile implements Profile, SettingReader
 
 
     public List<UserPermission> readSettingAsUserPermission( final PwmSetting setting )
     public List<UserPermission> readSettingAsUserPermission( final PwmSetting setting )
     {
     {
-        return Configuration.JavaTypeConverter.valueToUserPermissions( readSetting( setting ) );
+        return ValueTypeConverter.valueToUserPermissions( readSetting( setting ) );
     }
     }
 
 
     public String readSettingAsString( final PwmSetting setting )
     public String readSettingAsString( final PwmSetting setting )
     {
     {
-        return Configuration.JavaTypeConverter.valueToString( readSetting( setting ) );
+        return ValueTypeConverter.valueToString( readSetting( setting ) );
     }
     }
 
 
     @Override
     @Override
     public List<String> readSettingAsStringArray( final PwmSetting setting )
     public List<String> readSettingAsStringArray( final PwmSetting setting )
     {
     {
-        return Configuration.JavaTypeConverter.valueToStringArray( readSetting( setting ) );
+        return ValueTypeConverter.valueToStringArray( readSetting( setting ) );
     }
     }
 
 
     @Override
     @Override
     public List<FormConfiguration> readSettingAsForm( final PwmSetting setting )
     public List<FormConfiguration> readSettingAsForm( final PwmSetting setting )
     {
     {
-        return Configuration.JavaTypeConverter.valueToForm( readSetting( setting ) );
+        return ValueTypeConverter.valueToForm( readSetting( setting ) );
     }
     }
 
 
     @Override
     @Override
     public <E extends Enum<E>> Set<E> readSettingAsOptionList( final PwmSetting setting, final Class<E> enumClass )
     public <E extends Enum<E>> Set<E> readSettingAsOptionList( final PwmSetting setting, final Class<E> enumClass )
     {
     {
-        return Configuration.JavaTypeConverter.valueToOptionList( setting, readSetting( setting ), enumClass );
+        return ValueTypeConverter.valueToOptionList( setting, readSetting( setting ), enumClass );
     }
     }
 
 
     @Override
     @Override
     public <E extends Enum<E>> E readSettingAsEnum( final PwmSetting setting, final Class<E> enumClass )
     public <E extends Enum<E>> E readSettingAsEnum( final PwmSetting setting, final Class<E> enumClass )
     {
     {
         final StoredValue value = readSetting( setting );
         final StoredValue value = readSetting( setting );
-        final E returnValue = Configuration.JavaTypeConverter.valueToEnum( setting, value, enumClass );
+        final E returnValue = ValueTypeConverter.valueToEnum( setting, value, enumClass );
         if ( MessageSendMethod.class.equals( enumClass ) )
         if ( MessageSendMethod.class.equals( enumClass ) )
         {
         {
             Configuration.deprecatedSettingException( setting, this.getIdentifier(), ( MessageSendMethod ) returnValue );
             Configuration.deprecatedSettingException( setting, this.getIdentifier(), ( MessageSendMethod ) returnValue );
@@ -106,37 +107,37 @@ public abstract class AbstractProfile implements Profile, SettingReader
 
 
     public List<ActionConfiguration> readSettingAsAction( final PwmSetting setting )
     public List<ActionConfiguration> readSettingAsAction( final PwmSetting setting )
     {
     {
-        return Configuration.JavaTypeConverter.valueToAction( setting, readSetting( setting ) );
+        return ValueTypeConverter.valueToAction( setting, readSetting( setting ) );
     }
     }
 
 
     @Override
     @Override
     public List<X509Certificate> readSettingAsCertificate( final PwmSetting setting )
     public List<X509Certificate> readSettingAsCertificate( final PwmSetting setting )
     {
     {
-        return Configuration.JavaTypeConverter.valueToX509Certificates( setting, readSetting( setting ) );
+        return ValueTypeConverter.valueToX509Certificates( setting, readSetting( setting ) );
     }
     }
 
 
     @Override
     @Override
     public boolean readSettingAsBoolean( final PwmSetting setting )
     public boolean readSettingAsBoolean( final PwmSetting setting )
     {
     {
-        return Configuration.JavaTypeConverter.valueToBoolean( readSetting( setting ) );
+        return ValueTypeConverter.valueToBoolean( readSetting( setting ) );
     }
     }
 
 
     @Override
     @Override
     public long readSettingAsLong( final PwmSetting setting )
     public long readSettingAsLong( final PwmSetting setting )
     {
     {
-        return Configuration.JavaTypeConverter.valueToLong( readSetting( setting ) );
+        return ValueTypeConverter.valueToLong( readSetting( setting ) );
     }
     }
 
 
     @Override
     @Override
     public String readSettingAsLocalizedString( final PwmSetting setting, final Locale locale )
     public String readSettingAsLocalizedString( final PwmSetting setting, final Locale locale )
     {
     {
-        return Configuration.JavaTypeConverter.valueToLocalizedString( readSetting( setting ), locale );
+        return ValueTypeConverter.valueToLocalizedString( readSetting( setting ), locale );
     }
     }
 
 
     @Override
     @Override
     public PasswordData readSettingAsPassword( final PwmSetting setting )
     public PasswordData readSettingAsPassword( final PwmSetting setting )
     {
     {
-        return Configuration.JavaTypeConverter.valueToPassword( readSetting( setting ) );
+        return ValueTypeConverter.valueToPassword( readSetting( setting ) );
     }
     }
 
 
     @Override
     @Override

+ 5 - 5
server/src/main/java/password/pwm/config/profile/ChallengeProfile.java

@@ -26,11 +26,11 @@ import com.novell.ldapchai.cr.Challenge;
 import com.novell.ldapchai.cr.ChallengeSet;
 import com.novell.ldapchai.cr.ChallengeSet;
 import com.novell.ldapchai.exception.ChaiValidationException;
 import com.novell.ldapchai.exception.ChaiValidationException;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
-import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.value.ChallengeValue;
 import password.pwm.config.value.ChallengeValue;
+import password.pwm.config.value.ValueTypeConverter;
 import password.pwm.config.value.data.ChallengeItemConfiguration;
 import password.pwm.config.value.data.ChallengeItemConfiguration;
 import password.pwm.config.value.data.UserPermission;
 import password.pwm.config.value.data.UserPermission;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;
@@ -84,7 +84,7 @@ public class ChallengeProfile implements Profile, Serializable
             final StoredConfiguration storedConfiguration
             final StoredConfiguration storedConfiguration
     )
     )
     {
     {
-        final int minRandomRequired = ( int ) Configuration.JavaTypeConverter.valueToLong( storedConfiguration.readSetting( PwmSetting.CHALLENGE_MIN_RANDOM_REQUIRED, profileID ) );
+        final int minRandomRequired = ( int ) ValueTypeConverter.valueToLong( storedConfiguration.readSetting( PwmSetting.CHALLENGE_MIN_RANDOM_REQUIRED, profileID ) );
 
 
         ChallengeSet readChallengeSet = null;
         ChallengeSet readChallengeSet = null;
         try
         try
@@ -120,8 +120,8 @@ public class ChallengeProfile implements Profile, Serializable
             LOGGER.trace( () -> "discarding configured helpdesk challengeSet for profile '" + profileID + "' issue: " + e.getMessage() );
             LOGGER.trace( () -> "discarding configured helpdesk challengeSet for profile '" + profileID + "' issue: " + e.getMessage() );
         }
         }
 
 
-        final int minRandomSetup = ( int ) Configuration.JavaTypeConverter.valueToLong( storedConfiguration.readSetting( PwmSetting.CHALLENGE_MIN_RANDOM_SETUP, profileID ) );
-        final int minHelpdeskRandomSetup = ( int ) Configuration.JavaTypeConverter.valueToLong( storedConfiguration.readSetting(
+        final int minRandomSetup = ( int ) ValueTypeConverter.valueToLong( storedConfiguration.readSetting( PwmSetting.CHALLENGE_MIN_RANDOM_SETUP, profileID ) );
+        final int minHelpdeskRandomSetup = ( int ) ValueTypeConverter.valueToLong( storedConfiguration.readSetting(
                 PwmSetting.CHALLENGE_HELPDESK_MIN_RANDOM_SETUP,
                 PwmSetting.CHALLENGE_HELPDESK_MIN_RANDOM_SETUP,
                 profileID
                 profileID
         ) );
         ) );

+ 1 - 1
server/src/main/java/password/pwm/config/profile/ForgottenPasswordProfile.java

@@ -21,7 +21,7 @@
 package password.pwm.config.profile;
 package password.pwm.config.profile;
 
 
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.option.IdentityVerificationMethod;
 import password.pwm.config.option.IdentityVerificationMethod;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.value.VerificationMethodValue;
 import password.pwm.config.value.VerificationMethodValue;

+ 11 - 6
server/src/main/java/password/pwm/config/stored/ConfigurationCleaner.java

@@ -24,12 +24,13 @@ import password.pwm.PwmConstants;
 import password.pwm.bean.UserIdentity;
 import password.pwm.bean.UserIdentity;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.option.ADPolicyComplexity;
 import password.pwm.config.option.ADPolicyComplexity;
 import password.pwm.config.option.RecoveryMinLifetimeOption;
 import password.pwm.config.option.RecoveryMinLifetimeOption;
 import password.pwm.config.option.WebServiceUsage;
 import password.pwm.config.option.WebServiceUsage;
 import password.pwm.config.value.OptionListValue;
 import password.pwm.config.value.OptionListValue;
 import password.pwm.config.value.StringValue;
 import password.pwm.config.value.StringValue;
+import password.pwm.config.value.ValueTypeConverter;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.util.java.PwmExceptionLoggingConsumer;
 import password.pwm.util.java.PwmExceptionLoggingConsumer;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
@@ -77,7 +78,7 @@ class ConfigurationCleaner
             {
             {
                 if ( !oldConfig.isDefaultValue( PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY, profileID ) )
                 if ( !oldConfig.isDefaultValue( PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY, profileID ) )
                 {
                 {
-                    final boolean ad2003Enabled = ( boolean ) oldConfig.readSetting( PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY, profileID ).toNativeObject();
+                    final boolean ad2003Enabled = ValueTypeConverter.valueToBoolean( oldConfig.readSetting( PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY, profileID ) );
                     final StoredValue value;
                     final StoredValue value;
                     if ( ad2003Enabled )
                     if ( ad2003Enabled )
                     {
                     {
@@ -87,8 +88,11 @@ class ConfigurationCleaner
                     {
                     {
                         value = new StringValue( ADPolicyComplexity.NONE.toString() );
                         value = new StringValue( ADPolicyComplexity.NONE.toString() );
                     }
                     }
-                    LOGGER.info( () -> "converting deprecated non-default setting " + PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY.getKey() + "/" + profileID
-                            + " to replacement setting " + PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY_LEVEL + ", value=" + value.toNativeObject().toString() );
+                    LOGGER.info( () -> "converting deprecated non-default setting "
+                            + PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY.getKey() + "/" + profileID
+                            + " to replacement setting "
+                            + PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY_LEVEL + ", value="
+                            + ValueTypeConverter.valueToBoolean( value ) );
                     final Optional<ValueMetaData> valueMetaData = oldConfig.readMetaData(
                     final Optional<ValueMetaData> valueMetaData = oldConfig.readMetaData(
                             StoredConfigItemKey.fromSetting( PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY, profileID ) );
                             StoredConfigItemKey.fromSetting( PwmSetting.PASSWORD_POLICY_AD_COMPLEXITY, profileID ) );
                     final UserIdentity userIdentity = valueMetaData.map( ValueMetaData::getUserIdentity ).orElse( null );
                     final UserIdentity userIdentity = valueMetaData.map( ValueMetaData::getUserIdentity ).orElse( null );
@@ -109,7 +113,7 @@ class ConfigurationCleaner
             {
             {
                 if ( !oldConfig.isDefaultValue( PwmSetting.RECOVERY_ENFORCE_MINIMUM_PASSWORD_LIFETIME, profileID ) )
                 if ( !oldConfig.isDefaultValue( PwmSetting.RECOVERY_ENFORCE_MINIMUM_PASSWORD_LIFETIME, profileID ) )
                 {
                 {
-                    final boolean enforceEnabled = ( boolean ) oldConfig.readSetting( PwmSetting.RECOVERY_ENFORCE_MINIMUM_PASSWORD_LIFETIME, profileID ).toNativeObject();
+                    final boolean enforceEnabled = ValueTypeConverter.valueToBoolean( oldConfig.readSetting( PwmSetting.RECOVERY_ENFORCE_MINIMUM_PASSWORD_LIFETIME, profileID ) );
                     final StoredValue value = enforceEnabled
                     final StoredValue value = enforceEnabled
                             ? new StringValue( RecoveryMinLifetimeOption.NONE.name() )
                             ? new StringValue( RecoveryMinLifetimeOption.NONE.name() )
                             : new StringValue( RecoveryMinLifetimeOption.ALLOW.name() );
                             : new StringValue( RecoveryMinLifetimeOption.ALLOW.name() );
@@ -120,7 +124,8 @@ class ConfigurationCleaner
                     LOGGER.info( () -> "converting deprecated non-default setting "
                     LOGGER.info( () -> "converting deprecated non-default setting "
                             + PwmSetting.RECOVERY_ENFORCE_MINIMUM_PASSWORD_LIFETIME.toMenuLocationDebug( profileID, PwmConstants.DEFAULT_LOCALE ) + "/" + profileID
                             + PwmSetting.RECOVERY_ENFORCE_MINIMUM_PASSWORD_LIFETIME.toMenuLocationDebug( profileID, PwmConstants.DEFAULT_LOCALE ) + "/" + profileID
                             + " to replacement setting " + PwmSetting.RECOVERY_MINIMUM_PASSWORD_LIFETIME_OPTIONS.toMenuLocationDebug( profileID, PwmConstants.DEFAULT_LOCALE )
                             + " to replacement setting " + PwmSetting.RECOVERY_MINIMUM_PASSWORD_LIFETIME_OPTIONS.toMenuLocationDebug( profileID, PwmConstants.DEFAULT_LOCALE )
-                            + ", value=" + value.toNativeObject().toString() );
+                            + ", value="
+                            + ValueTypeConverter.valueToBoolean( value ) );
                     modifier.writeSetting( PwmSetting.RECOVERY_MINIMUM_PASSWORD_LIFETIME_OPTIONS, profileID, value, newActor );
                     modifier.writeSetting( PwmSetting.RECOVERY_MINIMUM_PASSWORD_LIFETIME_OPTIONS, profileID, value, newActor );
                 }
                 }
             }
             }

+ 1 - 1
server/src/main/java/password/pwm/config/stored/ConfigurationReader.java

@@ -28,7 +28,7 @@ import password.pwm.PwmConstants;
 import password.pwm.bean.SessionLabel;
 import password.pwm.bean.SessionLabel;
 import password.pwm.bean.UserIdentity;
 import password.pwm.bean.UserIdentity;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmOperationalException;

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfigData.java

@@ -23,7 +23,7 @@ package password.pwm.config.stored;
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Singular;
 import lombok.Singular;
 import lombok.Value;
 import lombok.Value;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 
 
 import java.time.Instant;
 import java.time.Instant;
 import java.util.Collection;
 import java.util.Collection;

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfigXmlSerializer.java

@@ -27,7 +27,7 @@ import password.pwm.config.PwmSettingFlag;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingTemplate;
 import password.pwm.config.PwmSettingTemplate;
 import password.pwm.config.PwmSettingTemplateSet;
 import password.pwm.config.PwmSettingTemplateSet;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.LocalizedStringValue;
 import password.pwm.config.value.LocalizedStringValue;
 import password.pwm.config.value.StoredValueEncoder;
 import password.pwm.config.value.StoredValueEncoder;
 import password.pwm.config.value.StringArrayValue;
 import password.pwm.config.value.StringArrayValue;

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfigZipJsonSerializer.java

@@ -24,7 +24,7 @@ import com.google.gson.reflect.TypeToken;
 import lombok.Value;
 import lombok.Value;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingSyntax;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.FileValue;
 import password.pwm.config.value.FileValue;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfigZipXmlSerializer.java

@@ -23,7 +23,7 @@ package password.pwm.config.stored;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.IOUtils;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingSyntax;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.FileValue;
 import password.pwm.config.value.FileValue;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.http.bean.ImmutableByteArray;
 import password.pwm.http.bean.ImmutableByteArray;

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfiguration.java

@@ -22,7 +22,7 @@ package password.pwm.config.stored;
 
 
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingTemplateSet;
 import password.pwm.config.PwmSettingTemplateSet;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.i18n.PwmLocaleBundle;
 import password.pwm.i18n.PwmLocaleBundle;
 import password.pwm.util.secure.PwmSecurityKey;
 import password.pwm.util.secure.PwmSecurityKey;

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfigurationImpl.java

@@ -23,7 +23,7 @@ package password.pwm.config.stored;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingTemplate;
 import password.pwm.config.PwmSettingTemplate;
 import password.pwm.config.PwmSettingTemplateSet;
 import password.pwm.config.PwmSettingTemplateSet;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.LocalizedStringValue;
 import password.pwm.config.value.LocalizedStringValue;
 import password.pwm.config.value.StringValue;
 import password.pwm.config.value.StringValue;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfigurationModifier.java

@@ -23,7 +23,7 @@ package password.pwm.config.stored;
 import password.pwm.bean.UserIdentity;
 import password.pwm.bean.UserIdentity;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingCategory;
 import password.pwm.config.PwmSettingCategory;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.LocalizedStringValue;
 import password.pwm.config.value.LocalizedStringValue;
 import password.pwm.config.value.StringArrayValue;
 import password.pwm.config.value.StringArrayValue;
 import password.pwm.config.value.StringValue;
 import password.pwm.config.value.StringValue;

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfigurationUtil.java

@@ -27,7 +27,7 @@ import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingCategory;
 import password.pwm.config.PwmSettingCategory;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingTemplateSet;
 import password.pwm.config.PwmSettingTemplateSet;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.PasswordValue;
 import password.pwm.config.value.PasswordValue;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmError;

+ 0 - 1
server/src/main/java/password/pwm/config/value/AbstractValue.java

@@ -21,7 +21,6 @@
 package password.pwm.config.value;
 package password.pwm.config.value;
 
 
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;

+ 0 - 1
server/src/main/java/password/pwm/config/value/ActionValue.java

@@ -24,7 +24,6 @@ import com.google.gson.reflect.TypeToken;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingSyntax;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.value.data.ActionConfiguration;

+ 0 - 1
server/src/main/java/password/pwm/config/value/BooleanValue.java

@@ -22,7 +22,6 @@ package password.pwm.config.value;
 
 
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.i18n.Display;
 import password.pwm.i18n.Display;

+ 0 - 1
server/src/main/java/password/pwm/config/value/ChallengeValue.java

@@ -22,7 +22,6 @@ package password.pwm.config.value;
 
 
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.reflect.TypeToken;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.value.data.ChallengeItemConfiguration;
 import password.pwm.config.value.data.ChallengeItemConfiguration;
 import password.pwm.util.i18n.LocaleHelper;
 import password.pwm.util.i18n.LocaleHelper;

+ 0 - 1
server/src/main/java/password/pwm/config/value/CustomLinkValue.java

@@ -24,7 +24,6 @@ import com.google.gson.reflect.TypeToken;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.value.data.CustomLinkConfiguration;
 import password.pwm.config.value.data.CustomLinkConfiguration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.XmlElement;
 import password.pwm.util.java.XmlElement;

+ 0 - 1
server/src/main/java/password/pwm/config/value/EmailValue.java

@@ -24,7 +24,6 @@ import com.google.gson.reflect.TypeToken;
 
 
 import password.pwm.bean.EmailItemBean;
 import password.pwm.bean.EmailItemBean;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.util.i18n.LocaleHelper;
 import password.pwm.util.i18n.LocaleHelper;

+ 0 - 1
server/src/main/java/password/pwm/config/value/FileValue.java

@@ -24,7 +24,6 @@ import lombok.Builder;
 import lombok.Value;
 import lombok.Value;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;

+ 0 - 1
server/src/main/java/password/pwm/config/value/FormValue.java

@@ -23,7 +23,6 @@ package password.pwm.config.value;
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.reflect.TypeToken;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingSyntax;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmOperationalException;

+ 0 - 1
server/src/main/java/password/pwm/config/value/LocalizedStringArrayValue.java

@@ -22,7 +22,6 @@ package password.pwm.config.value;
 
 
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.reflect.TypeToken;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.util.i18n.LocaleHelper;
 import password.pwm.util.i18n.LocaleHelper;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.JsonUtil;

+ 0 - 1
server/src/main/java/password/pwm/config/value/LocalizedStringValue.java

@@ -22,7 +22,6 @@ package password.pwm.config.value;
 
 
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.reflect.TypeToken;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.util.i18n.LocaleHelper;
 import password.pwm.util.i18n.LocaleHelper;

+ 0 - 1
server/src/main/java/password/pwm/config/value/NamedSecretValue.java

@@ -23,7 +23,6 @@ package password.pwm.config.value;
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.reflect.TypeToken;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.value.data.NamedSecretData;
 import password.pwm.config.value.data.NamedSecretData;

+ 0 - 1
server/src/main/java/password/pwm/config/value/NumericArrayValue.java

@@ -21,7 +21,6 @@
 package password.pwm.config.value;
 package password.pwm.config.value;
 
 
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.JsonUtil;

+ 0 - 1
server/src/main/java/password/pwm/config/value/NumericValue.java

@@ -22,7 +22,6 @@ package password.pwm.config.value;
 
 
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingProperty;
 import password.pwm.config.PwmSettingProperty;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.JsonUtil;

+ 0 - 1
server/src/main/java/password/pwm/config/value/OptionListValue.java

@@ -22,7 +22,6 @@ package password.pwm.config.value;
 
 
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.reflect.TypeToken;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.JsonUtil;

+ 0 - 1
server/src/main/java/password/pwm/config/value/PasswordValue.java

@@ -23,7 +23,6 @@ package password.pwm.config.value;
 
 
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;

+ 2 - 3
server/src/main/java/password/pwm/config/value/PrivateKeyValue.java

@@ -22,7 +22,6 @@ package password.pwm.config.value;
 
 
 import password.pwm.bean.PrivateKeyCertificate;
 import password.pwm.bean.PrivateKeyCertificate;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.JsonUtil;
@@ -120,7 +119,7 @@ public class PrivateKeyValue extends AbstractValue
 
 
             public X509CertificateValue fromJson( final String input )
             public X509CertificateValue fromJson( final String input )
             {
             {
-                return new X509CertificateValue( new X509Certificate[ 0 ] );
+                return new X509CertificateValue( Collections.emptyList() );
             }
             }
         };
         };
     }
     }
@@ -171,7 +170,7 @@ public class PrivateKeyValue extends AbstractValue
                 }
                 }
                 {
                 {
                     final XmlElement keyElement = XmlFactory.getFactory().newElement( ELEMENT_NAME_KEY );
                     final XmlElement keyElement = XmlFactory.getFactory().newElement( ELEMENT_NAME_KEY );
-                    final String b64EncodedKey = StringUtil.base64Encode( privateKeyCertificate.getKey().getEncoded() );
+                    final String b64EncodedKey = privateKeyCertificate.getPrivateKey();
                     final String encryptedKey = StoredValueEncoder.encode(
                     final String encryptedKey = StoredValueEncoder.encode(
                             b64EncodedKey,
                             b64EncodedKey,
                             xmlOutputProcessData.getStoredValueEncoderMode(),
                             xmlOutputProcessData.getStoredValueEncoderMode(),

+ 0 - 1
server/src/main/java/password/pwm/config/value/RemoteWebServiceValue.java

@@ -23,7 +23,6 @@ package password.pwm.config.value;
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.reflect.TypeToken;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.value.data.RemoteWebServiceConfiguration;
 import password.pwm.config.value.data.RemoteWebServiceConfiguration;

+ 2 - 1
server/src/main/java/password/pwm/config/StoredValue.java → server/src/main/java/password/pwm/config/value/StoredValue.java

@@ -18,8 +18,9 @@
  * limitations under the License.
  * limitations under the License.
  */
  */
 
 
-package password.pwm.config;
+package password.pwm.config.value;
 
 
+import password.pwm.config.PwmSetting;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.error.PwmException;
 import password.pwm.error.PwmException;
 import password.pwm.util.java.XmlElement;
 import password.pwm.util.java.XmlElement;

+ 0 - 1
server/src/main/java/password/pwm/config/value/StringArrayValue.java

@@ -21,7 +21,6 @@
 package password.pwm.config.value;
 package password.pwm.config.value;
 
 
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.JsonUtil;

+ 0 - 1
server/src/main/java/password/pwm/config/value/StringValue.java

@@ -22,7 +22,6 @@ package password.pwm.config.value;
 
 
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingFlag;
 import password.pwm.config.PwmSettingFlag;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.config.value.data.FormConfiguration;

+ 0 - 1
server/src/main/java/password/pwm/config/value/UserPermissionValue.java

@@ -23,7 +23,6 @@ package password.pwm.config.value;
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.reflect.TypeToken;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.value.data.UserPermission;
 import password.pwm.config.value.data.UserPermission;

+ 0 - 1
server/src/main/java/password/pwm/config/value/ValueFactory.java

@@ -21,7 +21,6 @@
 package password.pwm.config.value;
 package password.pwm.config.value;
 
 
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmOperationalException;

+ 349 - 0
server/src/main/java/password/pwm/config/value/ValueTypeConverter.java

@@ -0,0 +1,349 @@
+/*
+ * Password Management Servlets (PWM)
+ * http://www.pwm-project.org
+ *
+ * Copyright (c) 2006-2009 Novell, Inc.
+ * Copyright (c) 2009-2020 The PWM Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package password.pwm.config.value;
+
+import password.pwm.config.PwmSetting;
+import password.pwm.config.PwmSettingSyntax;
+import password.pwm.config.value.data.ActionConfiguration;
+import password.pwm.config.value.data.FormConfiguration;
+import password.pwm.config.value.data.NamedSecretData;
+import password.pwm.config.value.data.RemoteWebServiceConfiguration;
+import password.pwm.config.value.data.UserPermission;
+import password.pwm.util.PasswordData;
+import password.pwm.util.i18n.LocaleHelper;
+import password.pwm.util.logging.PwmLogger;
+
+import java.lang.reflect.InvocationTargetException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+public final class ValueTypeConverter
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass(  ValueTypeConverter.class );
+
+    private ValueTypeConverter()
+    {
+    }
+
+    public static long valueToLong( final StoredValue value )
+    {
+        if ( !( value instanceof NumericValue ) )
+        {
+            throw new IllegalArgumentException( "setting value is not readable as number" );
+        }
+        return ( long ) value.toNativeObject();
+    }
+
+    public static List<Long> valueToLongArray( final StoredValue value )
+    {
+        if ( !( value instanceof NumericArrayValue ) )
+        {
+            throw new IllegalArgumentException( "setting value is not readable as number array" );
+        }
+        return ( List<Long> ) value.toNativeObject();
+    }
+
+    public static String valueToString( final StoredValue value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        if ( ( !( value instanceof StringValue ) ) && ( !( value instanceof BooleanValue ) ) )
+        {
+            throw new IllegalArgumentException( "setting value is not readable as string" );
+        }
+        final Object nativeObject = value.toNativeObject();
+        if ( nativeObject == null )
+        {
+            return null;
+        }
+        return nativeObject.toString();
+    }
+
+    public static PasswordData valueToPassword( final StoredValue value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        if ( ( !( value instanceof PasswordValue ) ) )
+        {
+            throw new IllegalArgumentException( "setting value is not readable as password" );
+        }
+        final Object nativeObject = value.toNativeObject();
+        if ( nativeObject == null )
+        {
+            return null;
+        }
+        return ( PasswordData ) nativeObject;
+    }
+
+    public static Map<String, NamedSecretData> valueToNamedPassword( final StoredValue value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        if ( ( !( value instanceof NamedSecretValue ) ) )
+        {
+            throw new IllegalArgumentException( "setting value is not readable as named password" );
+        }
+        final Object nativeObject = value.toNativeObject();
+        if ( nativeObject == null )
+        {
+            return null;
+        }
+        return ( Map<String, NamedSecretData> ) nativeObject;
+    }
+
+    public static List<RemoteWebServiceConfiguration> valueToRemoteWebServiceConfiguration( final StoredValue value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        if ( ( !( value instanceof RemoteWebServiceValue ) ) )
+        {
+            throw new IllegalArgumentException( "setting value is not readable as named password" );
+        }
+        final Object nativeObject = value.toNativeObject();
+        if ( nativeObject == null )
+        {
+            return null;
+        }
+        return ( List<RemoteWebServiceConfiguration> ) nativeObject;
+    }
+
+    public static List<ActionConfiguration> valueToAction( final PwmSetting setting, final StoredValue storedValue )
+    {
+        if ( PwmSettingSyntax.ACTION != setting.getSyntax() )
+        {
+            throw new IllegalArgumentException( "may not read ACTION value for setting: " + setting.toString() );
+        }
+
+        return ( List<ActionConfiguration> ) storedValue.toNativeObject();
+    }
+
+    public static List<X509Certificate> valueToX509Certificates( final PwmSetting setting, final StoredValue storedValue  )
+    {
+        if ( PwmSettingSyntax.X509CERT != setting.getSyntax() )
+        {
+            throw new IllegalArgumentException( "may not read X509CERT value for setting: " + setting.toString() );
+        }
+
+        return ( (X509CertificateValue) storedValue ).asX509Certificates();
+    }
+
+    public static List<FormConfiguration> valueToForm( final StoredValue value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+
+        if ( value instanceof CustomLinkValue )
+        {
+            return ( List<FormConfiguration> ) value.toNativeObject();
+        }
+
+        if ( ( !( value instanceof FormValue ) ) )
+        {
+            throw new IllegalArgumentException( "setting value is not readable as form" );
+        }
+
+        return ( List<FormConfiguration> ) value.toNativeObject();
+    }
+
+    public static List<String> valueToStringArray( final StoredValue value )
+    {
+        if ( !( value instanceof StringArrayValue ) )
+        {
+            throw new IllegalArgumentException( "setting value is not readable as string array" );
+        }
+
+        final List<String> results = new ArrayList<>( ( List<String> ) value.toNativeObject() );
+        for ( final Iterator iter = results.iterator(); iter.hasNext(); )
+        {
+            final Object loopString = iter.next();
+            if ( loopString == null || loopString.toString().length() < 1 )
+            {
+                iter.remove();
+            }
+        }
+        return results;
+    }
+
+    public static List<UserPermission> valueToUserPermissions( final StoredValue value )
+    {
+        if ( value == null )
+        {
+            return Collections.emptyList();
+        }
+
+        if ( !( value instanceof UserPermissionValue ) )
+        {
+            throw new IllegalArgumentException( "setting value is not readable as string array" );
+        }
+
+        final List<UserPermission> results = new ArrayList<>( ( List<UserPermission> ) value.toNativeObject() );
+        for ( final Iterator iter = results.iterator(); iter.hasNext(); )
+        {
+            final Object loopString = iter.next();
+            if ( loopString == null || loopString.toString().length() < 1 )
+            {
+                iter.remove();
+            }
+        }
+        return results;
+    }
+
+    public static boolean valueToBoolean( final StoredValue value )
+    {
+        if ( !( value instanceof BooleanValue ) )
+        {
+            throw new IllegalArgumentException( "may not read BOOLEAN value for setting" );
+        }
+
+        return ( Boolean ) value.toNativeObject();
+    }
+
+    public static String valueToLocalizedString( final StoredValue value, final Locale locale )
+    {
+        if ( !( value instanceof LocalizedStringValue ) )
+        {
+            throw new IllegalArgumentException( "may not read LOCALIZED_STRING or LOCALIZED_TEXT_AREA values for setting" );
+        }
+
+        final Map<String, String> availableValues = ( Map<String, String> ) value.toNativeObject();
+        final Map<Locale, String> availableLocaleMap = new LinkedHashMap<>();
+        for ( final Map.Entry<String, String> entry : availableValues.entrySet() )
+        {
+            final String localeStr = entry.getKey();
+            availableLocaleMap.put( LocaleHelper.parseLocaleString( localeStr ), entry.getValue() );
+        }
+        final Locale matchedLocale = LocaleHelper.localeResolver( locale, availableLocaleMap.keySet() );
+
+        return availableLocaleMap.get( matchedLocale );
+    }
+
+    public static List<String> valueToLocalizedStringArray( final StoredValue value, final Locale locale )
+    {
+        if ( !( value instanceof LocalizedStringArrayValue ) )
+        {
+            throw new IllegalArgumentException( "may not read LOCALIZED_STRING_ARRAY value" );
+        }
+        final Map<String, List<String>> storedValues = ( Map<String, List<String>> ) value.toNativeObject();
+        final Map<Locale, List<String>> availableLocaleMap = new LinkedHashMap<>();
+        for ( final Map.Entry<String, List<String>> entry : storedValues.entrySet() )
+        {
+            final String localeStr = entry.getKey();
+            availableLocaleMap.put( LocaleHelper.parseLocaleString( localeStr ), entry.getValue() );
+        }
+        final Locale matchedLocale = LocaleHelper.localeResolver( locale, availableLocaleMap.keySet() );
+
+        return availableLocaleMap.get( matchedLocale );
+    }
+
+    public static <E extends Enum<E>> E valueToEnum( final PwmSetting setting, final StoredValue value, final Class<E> enumClass )
+    {
+        if ( PwmSettingSyntax.SELECT != setting.getSyntax() )
+        {
+            throw new IllegalArgumentException( "may not read SELECT enum value for setting: " + setting.toString() );
+        }
+
+        if ( value != null )
+        {
+            final String strValue = ( String ) value.toNativeObject();
+            try
+            {
+                return ( E ) enumClass.getMethod( "valueOf", String.class ).invoke( null, strValue );
+            }
+            catch ( final InvocationTargetException e1 )
+            {
+                if ( e1.getCause() instanceof IllegalArgumentException )
+                {
+                    LOGGER.error( () -> "illegal setting value for option '" + strValue + "' for setting key '" + setting.getKey() + "' is not recognized, will use default" );
+                }
+            }
+            catch ( final Exception e1 )
+            {
+                LOGGER.error( () -> "unexpected error", e1 );
+            }
+        }
+
+        return null;
+    }
+
+    public static Map<FileValue.FileInformation, FileValue.FileContent> valueToFile( final PwmSetting setting, final StoredValue storedValue )
+    {
+        if ( PwmSettingSyntax.FILE != setting.getSyntax() )
+        {
+            throw new IllegalArgumentException( "may not read file value for setting: " + setting.toString() );
+        }
+
+        if ( !( storedValue instanceof FileValue ) )
+        {
+            throw new IllegalArgumentException( "unexpected value type '" + storedValue.getClass().getName() + " ' is not expected file value" );
+        }
+
+        return ( Map ) storedValue.toNativeObject();
+    }
+
+    public static <E extends Enum<E>> Set<E> valueToOptionList( final PwmSetting setting, final StoredValue value, final Class<E> enumClass )
+    {
+        if ( PwmSettingSyntax.OPTIONLIST != setting.getSyntax() )
+        {
+            throw new IllegalArgumentException( "may not read optionlist value for setting: " + setting.toString() );
+        }
+
+        final Set<E> returnSet = new LinkedHashSet<>();
+        final Set<String> strValues = ( Set<String> ) value.toNativeObject();
+        for ( final String strValue : strValues )
+        {
+            try
+            {
+                returnSet.add( ( E ) enumClass.getMethod( "valueOf", String.class ).invoke( null, strValue ) );
+            }
+            catch ( final InvocationTargetException e1 )
+            {
+                if ( e1.getCause() instanceof IllegalArgumentException )
+                {
+                    LOGGER.error( () -> "illegal setting value for option '" + strValue + "' is not recognized, will use default" );
+                }
+            }
+            catch ( final Exception e1 )
+            {
+                LOGGER.error( () -> "unexpected error", e1 );
+            }
+        }
+
+        return Collections.unmodifiableSet( returnSet );
+    }
+}

+ 0 - 1
server/src/main/java/password/pwm/config/value/VerificationMethodValue.java

@@ -22,7 +22,6 @@ package password.pwm.config.value;
 
 
 import lombok.Value;
 import lombok.Value;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.option.IdentityVerificationMethod;
 import password.pwm.config.option.IdentityVerificationMethod;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;

+ 39 - 43
server/src/main/java/password/pwm/config/value/X509CertificateValue.java

@@ -22,11 +22,11 @@ package password.pwm.config.value;
 
 
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JavaHelper;
+import password.pwm.util.java.LazySupplier;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.XmlElement;
 import password.pwm.util.java.XmlElement;
 import password.pwm.util.java.XmlFactory;
 import password.pwm.util.java.XmlFactory;
@@ -41,17 +41,24 @@ import java.io.Serializable;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.List;
 import java.util.List;
 import java.util.Locale;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Map;
+import java.util.function.Supplier;
 
 
 public class X509CertificateValue extends AbstractValue implements StoredValue
 public class X509CertificateValue extends AbstractValue implements StoredValue
 {
 {
+    private static final long serialVersionUID = 1L;
+
     private static final PwmLogger LOGGER = PwmLogger.forClass( X509CertificateValue.class );
     private static final PwmLogger LOGGER = PwmLogger.forClass( X509CertificateValue.class );
-    private final X509Certificate[] certificates;
+
+    // native object;
+    private final List<String> b64certificates;
+
+    // non-serializable representation of native object
+    private final transient Supplier<List<X509Certificate>> certs;
 
 
     public static StoredValueFactory factory( )
     public static StoredValueFactory factory( )
     {
     {
@@ -59,71 +66,54 @@ public class X509CertificateValue extends AbstractValue implements StoredValue
         {
         {
             public X509CertificateValue fromXmlElement( final PwmSetting pwmSetting, final XmlElement settingElement, final PwmSecurityKey key )
             public X509CertificateValue fromXmlElement( final PwmSetting pwmSetting, final XmlElement settingElement, final PwmSecurityKey key )
             {
             {
-                final List<X509Certificate> certificates = new ArrayList<>();
+                final List<String> b64certificates = new ArrayList<>();
                 final List<XmlElement> valueElements = settingElement.getChildren( StoredConfigXmlSerializer.StoredConfigXmlConstants.XML_ELEMENT_VALUE );
                 final List<XmlElement> valueElements = settingElement.getChildren( StoredConfigXmlSerializer.StoredConfigXmlConstants.XML_ELEMENT_VALUE );
                 for ( final XmlElement loopValueElement : valueElements )
                 for ( final XmlElement loopValueElement : valueElements )
                 {
                 {
                     final String b64encodedStr = loopValueElement.getText();
                     final String b64encodedStr = loopValueElement.getText();
-                    try
-                    {
-                        certificates.add( X509Utils.certificateFromBase64( b64encodedStr ) );
-                    }
-                    catch ( final Exception e )
-                    {
-                        LOGGER.error( () -> "error decoding certificate: " + e.getMessage() );
-                    }
+
+                    b64certificates.add( b64encodedStr );
                 }
                 }
-                return new X509CertificateValue( certificates.toArray( new X509Certificate[ certificates.size() ] ) );
+                return new X509CertificateValue( Collections.unmodifiableList( b64certificates ) );
             }
             }
 
 
             public X509CertificateValue fromJson( final String input )
             public X509CertificateValue fromJson( final String input )
             {
             {
-                return new X509CertificateValue( new X509Certificate[ 0 ] );
+                return new X509CertificateValue( Collections.emptyList() );
             }
             }
         };
         };
     }
     }
 
 
-    public X509CertificateValue( final X509Certificate[] certificates )
-    {
-        if ( certificates == null )
-        {
-            throw new NullPointerException( "certificates cannot be null" );
-        }
-        this.certificates = Arrays.copyOf( certificates, certificates.length );
-    }
-
     public boolean hasCertificates( )
     public boolean hasCertificates( )
     {
     {
-        return certificates != null && certificates.length > 0;
+        return !JavaHelper.isEmpty( b64certificates );
     }
     }
 
 
-    public X509CertificateValue( final Collection<X509Certificate> certificates )
+    public X509CertificateValue( final List<String> b64certificates )
     {
     {
-        if ( certificates == null )
+        if ( b64certificates == null )
         {
         {
             throw new NullPointerException( "certificates cannot be null" );
             throw new NullPointerException( "certificates cannot be null" );
         }
         }
-        this.certificates = certificates.toArray( new X509Certificate[0] );
+        this.b64certificates = Collections.unmodifiableList( b64certificates );
+        this.certs = new LazySupplier<>( () -> X509Utils.certificatesFromBase64s( b64certificates ) );
     }
     }
 
 
+    public static X509CertificateValue fromX509( final Collection<X509Certificate> x509Certificate )
+    {
+        return new X509CertificateValue( X509Utils.certificatesToBase64s( x509Certificate ) );
+    }
 
 
     @Override
     @Override
     public List<XmlElement> toXmlValues( final String valueElementName, final XmlOutputProcessData xmlOutputProcessData )
     public List<XmlElement> toXmlValues( final String valueElementName, final XmlOutputProcessData xmlOutputProcessData )
     {
     {
         final List<XmlElement> returnList = new ArrayList<>();
         final List<XmlElement> returnList = new ArrayList<>();
-        for ( final X509Certificate value : certificates )
+        for ( final String b64value : b64certificates )
         {
         {
             final XmlElement valueElement = XmlFactory.getFactory().newElement( valueElementName );
             final XmlElement valueElement = XmlFactory.getFactory().newElement( valueElementName );
-            try
-            {
-                final String b64Value = X509Utils.certificateToBase64( value );
-                final String splitValue = StringUtil.insertRepeatedLineBreaks( b64Value, PwmConstants.XML_OUTPUT_LINE_WRAP_LENGTH );
-                valueElement.addText( splitValue );
-            }
-            catch ( final CertificateEncodingException e )
-            {
-                LOGGER.error( () -> "error encoding certificate: " + e.getMessage() );
-            }
+            final String splitValue = StringUtil.insertRepeatedLineBreaks( b64value, PwmConstants.XML_OUTPUT_LINE_WRAP_LENGTH );
+            valueElement.addText( splitValue );
+
             returnList.add( valueElement );
             returnList.add( valueElement );
         }
         }
         return returnList;
         return returnList;
@@ -132,7 +122,12 @@ public class X509CertificateValue extends AbstractValue implements StoredValue
     @Override
     @Override
     public Object toNativeObject( )
     public Object toNativeObject( )
     {
     {
-        return certificates == null ? null : Arrays.copyOf( certificates, certificates.length );
+        return b64certificates;
+    }
+
+    public List<X509Certificate> asX509Certificates()
+    {
+        return certs.get();
     }
     }
 
 
     @Override
     @Override
@@ -145,7 +140,7 @@ public class X509CertificateValue extends AbstractValue implements StoredValue
     {
     {
         final StringBuilder sb = new StringBuilder();
         final StringBuilder sb = new StringBuilder();
         final int counter = 0;
         final int counter = 0;
-        for ( final X509Certificate cert : certificates )
+        for ( final X509Certificate cert : certs.get() )
         {
         {
             sb.append( "Certificate " ).append( counter ).append( "\n" );
             sb.append( "Certificate " ).append( counter ).append( "\n" );
             sb.append( " Subject: " ).append( cert.getSubjectDN().toString() ).append( "\n" );
             sb.append( " Subject: " ).append( cert.getSubjectDN().toString() ).append( "\n" );
@@ -176,22 +171,23 @@ public class X509CertificateValue extends AbstractValue implements StoredValue
 
 
     public List<Map<String, String>> toInfoMap( final boolean includeDetail )
     public List<Map<String, String>> toInfoMap( final boolean includeDetail )
     {
     {
-        if ( this.certificates == null )
+        if ( this.certs.get() == null )
         {
         {
             return Collections.emptyList();
             return Collections.emptyList();
         }
         }
 
 
         final List<Map<String, String>> list = new ArrayList<>();
         final List<Map<String, String>> list = new ArrayList<>();
-        for ( final X509Certificate cert : this.certificates )
+        for ( final X509Certificate cert : certs.get() )
         {
         {
             final X509Utils.DebugInfoFlag[] flags = includeDetail
             final X509Utils.DebugInfoFlag[] flags = includeDetail
                     ? new X509Utils.DebugInfoFlag[]
                     ? new X509Utils.DebugInfoFlag[]
                     {
                     {
                             X509Utils.DebugInfoFlag.IncludeCertificateDetail,
                             X509Utils.DebugInfoFlag.IncludeCertificateDetail,
-                    }
+                            }
                     : null;
                     : null;
             list.add( X509Utils.makeDebugInfoMap( cert, flags ) );
             list.add( X509Utils.makeDebugInfoMap( cert, flags ) );
         }
         }
         return Collections.unmodifiableList( list );
         return Collections.unmodifiableList( list );
     }
     }
+
 }
 }

+ 1 - 1
server/src/main/java/password/pwm/health/ConfigurationChecker.java

@@ -27,7 +27,7 @@ import password.pwm.PwmConstants;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingSyntax;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.option.DataStorageMethod;
 import password.pwm.config.option.DataStorageMethod;
 import password.pwm.config.option.MessageSendMethod;
 import password.pwm.config.option.MessageSendMethod;
 import password.pwm.config.profile.ActivateUserProfile;
 import password.pwm.config.profile.ActivateUserProfile;

+ 2 - 2
server/src/main/java/password/pwm/http/ContextManager.java

@@ -28,7 +28,7 @@ import password.pwm.PwmEnvironment;
 import password.pwm.bean.SessionLabel;
 import password.pwm.bean.SessionLabel;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.profile.LdapProfile;
 import password.pwm.config.profile.LdapProfile;
 import password.pwm.config.stored.ConfigurationProperty;
 import password.pwm.config.stored.ConfigurationProperty;
 import password.pwm.config.stored.ConfigurationReader;
 import password.pwm.config.stored.ConfigurationReader;
@@ -771,7 +771,7 @@ public class ContextManager implements Serializable
                         {
                         {
                             LOGGER.trace( SESSION_LABEL, () -> "imported cert: " + X509Utils.makeDebugText( cert ) );
                             LOGGER.trace( SESSION_LABEL, () -> "imported cert: " + X509Utils.makeDebugText( cert ) );
                         }
                         }
-                        final StoredValue storedValue = new X509CertificateValue( certs );
+                        final StoredValue storedValue = X509CertificateValue.fromX509( certs );
 
 
                         modifiedConfig.writeSetting( PwmSetting.LDAP_SERVER_CERTS, ldapProfile.getIdentifier(), storedValue, null );
                         modifiedConfig.writeSetting( PwmSetting.LDAP_SERVER_CERTS, ldapProfile.getIdentifier(), storedValue, null );
                     }
                     }

+ 1 - 1
server/src/main/java/password/pwm/http/servlet/configeditor/ConfigEditorServlet.java

@@ -36,7 +36,7 @@ import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingTemplate;
 import password.pwm.config.PwmSettingTemplate;
 import password.pwm.config.PwmSettingTemplateSet;
 import password.pwm.config.PwmSettingTemplateSet;
 import password.pwm.config.SettingUIFunction;
 import password.pwm.config.SettingUIFunction;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.profile.EmailServerProfile;
 import password.pwm.config.profile.EmailServerProfile;
 import password.pwm.config.profile.PwmPasswordPolicy;
 import password.pwm.config.profile.PwmPasswordPolicy;
 import password.pwm.config.stored.ConfigurationProperty;
 import password.pwm.config.stored.ConfigurationProperty;

+ 1 - 1
server/src/main/java/password/pwm/http/servlet/configeditor/NavTreeHelper.java

@@ -26,7 +26,7 @@ import password.pwm.PwmEnvironment;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingCategory;
 import password.pwm.config.PwmSettingCategory;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfigurationUtil;
 import password.pwm.config.stored.StoredConfigurationUtil;
 import password.pwm.i18n.Config;
 import password.pwm.i18n.Config;

+ 2 - 2
server/src/main/java/password/pwm/http/servlet/configguide/ConfigGuideForm.java

@@ -22,7 +22,7 @@ package password.pwm.http.servlet.configguide;
 
 
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingTemplate;
 import password.pwm.config.PwmSettingTemplate;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfigurationFactory;
 import password.pwm.config.stored.StoredConfigurationFactory;
 import password.pwm.config.stored.StoredConfigurationModifier;
 import password.pwm.config.stored.StoredConfigurationModifier;
@@ -132,7 +132,7 @@ public class ConfigGuideForm
 
 
         if ( configGuideBean.isUseConfiguredCerts() && !JavaHelper.isEmpty( configGuideBean.getLdapCertificates() ) )
         if ( configGuideBean.isUseConfiguredCerts() && !JavaHelper.isEmpty( configGuideBean.getLdapCertificates() ) )
         {
         {
-            final StoredValue newStoredValue = new X509CertificateValue( configGuideBean.getLdapCertificates() );
+            final StoredValue newStoredValue = X509CertificateValue.fromX509( configGuideBean.getLdapCertificates() );
             storedConfiguration.writeSetting( PwmSetting.LDAP_SERVER_CERTS, LDAP_PROFILE_NAME, newStoredValue, null );
             storedConfiguration.writeSetting( PwmSetting.LDAP_SERVER_CERTS, LDAP_PROFILE_NAME, newStoredValue, null );
         }
         }
 
 

+ 1 - 1
server/src/main/java/password/pwm/http/servlet/configguide/ConfigGuideServlet.java

@@ -29,7 +29,7 @@ import password.pwm.PwmConstants;
 import password.pwm.bean.UserIdentity;
 import password.pwm.bean.UserIdentity;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.function.UserMatchViewerFunction;
 import password.pwm.config.function.UserMatchViewerFunction;
 import password.pwm.config.profile.LdapProfile;
 import password.pwm.config.profile.LdapProfile;
 import password.pwm.config.stored.ConfigurationProperty;
 import password.pwm.config.stored.ConfigurationProperty;

+ 10 - 27
server/src/main/java/password/pwm/http/servlet/configmanager/ConfigManagerCertificatesServlet.java

@@ -20,16 +20,16 @@
 
 
 package password.pwm.http.servlet.configmanager;
 package password.pwm.http.servlet.configmanager;
 
 
-import com.novell.ldapchai.exception.ChaiUnavailableException;
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Value;
 import lombok.Value;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingSyntax;
 import password.pwm.config.PwmSettingSyntax;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.stored.StoredConfigItemKey;
 import password.pwm.config.stored.StoredConfigItemKey;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
+import password.pwm.config.value.ValueTypeConverter;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.http.HttpMethod;
 import password.pwm.http.HttpMethod;
@@ -49,7 +49,6 @@ import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.security.cert.X509Certificate;
 import java.time.Instant;
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.List;
 import java.util.List;
@@ -96,14 +95,14 @@ public class ConfigManagerCertificatesServlet extends AbstractPwmServlet
     }
     }
 
 
     protected void processAction( final PwmRequest pwmRequest )
     protected void processAction( final PwmRequest pwmRequest )
-            throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
+            throws ServletException, IOException, PwmUnrecoverableException
     {
     {
         ConfigManagerServlet.verifyConfigAccess( pwmRequest );
         ConfigManagerServlet.verifyConfigAccess( pwmRequest );
 
 
         final ConfigManagerCertificateAction action = readProcessAction( pwmRequest );
         final ConfigManagerCertificateAction action = readProcessAction( pwmRequest );
         final ArrayList<CertificateDebugDataItem> certificateDebugDataItems = new ArrayList<>( makeCertificateDebugData( pwmRequest.getConfig() ) );
         final ArrayList<CertificateDebugDataItem> certificateDebugDataItems = new ArrayList<>( makeCertificateDebugData( pwmRequest.getConfig() ) );
 
 
-        if ( action != null && action == ConfigManagerCertificateAction.certificateData )
+        if ( action == ConfigManagerCertificateAction.certificateData )
         {
         {
             final RestResultBean restResultBean = RestResultBean.withData( certificateDebugDataItems );
             final RestResultBean restResultBean = RestResultBean.withData( certificateDebugDataItems );
             pwmRequest.outputJsonResult( restResultBean );
             pwmRequest.outputJsonResult( restResultBean );
@@ -127,31 +126,14 @@ public class ConfigManagerCertificatesServlet extends AbstractPwmServlet
                 final PwmSetting pwmSetting = PwmSetting.forKey( ref.getRecordID() );
                 final PwmSetting pwmSetting = PwmSetting.forKey( ref.getRecordID() );
                 if ( pwmSetting.getSyntax() == PwmSettingSyntax.X509CERT )
                 if ( pwmSetting.getSyntax() == PwmSettingSyntax.X509CERT )
                 {
                 {
-                    final StoredValue storedValue;
-                    if ( pwmSetting.getCategory().hasProfiles() )
-                    {
-                        storedValue = storedConfiguration.readSetting( pwmSetting, ref.getProfileID() );
-                    }
-                    else
-                    {
-                        storedValue = storedConfiguration.readSetting( pwmSetting, null );
-                    }
-                    final X509Certificate[] arrayCerts = ( X509Certificate[] ) storedValue.toNativeObject();
-                    final List<X509Certificate> certificates = arrayCerts == null ? Collections.emptyList() : Arrays.asList( arrayCerts );
+                    final StoredValue storedValue = storedConfiguration.readSetting( pwmSetting, ref.getProfileID() );
+                    final List<X509Certificate> certificates = ValueTypeConverter.valueToX509Certificates( pwmSetting, storedValue );
                     certificateDebugDataItems.addAll( makeItems( pwmSetting, ref.getProfileID(), certificates ) );
                     certificateDebugDataItems.addAll( makeItems( pwmSetting, ref.getProfileID(), certificates ) );
                 }
                 }
                 else if ( pwmSetting.getSyntax() == PwmSettingSyntax.ACTION )
                 else if ( pwmSetting.getSyntax() == PwmSettingSyntax.ACTION )
                 {
                 {
-                    final StoredValue storedValue;
-                    if ( pwmSetting.getCategory().hasProfiles() )
-                    {
-                        storedValue = storedConfiguration.readSetting( pwmSetting, ref.getProfileID() );
-                    }
-                    else
-                    {
-                        storedValue = storedConfiguration.readSetting( pwmSetting, null );
-                    }
-                    final List<ActionConfiguration> actionConfigurations = ( List ) storedValue.toNativeObject();
+                    final StoredValue storedValue = storedConfiguration.readSetting( pwmSetting, ref.getProfileID() );
+                    final List<ActionConfiguration> actionConfigurations = ValueTypeConverter.valueToAction( pwmSetting, storedValue );
                     for ( final ActionConfiguration actionConfiguration : actionConfigurations )
                     for ( final ActionConfiguration actionConfiguration : actionConfigurations )
                     {
                     {
                         for ( final ActionConfiguration.WebAction webAction : actionConfiguration.getWebActions() )
                         for ( final ActionConfiguration.WebAction webAction : actionConfiguration.getWebActions() )
@@ -172,7 +154,8 @@ public class ConfigManagerCertificatesServlet extends AbstractPwmServlet
             final PwmSetting setting,
             final PwmSetting setting,
             final String profileId,
             final String profileId,
             final List<X509Certificate> certificates
             final List<X509Certificate> certificates
-    ) throws PwmUnrecoverableException
+    )
+            throws PwmUnrecoverableException
     {
     {
         if ( certificates == null )
         if ( certificates == null )
         {
         {

+ 1 - 1
server/src/main/java/password/pwm/http/servlet/configmanager/DebugItemGenerator.java

@@ -31,7 +31,7 @@ import password.pwm.PwmConstants;
 import password.pwm.bean.SessionLabel;
 import password.pwm.bean.SessionLabel;
 import password.pwm.bean.UserIdentity;
 import password.pwm.bean.UserIdentity;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.stored.StoredConfigItemKey;
 import password.pwm.config.stored.StoredConfigItemKey;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfigurationFactory;
 import password.pwm.config.stored.StoredConfigurationFactory;

+ 1 - 0
server/src/main/java/password/pwm/svc/PwmServiceManager.java

@@ -129,6 +129,7 @@ public class PwmServiceManager
             }
             }
             final String errorMsgFinal = errorMsg;
             final String errorMsgFinal = errorMsg;
             LOGGER.fatal( () -> errorMsgFinal );
             LOGGER.fatal( () -> errorMsgFinal );
+            e.printStackTrace();
             throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_STARTUP_ERROR, errorMsg ) );
             throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_STARTUP_ERROR, errorMsg ) );
         }
         }
         return newServiceInstance;
         return newServiceInstance;

+ 2 - 2
server/src/main/java/password/pwm/svc/sessiontrack/SessionTrackService.java

@@ -47,7 +47,7 @@ import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.EnumMap;
 import java.util.HashSet;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.List;
@@ -139,7 +139,7 @@ public class SessionTrackService implements PwmService
                     LOGGER.error( () -> "error during session size calculation: " + e.getMessage() );
                     LOGGER.error( () -> "error during session size calculation: " + e.getMessage() );
                 }
                 }
             }
             }
-            final Map<DebugKey, String> returnMap = new HashMap<>();
+            final Map<DebugKey, String> returnMap = new EnumMap<>( DebugKey.class );
             returnMap.put( DebugKey.HttpSessionCount, String.valueOf( sessionCounter ) );
             returnMap.put( DebugKey.HttpSessionCount, String.valueOf( sessionCounter ) );
             returnMap.put( DebugKey.HttpSessionTotalSize, String.valueOf( sizeTotal ) );
             returnMap.put( DebugKey.HttpSessionTotalSize, String.valueOf( sizeTotal ) );
             returnMap.put( DebugKey.HttpSessionAvgSize,
             returnMap.put( DebugKey.HttpSessionAvgSize,

+ 16 - 15
server/src/main/java/password/pwm/util/LDAPPermissionCalculator.java

@@ -32,6 +32,7 @@ import password.pwm.config.option.DataStorageMethod;
 import password.pwm.config.profile.LdapProfile;
 import password.pwm.config.profile.LdapProfile;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfigurationUtil;
 import password.pwm.config.stored.StoredConfigurationUtil;
+import password.pwm.config.value.ValueTypeConverter;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.config.value.data.UserPermission;
 import password.pwm.config.value.data.UserPermission;
@@ -137,7 +138,7 @@ public class LDAPPermissionCalculator implements Serializable
             {
             {
                 case STRING:
                 case STRING:
                 {
                 {
-                    final String attrName = ( String ) storedConfiguration.readSetting( pwmSetting, profile ).toNativeObject();
+                    final String attrName = ValueTypeConverter.valueToString( storedConfiguration.readSetting( pwmSetting, profile ) );
                     if ( attrName != null && !attrName.trim().isEmpty() )
                     if ( attrName != null && !attrName.trim().isEmpty() )
                     {
                     {
                         permissionRecords.add( new PermissionRecord( attrName, pwmSetting, profile, permissionInfo.getAccess(), permissionInfo.getActor() ) );
                         permissionRecords.add( new PermissionRecord( attrName, pwmSetting, profile, permissionInfo.getAccess(), permissionInfo.getActor() ) );
@@ -147,7 +148,7 @@ public class LDAPPermissionCalculator implements Serializable
 
 
                 case FORM:
                 case FORM:
                 {
                 {
-                    final List<FormConfiguration> formItems = ( List<FormConfiguration> ) storedConfiguration.readSetting( pwmSetting, profile ).toNativeObject();
+                    final List<FormConfiguration> formItems = ValueTypeConverter.valueToForm( storedConfiguration.readSetting( pwmSetting, profile ) );
                     if ( formItems != null )
                     if ( formItems != null )
                     {
                     {
                         for ( final FormConfiguration formConfiguration : formItems )
                         for ( final FormConfiguration formConfiguration : formItems )
@@ -164,7 +165,7 @@ public class LDAPPermissionCalculator implements Serializable
 
 
                 case ACTION:
                 case ACTION:
                 {
                 {
-                    final List<ActionConfiguration> actionItems = ( List<ActionConfiguration> ) storedConfiguration.readSetting( pwmSetting, profile ).toNativeObject();
+                    final List<ActionConfiguration> actionItems = ValueTypeConverter.valueToAction( pwmSetting, storedConfiguration.readSetting( pwmSetting, profile ) );
                     if ( actionItems != null )
                     if ( actionItems != null )
                     {
                     {
                         for ( final ActionConfiguration actionConfiguration : actionItems )
                         for ( final ActionConfiguration actionConfiguration : actionItems )
@@ -184,7 +185,7 @@ public class LDAPPermissionCalculator implements Serializable
 
 
                 case STRING_ARRAY:
                 case STRING_ARRAY:
                 {
                 {
-                    final List<String> strings = ( List<String> ) storedConfiguration.readSetting( pwmSetting, profile ).toNativeObject();
+                    final List<String> strings = ValueTypeConverter.valueToStringArray( storedConfiguration.readSetting( pwmSetting, profile ) );
                     for ( final String attrName : strings )
                     for ( final String attrName : strings )
                     {
                     {
                         if ( attrName != null && !attrName.trim().isEmpty() )
                         if ( attrName != null && !attrName.trim().isEmpty() )
@@ -197,7 +198,7 @@ public class LDAPPermissionCalculator implements Serializable
 
 
                 case USER_PERMISSION:
                 case USER_PERMISSION:
                 {
                 {
-                    final List<UserPermission> userPermissions = ( List<UserPermission> ) storedConfiguration.readSetting( pwmSetting, profile ).toNativeObject();
+                    final List<UserPermission> userPermissions = ValueTypeConverter.valueToUserPermissions ( storedConfiguration.readSetting( pwmSetting, profile ) );
                     if ( configuration.getLdapProfiles() != null && !configuration.getLdapProfiles().isEmpty() )
                     if ( configuration.getLdapProfiles() != null && !configuration.getLdapProfiles().isEmpty() )
                     {
                     {
                         for ( final LdapProfile ldapProfile : configuration.getLdapProfiles().values() )
                         for ( final LdapProfile ldapProfile : configuration.getLdapProfiles().values() )
@@ -243,12 +244,12 @@ public class LDAPPermissionCalculator implements Serializable
         {
         {
             case PEOPLE_SEARCH:
             case PEOPLE_SEARCH:
             {
             {
-                if ( !( Boolean ) storedConfiguration.readSetting( PwmSetting.PEOPLE_SEARCH_ENABLE, null ).toNativeObject() )
+                if ( !ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.PEOPLE_SEARCH_ENABLE, null ) ) )
                 {
                 {
                     return Collections.emptyList();
                     return Collections.emptyList();
                 }
                 }
-                final boolean proxyOverride = ( Boolean ) storedConfiguration.readSetting( PwmSetting.PEOPLE_SEARCH_USE_PROXY, profile ).toNativeObject();
-                final boolean publicOverride = ( Boolean ) storedConfiguration.readSetting( PwmSetting.PEOPLE_SEARCH_ENABLE_PUBLIC, profile ).toNativeObject();
+                final boolean proxyOverride = ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.PEOPLE_SEARCH_USE_PROXY, profile ) );
+                final boolean publicOverride = ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.PEOPLE_SEARCH_ENABLE_PUBLIC, profile ) );
 
 
                 if ( proxyOverride || publicOverride )
                 if ( proxyOverride || publicOverride )
                 {
                 {
@@ -270,7 +271,7 @@ public class LDAPPermissionCalculator implements Serializable
 
 
             case GUEST:
             case GUEST:
             {
             {
-                if ( !( Boolean ) storedConfiguration.readSetting( PwmSetting.GUEST_ENABLE, null ).toNativeObject() )
+                if ( !ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.GUEST_ENABLE, null ) ) )
                 {
                 {
                     return Collections.emptyList();
                     return Collections.emptyList();
                 }
                 }
@@ -281,7 +282,7 @@ public class LDAPPermissionCalculator implements Serializable
             case UPDATE_PROFILE:
             case UPDATE_PROFILE:
             case UPDATE_SETTINGS:
             case UPDATE_SETTINGS:
             {
             {
-                if ( !( Boolean ) storedConfiguration.readSetting( PwmSetting.UPDATE_PROFILE_ENABLE, null ).toNativeObject() )
+                if ( !ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.UPDATE_PROFILE_ENABLE, null ) ) )
                 {
                 {
                     return Collections.emptyList();
                     return Collections.emptyList();
                 }
                 }
@@ -290,7 +291,7 @@ public class LDAPPermissionCalculator implements Serializable
 
 
             case FORGOTTEN_USERNAME:
             case FORGOTTEN_USERNAME:
             {
             {
-                if ( !( Boolean ) storedConfiguration.readSetting( PwmSetting.FORGOTTEN_USERNAME_ENABLE, null ).toNativeObject() )
+                if ( !ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.FORGOTTEN_USERNAME_ENABLE, null ) ) )
                 {
                 {
                     return Collections.emptyList();
                     return Collections.emptyList();
                 }
                 }
@@ -301,7 +302,7 @@ public class LDAPPermissionCalculator implements Serializable
             case NEWUSER_PROFILE:
             case NEWUSER_PROFILE:
             case NEWUSER_SETTINGS:
             case NEWUSER_SETTINGS:
             {
             {
-                if ( !( Boolean ) storedConfiguration.readSetting( PwmSetting.NEWUSER_ENABLE, null ).toNativeObject() )
+                if ( !ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.NEWUSER_ENABLE, null ) ) )
                 {
                 {
                     return Collections.emptyList();
                     return Collections.emptyList();
                 }
                 }
@@ -310,7 +311,7 @@ public class LDAPPermissionCalculator implements Serializable
 
 
             case ACTIVATION:
             case ACTIVATION:
             {
             {
-                if ( !( Boolean ) storedConfiguration.readSetting( PwmSetting.ACTIVATE_USER_ENABLE, null ).toNativeObject() )
+                if ( !ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.ACTIVATE_USER_ENABLE, null ) ) )
                 {
                 {
                     return Collections.emptyList();
                     return Collections.emptyList();
                 }
                 }
@@ -319,11 +320,11 @@ public class LDAPPermissionCalculator implements Serializable
 
 
             case HELPDESK_PROFILE:
             case HELPDESK_PROFILE:
             {
             {
-                if ( !( Boolean ) storedConfiguration.readSetting( PwmSetting.HELPDESK_ENABLE, null ).toNativeObject() )
+                if ( !ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.HELPDESK_ENABLE, null ) ) )
                 {
                 {
                     return Collections.emptyList();
                     return Collections.emptyList();
                 }
                 }
-                if ( ( Boolean ) storedConfiguration.readSetting( PwmSetting.HELPDESK_USE_PROXY, profile ).toNativeObject() )
+                if ( ValueTypeConverter.valueToBoolean( storedConfiguration.readSetting( PwmSetting.HELPDESK_USE_PROXY, profile ) ) )
                 {
                 {
                     final Collection<LDAPPermissionInfo> configuredRecords = pwmSetting.getLDAPPermissionInfo();
                     final Collection<LDAPPermissionInfo> configuredRecords = pwmSetting.getLDAPPermissionInfo();
                     final Collection<LDAPPermissionInfo> returnRecords = new ArrayList<>();
                     final Collection<LDAPPermissionInfo> returnRecords = new ArrayList<>();

+ 4 - 4
server/src/main/java/password/pwm/util/PropertyConfigurationImporter.java

@@ -21,7 +21,7 @@
 package password.pwm.util;
 package password.pwm.util;
 
 
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.stored.ConfigurationProperty;
 import password.pwm.config.stored.ConfigurationProperty;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfiguration;
 import password.pwm.config.stored.StoredConfigurationFactory;
 import password.pwm.config.stored.StoredConfigurationFactory;
@@ -181,21 +181,21 @@ public class PropertyConfigurationImporter
             final Optional<Collection<X509Certificate>> optionalCert = readCertificate( PropertyKey.LDAP_SERVERCERTS );
             final Optional<Collection<X509Certificate>> optionalCert = readCertificate( PropertyKey.LDAP_SERVERCERTS );
             if ( optionalCert.isPresent( ) )
             if ( optionalCert.isPresent( ) )
             {
             {
-                storedConfiguration.writeSetting( PwmSetting.LDAP_SERVER_CERTS, LDAP_PROFILE, new X509CertificateValue( optionalCert.get( ) ), null );
+                storedConfiguration.writeSetting( PwmSetting.LDAP_SERVER_CERTS, LDAP_PROFILE, X509CertificateValue.fromX509( optionalCert.get( ) ), null );
             }
             }
         }
         }
         {
         {
             final Optional<Collection<X509Certificate>> optionalCert = readCertificate( PropertyKey.AUDIT_SERVERCERTS );
             final Optional<Collection<X509Certificate>> optionalCert = readCertificate( PropertyKey.AUDIT_SERVERCERTS );
             if ( optionalCert.isPresent( ) )
             if ( optionalCert.isPresent( ) )
             {
             {
-                storedConfiguration.writeSetting( PwmSetting.AUDIT_SYSLOG_CERTIFICATES, null, new X509CertificateValue( optionalCert.get( ) ), null );
+                storedConfiguration.writeSetting( PwmSetting.AUDIT_SYSLOG_CERTIFICATES, null, X509CertificateValue.fromX509( optionalCert.get( ) ), null );
             }
             }
         }
         }
         {
         {
             final Optional<Collection<X509Certificate>> optionalCert = readCertificate( PropertyKey.OAUTH_IDSERVER_SERVERCERTS );
             final Optional<Collection<X509Certificate>> optionalCert = readCertificate( PropertyKey.OAUTH_IDSERVER_SERVERCERTS );
             if ( optionalCert.isPresent( ) )
             if ( optionalCert.isPresent( ) )
             {
             {
-                storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_CERTIFICATE, null, new X509CertificateValue( optionalCert.get( ) ), null );
+                storedConfiguration.writeSetting( PwmSetting.OAUTH_ID_CERTIFICATE, null, X509CertificateValue.fromX509( optionalCert.get( ) ), null );
             }
             }
         }
         }
 
 

+ 1 - 1
server/src/main/java/password/pwm/util/i18n/ConfigLocaleStats.java

@@ -25,7 +25,7 @@ import lombok.Value;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSettingTemplateSet;
 import password.pwm.config.PwmSettingTemplateSet;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.ChallengeValue;
 import password.pwm.config.value.ChallengeValue;
 import password.pwm.config.value.data.ChallengeItemConfiguration;
 import password.pwm.config.value.data.ChallengeItemConfiguration;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmOperationalException;

+ 1 - 1
server/src/main/java/password/pwm/util/java/XmlFactory.java

@@ -70,7 +70,7 @@ public interface XmlFactory
 
 
     static XmlFactory getFactory()
     static XmlFactory getFactory()
     {
     {
-        return new XmlFactoryJDOM();
+        return new XmlFactoryW3c();
     }
     }
 
 
     static XmlFactory getFactory( final FactoryType factoryType )
     static XmlFactory getFactory( final FactoryType factoryType )

+ 1 - 1
server/src/main/java/password/pwm/util/secure/HttpsServerCertificateManager.java

@@ -24,7 +24,7 @@ import password.pwm.PwmApplication;
 import password.pwm.bean.PrivateKeyCertificate;
 import password.pwm.bean.PrivateKeyCertificate;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.StoredValue;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.stored.StoredConfigurationModifier;
 import password.pwm.config.stored.StoredConfigurationModifier;
 import password.pwm.config.value.PrivateKeyValue;
 import password.pwm.config.value.PrivateKeyValue;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;

+ 47 - 0
server/src/main/java/password/pwm/util/secure/X509Utils.java

@@ -57,6 +57,7 @@ import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedHashSet;
@@ -65,6 +66,8 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Optional;
 import java.util.Set;
 import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  *
  *
@@ -289,6 +292,50 @@ public class X509Utils
         return "subject=" + x509Certificate.getSubjectDN().getName() + ", serial=" + x509Certificate.getSerialNumber();
         return "subject=" + x509Certificate.getSubjectDN().getName() + ", serial=" + x509Certificate.getSerialNumber();
     }
     }
 
 
+    public static List<X509Certificate> certificatesFromBase64s( final Collection<String> b64certificates )
+    {
+        final Function<String, X509Certificate> mapFunction = s ->
+        {
+            try
+            {
+                return certificateFromBase64( s );
+            }
+            catch ( final Exception e )
+            {
+                LOGGER.error( () -> "error decoding certificate from b64: " + e.getMessage() );
+            }
+            return null;
+        };
+
+        return b64certificates
+                .stream()
+                .map( mapFunction )
+                .filter( Objects::nonNull )
+                .collect( Collectors.toList() );
+    }
+
+    public static List<String> certificatesToBase64s( final Collection<X509Certificate> certificates )
+    {
+        final Function<X509Certificate, String> mapFunction = s ->
+        {
+            try
+            {
+                return certificateToBase64( s );
+            }
+            catch ( final Exception e )
+            {
+                LOGGER.error( () -> "error encoding certificate to b64: " + e.getMessage() );
+            }
+            return null;
+        };
+
+        return certificates
+                .stream()
+                .map( mapFunction )
+                .filter( Objects::nonNull )
+                .collect( Collectors.toList() );
+    }
+
     enum CertDebugInfoKey
     enum CertDebugInfoKey
     {
     {
         subject,
         subject,

+ 4 - 3
server/src/test/java/password/pwm/config/PwmSettingTest.java

@@ -24,21 +24,22 @@ import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.junit.rules.TemporaryFolder;
-import password.pwm.PwmApplication;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.StoredConfigXmlSerializer;
 import password.pwm.config.stored.XmlOutputProcessData;
 import password.pwm.config.stored.XmlOutputProcessData;
+import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.StoredValueEncoder;
 import password.pwm.config.value.StoredValueEncoder;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
+import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.XmlDocument;
 import password.pwm.util.java.XmlDocument;
 import password.pwm.util.java.XmlElement;
 import password.pwm.util.java.XmlElement;
 import password.pwm.util.java.XmlFactory;
 import password.pwm.util.java.XmlFactory;
-import password.pwm.util.localdb.TestHelper;
 import password.pwm.util.secure.PwmSecurityKey;
 import password.pwm.util.secure.PwmSecurityKey;
 
 
 import java.io.InputStream;
 import java.io.InputStream;
+import java.io.Serializable;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.List;
@@ -53,7 +54,6 @@ public class PwmSettingTest
     @Test
     @Test
     public void testDefaultValues() throws Exception
     public void testDefaultValues() throws Exception
     {
     {
-        final PwmApplication pwmApplication = TestHelper.makeTestPwmApplication( temporaryFolder.newFolder() );
         final PwmSecurityKey pwmSecurityKey = new PwmSecurityKey( "abcdefghijklmnopqrstuvwxyz" );
         final PwmSecurityKey pwmSecurityKey = new PwmSecurityKey( "abcdefghijklmnopqrstuvwxyz" );
         final XmlOutputProcessData outputSettings = XmlOutputProcessData.builder()
         final XmlOutputProcessData outputSettings = XmlOutputProcessData.builder()
                 .pwmSecurityKey( pwmSecurityKey )
                 .pwmSecurityKey( pwmSecurityKey )
@@ -71,6 +71,7 @@ public class PwmSettingTest
                 storedValue.toXmlValues( StoredConfigXmlSerializer.StoredConfigXmlConstants.XML_ELEMENT_VALUE, outputSettings );
                 storedValue.toXmlValues( StoredConfigXmlSerializer.StoredConfigXmlConstants.XML_ELEMENT_VALUE, outputSettings );
                 storedValue.validateValue( pwmSetting );
                 storedValue.validateValue( pwmSetting );
                 Assert.assertNotNull( storedValue.valueHash() );
                 Assert.assertNotNull( storedValue.valueHash() );
+                JsonUtil.serialize( (Serializable) storedValue.toNativeObject() );
             }
             }
         }
         }
     }
     }