diff --git a/phase4-cef-client/src/test/java/com/helger/phase4/cef/MainCEFeInvoicingConnectivityTest.java b/phase4-cef-client/src/test/java/com/helger/phase4/cef/MainCEFeInvoicingConnectivityTest.java
index 69cbf0b9e..953992dcc 100644
--- a/phase4-cef-client/src/test/java/com/helger/phase4/cef/MainCEFeInvoicingConnectivityTest.java
+++ b/phase4-cef-client/src/test/java/com/helger/phase4/cef/MainCEFeInvoicingConnectivityTest.java
@@ -80,7 +80,7 @@ public class MainCEFeInvoicingConnectivityTest
throw new InitializationException ("TrustStore error: " + aLTS.getErrorText (Locale.US));
TRUST_STORE = aLTS.getKeyStore ();
- CF = new AS4CryptoFactoryInMemoryKeyStore (aLKS.getKeyStore (), YOUR_ID, "test123", TRUST_STORE);
+ CF = new AS4CryptoFactoryInMemoryKeyStore (aLKS.getKeyStore (), YOUR_ID, "test123".toCharArray (), TRUST_STORE);
}
public static void main (final String [] args)
@@ -122,51 +122,51 @@ public void onSoapDocument (@Nonnull final Document aDoc)
// XXX The message ID to use in the UI
final String sAS4MessageID = "36999089-662a-441f-95fd-470bec2b538e-100@phase4";
final EAS4UserMessageSendResult eRes = Phase4CEFSender.builder ()
- .cryptoFactory (CF)
- .httpRetrySettings (new HttpRetrySettings ().setMaxRetries (0))
- .action ("TC1Leg1")
- .service ("tc1", "bdx:noprocess")
- .senderParticipantID (new SimpleParticipantIdentifier ("connectivity-partid-qns",
- YOUR_ID))
- .receiverParticipantID (new SimpleParticipantIdentifier ("connectivity-partid-qns",
- "domibus-gitb"))
- .fromPartyIDType ("urn:oasis:names:tc:ebcore:partyid-type:unregistered")
- .fromPartyID (YOUR_ID)
- .fromRole (CAS4.DEFAULT_INITIATOR_URL)
- .toPartyIDType ("urn:oasis:names:tc:ebcore:partyid-type:unregistered")
- .toPartyID ("domibus-gitb")
- .toRole (CAS4.DEFAULT_RESPONDER_URL)
- .messageID (sAS4MessageID)
- .payload (AS4OutgoingAttachment.builder ()
- .data (aPayloadBytes)
- .filename ("businessContentPayload")
- .compressionGZIP ()
- .mimeType (CMimeType.TEXT_XML)
- .contentID ("message")
- .build ())
- .buildMessageCallback (x1)
- .endpointDetailProvider (new AS4EndpointDetailProviderConstant (CertificateHelper.convertStringToCertficateOrNull ("-----BEGIN CERTIFICATE-----\r\n" +
- "MIIDOzCCAiOgAwIBAgIJAKbwaKpEwNTKMA0GCSqGSIb3DQEBCwUAMDQxDTALBgNV\r\n" +
- "BAoMBEdJVEIxDTALBgNVBAsMBEdJVEIxFDASBgNVBAMMC2dpdGItZW5naW5lMB4X\r\n" +
- "DTE0MTIyNDEzMjIzNFoXDTI0MTIyMTEzMjIzNFowNDENMAsGA1UECgwER0lUQjEN\r\n" +
- "MAsGA1UECwwER0lUQjEUMBIGA1UEAwwLZ2l0Yi1lbmdpbmUwggEiMA0GCSqGSIb3\r\n" +
- "DQEBAQUAA4IBDwAwggEKAoIBAQCpNuRRMhpd2SvNKsZe/WTxm4zuX2Zc5by3zGcm\r\n" +
- "uzwePdMCnCXk2FAUH67qS9r5VBa4USfiB7l1piyLrNwYWGRDo5OeWIz6Q821/1v7\r\n" +
- "UHq7FfB0LFPcJ+mOwrDqS+VL0MjcSW4pocJHrpFwObWHTY/R4WmW2xwGOKVh0OUL\r\n" +
- "UhqQsHDnDhCzFaEWhS8n1lUw3GRipwKLyYvXK8XgLceEmh+j0+cdmIj4a1L4oza/\r\n" +
- "UgBnCqSob+vowgClyZnGVihE9K8eLLwCSLlIiD+bXWf0VJPLXBNLdNIkRRC0QO0j\r\n" +
- "T9TuE5TF3SknkA5D0NFp023Alz7jieI0D6JE78QyNQN6y6QRAgMBAAGjUDBOMB0G\r\n" +
- "A1UdDgQWBBQpAkry20hAcvlw+4poxQC8TI+EgTAfBgNVHSMEGDAWgBQpAkry20hA\r\n" +
- "cvlw+4poxQC8TI+EgTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBS\r\n" +
- "dfmT3E9uvhiEgVefdwXkkxqlXLQQxfjaqVRVzPTHLqdVs/nBK+iQNhqg+6eLcaGQ\r\n" +
- "yyDy88vwQ85rqwOFbZd05esIFXYl0pgl1pVsb7HmMNmKT3UPay3HDlHX45ZoexDU\r\n" +
- "pza4OcrauEM8Yg/5i9dCIPC1GiHebJpYusMVfP78b+5DAyARrHtcb0EJ8rOLxHh6\r\n" +
- "K2S4EHI6sqQkGHEt1z4m66LyK+vnkLGaq3y6MWEufh78eICDyyVz0DhdIhr18ZHX\r\n" +
- "dpcsH2VOkE36KnWSo0spEXa6ZtP8MqQ60kJgBt4XcuArKfjIGC6vB6dE0NzXngBD\r\n" +
- "PHgMfmHJW018/6eN/f0q\r\n" +
- "-----END CERTIFICATE-----"),
- "https://www.itb.ec.europa.eu/cef/domibus/services/msh"))
- .sendMessageAndCheckForReceipt ();
+ .cryptoFactory (CF)
+ .httpRetrySettings (new HttpRetrySettings ().setMaxRetries (0))
+ .action ("TC1Leg1")
+ .service ("tc1", "bdx:noprocess")
+ .senderParticipantID (new SimpleParticipantIdentifier ("connectivity-partid-qns",
+ YOUR_ID))
+ .receiverParticipantID (new SimpleParticipantIdentifier ("connectivity-partid-qns",
+ "domibus-gitb"))
+ .fromPartyIDType ("urn:oasis:names:tc:ebcore:partyid-type:unregistered")
+ .fromPartyID (YOUR_ID)
+ .fromRole (CAS4.DEFAULT_INITIATOR_URL)
+ .toPartyIDType ("urn:oasis:names:tc:ebcore:partyid-type:unregistered")
+ .toPartyID ("domibus-gitb")
+ .toRole (CAS4.DEFAULT_RESPONDER_URL)
+ .messageID (sAS4MessageID)
+ .payload (AS4OutgoingAttachment.builder ()
+ .data (aPayloadBytes)
+ .filename ("businessContentPayload")
+ .compressionGZIP ()
+ .mimeType (CMimeType.TEXT_XML)
+ .contentID ("message")
+ .build ())
+ .buildMessageCallback (x1)
+ .endpointDetailProvider (new AS4EndpointDetailProviderConstant (CertificateHelper.convertStringToCertficateOrNull ("-----BEGIN CERTIFICATE-----\r\n" +
+ "MIIDOzCCAiOgAwIBAgIJAKbwaKpEwNTKMA0GCSqGSIb3DQEBCwUAMDQxDTALBgNV\r\n" +
+ "BAoMBEdJVEIxDTALBgNVBAsMBEdJVEIxFDASBgNVBAMMC2dpdGItZW5naW5lMB4X\r\n" +
+ "DTE0MTIyNDEzMjIzNFoXDTI0MTIyMTEzMjIzNFowNDENMAsGA1UECgwER0lUQjEN\r\n" +
+ "MAsGA1UECwwER0lUQjEUMBIGA1UEAwwLZ2l0Yi1lbmdpbmUwggEiMA0GCSqGSIb3\r\n" +
+ "DQEBAQUAA4IBDwAwggEKAoIBAQCpNuRRMhpd2SvNKsZe/WTxm4zuX2Zc5by3zGcm\r\n" +
+ "uzwePdMCnCXk2FAUH67qS9r5VBa4USfiB7l1piyLrNwYWGRDo5OeWIz6Q821/1v7\r\n" +
+ "UHq7FfB0LFPcJ+mOwrDqS+VL0MjcSW4pocJHrpFwObWHTY/R4WmW2xwGOKVh0OUL\r\n" +
+ "UhqQsHDnDhCzFaEWhS8n1lUw3GRipwKLyYvXK8XgLceEmh+j0+cdmIj4a1L4oza/\r\n" +
+ "UgBnCqSob+vowgClyZnGVihE9K8eLLwCSLlIiD+bXWf0VJPLXBNLdNIkRRC0QO0j\r\n" +
+ "T9TuE5TF3SknkA5D0NFp023Alz7jieI0D6JE78QyNQN6y6QRAgMBAAGjUDBOMB0G\r\n" +
+ "A1UdDgQWBBQpAkry20hAcvlw+4poxQC8TI+EgTAfBgNVHSMEGDAWgBQpAkry20hA\r\n" +
+ "cvlw+4poxQC8TI+EgTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBS\r\n" +
+ "dfmT3E9uvhiEgVefdwXkkxqlXLQQxfjaqVRVzPTHLqdVs/nBK+iQNhqg+6eLcaGQ\r\n" +
+ "yyDy88vwQ85rqwOFbZd05esIFXYl0pgl1pVsb7HmMNmKT3UPay3HDlHX45ZoexDU\r\n" +
+ "pza4OcrauEM8Yg/5i9dCIPC1GiHebJpYusMVfP78b+5DAyARrHtcb0EJ8rOLxHh6\r\n" +
+ "K2S4EHI6sqQkGHEt1z4m66LyK+vnkLGaq3y6MWEufh78eICDyyVz0DhdIhr18ZHX\r\n" +
+ "dpcsH2VOkE36KnWSo0spEXa6ZtP8MqQ60kJgBt4XcuArKfjIGC6vB6dE0NzXngBD\r\n" +
+ "PHgMfmHJW018/6eN/f0q\r\n" +
+ "-----END CERTIFICATE-----"),
+ "https://www.itb.ec.europa.eu/cef/domibus/services/msh"))
+ .sendMessageAndCheckForReceipt ();
LOGGER.info ("Sending AS4 message to CEF with result " + eRes);
}
finally
diff --git a/phase4-euctp-client/src/test/java/com/helger/phase4/euctp/MainPhase4EuCtpSenderExample.java b/phase4-euctp-client/src/test/java/com/helger/phase4/euctp/MainPhase4EuCtpSenderExample.java
index fd35701fc..80413d3b8 100644
--- a/phase4-euctp-client/src/test/java/com/helger/phase4/euctp/MainPhase4EuCtpSenderExample.java
+++ b/phase4-euctp-client/src/test/java/com/helger/phase4/euctp/MainPhase4EuCtpSenderExample.java
@@ -78,18 +78,18 @@ public class MainPhase4EuCtpSenderExample
@Nonnull
private static AS4CryptoProperties _buildAs4CryptoProperties ()
{
- final AS4CryptoProperties as4SigningProperties = new AS4CryptoProperties ();
- as4SigningProperties.setKeyStorePath (System.getenv ("AS4_SIGNING_KEYSTORE_PATH"));
- as4SigningProperties.setKeyStoreType (EKeyStoreType.PKCS12);
- as4SigningProperties.setKeyStorePassword (System.getenv ("AS4_SIGNING_KEYSTORE_PASSWORD"));
- as4SigningProperties.setKeyAlias (System.getenv ("AS4_SIGNING_KEY_ALIAS"));
- as4SigningProperties.setKeyPassword (System.getenv ("AS4_SIGNING_KEY_PASSWORD"));
+ final AS4CryptoProperties ret = new AS4CryptoProperties ();
+ ret.setKeyStorePath (System.getenv ("AS4_SIGNING_KEYSTORE_PATH"));
+ ret.setKeyStoreType (EKeyStoreType.PKCS12);
+ ret.setKeyStorePassword (System.getenv ("AS4_SIGNING_KEYSTORE_PASSWORD"));
+ ret.setKeyAlias (System.getenv ("AS4_SIGNING_KEY_ALIAS"));
+ ret.setKeyPassword (System.getenv ("AS4_SIGNING_KEY_PASSWORD"));
// must include the Taxud CA and intermediate certificates
- as4SigningProperties.setTrustStorePath (System.getenv ("AS4_SIGNING_TRUST_KEYSTORE_PATH"));
- as4SigningProperties.setTrustStoreType (EKeyStoreType.PKCS12);
- as4SigningProperties.setTrustStorePassword (System.getenv ("AS4_SIGNING_TRUST_KEYSTORE_PASSWORD"));
- return as4SigningProperties;
+ ret.setTrustStorePath (System.getenv ("AS4_SIGNING_TRUST_KEYSTORE_PATH"));
+ ret.setTrustStoreType (EKeyStoreType.PKCS12);
+ ret.setTrustStorePassword (System.getenv ("AS4_SIGNING_TRUST_KEYSTORE_PASSWORD"));
+ return ret;
}
public static void main (final String [] args)
@@ -113,8 +113,8 @@ public static void main (final String [] args)
final Phase4EuCtpHttpClientSettings aHttpClientSettings = new Phase4EuCtpHttpClientSettings (aSslKeyStore,
aKeyStorePassword);
- final AS4CryptoProperties as4SigningProperties = _buildAs4CryptoProperties ();
- final AS4CryptoFactoryProperties cryptoFactoryProperties = new AS4CryptoFactoryProperties (as4SigningProperties);
+ final AS4CryptoProperties as4CryptoProperties = _buildAs4CryptoProperties ();
+ final AS4CryptoFactoryProperties cryptoFactoryProperties = new AS4CryptoFactoryProperties (as4CryptoProperties);
// configured on the STI
final String fromPartyID = System.getenv ("AS4_FROM_PARTY_ID");
diff --git a/phase4-lib/src/main/java/com/helger/phase4/config/AS4Configuration.java b/phase4-lib/src/main/java/com/helger/phase4/config/AS4Configuration.java
index 973a3d2f6..4807e078c 100644
--- a/phase4-lib/src/main/java/com/helger/phase4/config/AS4Configuration.java
+++ b/phase4-lib/src/main/java/com/helger/phase4/config/AS4Configuration.java
@@ -31,9 +31,10 @@
import com.helger.commons.io.resource.IReadableResource;
import com.helger.commons.io.resourceprovider.ReadableResourceProviderChain;
import com.helger.commons.string.StringParser;
-import com.helger.config.Config;
import com.helger.config.ConfigFactory;
import com.helger.config.IConfig;
+import com.helger.config.fallback.ConfigWithFallback;
+import com.helger.config.fallback.IConfigWithFallback;
import com.helger.config.source.EConfigSourceType;
import com.helger.config.source.MultiConfigurationValueProvider;
import com.helger.config.source.res.ConfigurationSourceProperties;
@@ -109,9 +110,9 @@ public static MultiConfigurationValueProvider createPhase4ValueProvider ()
}
private static final MultiConfigurationValueProvider VP = createPhase4ValueProvider ();
- private static final IConfig DEFAULT_INSTANCE = Config.create (VP);
+ private static final IConfigWithFallback DEFAULT_INSTANCE = new ConfigWithFallback (VP);
private static final SimpleReadWriteLock RW_LOCK = new SimpleReadWriteLock ();
- private static IConfig s_aConfig = DEFAULT_INSTANCE;
+ private static IConfigWithFallback s_aConfig = DEFAULT_INSTANCE;
private AS4Configuration ()
{}
@@ -120,7 +121,7 @@ private AS4Configuration ()
* @return The current global configuration. Never null
.
*/
@Nonnull
- public static IConfig getConfig ()
+ public static IConfigWithFallback getConfig ()
{
// Inline for performance
RW_LOCK.readLock ().lock ();
@@ -142,10 +143,10 @@ public static IConfig getConfig ()
* @return The old value of {@link IConfig}. Never null
.
*/
@Nonnull
- public static IConfig setConfig (@Nonnull final IConfig aNewConfig)
+ public static IConfigWithFallback setConfig (@Nonnull final IConfigWithFallback aNewConfig)
{
ValueEnforcer.notNull (aNewConfig, "NewConfig");
- final IConfig ret;
+ final IConfigWithFallback ret;
RW_LOCK.writeLock ().lock ();
try
{
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryConfiguration.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryConfiguration.java
index eb562a828..2cf7d1826 100644
--- a/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryConfiguration.java
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryConfiguration.java
@@ -16,22 +16,23 @@
*/
package com.helger.phase4.crypto;
-import java.security.KeyStore;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.util.Locale;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
-import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.Merlin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import com.helger.commons.ValueEnforcer;
import com.helger.commons.annotation.Nonempty;
-import com.helger.commons.string.StringHelper;
import com.helger.config.IConfig;
+import com.helger.config.fallback.IConfigWithFallback;
import com.helger.phase4.config.AS4Configuration;
-import com.helger.security.keystore.EKeyStoreType;
-import com.helger.security.keystore.KeyStoreHelper;
+import com.helger.security.keystore.LoadedKey;
+import com.helger.security.keystore.LoadedKeyStore;
/**
* phase4 crypto factory settings based on {@link IConfig}. It can do the same
@@ -51,11 +52,11 @@
*/
@SuppressWarnings ("javadoc")
@Immutable
-public class AS4CryptoFactoryConfiguration extends AbstractAS4CryptoFactory
+public class AS4CryptoFactoryConfiguration extends AS4CryptoFactoryInMemoryKeyStore
{
- public static final EKeyStoreType DEFAULT_KEYSTORE_TYPE = EKeyStoreType.JKS;
- public static final EKeyStoreType DEFAULT_TRUSTSTORE_TYPE = EKeyStoreType.JKS;
+ public static final String DEFAULT_CONFIG_PREFIX = "org.apache.wss4j.crypto.merlin.";
+ private static final Logger LOGGER = LoggerFactory.getLogger (AS4CryptoFactoryConfiguration.class);
private static final AS4CryptoFactoryConfiguration DEFAULT_INSTANCE = new AS4CryptoFactoryConfiguration (AS4Configuration.getConfig ());
/**
@@ -68,22 +69,6 @@ public static AS4CryptoFactoryConfiguration getDefaultInstance ()
return DEFAULT_INSTANCE;
}
- private final EKeyStoreType m_eKeyStoreType;
- private final String m_sKeyStorePath;
- private final String m_sKeyStorePassword;
-
- private final String m_sKeyAlias;
- private final String m_sKeyPassword;
-
- private final EKeyStoreType m_eTrustStoreType;
- private final String m_sTrustStorePath;
- private final String m_sTrustStorePassword;
-
- // Lazy initialized
- private Merlin m_aCrypto;
- private KeyStore m_aKeyStore;
- private KeyStore m_aTrustStore;
-
/**
* This constructor takes the configuration object and uses the default prefix
* for backwards compatibility. This is kind of the default constructor.
@@ -91,126 +76,69 @@ public static AS4CryptoFactoryConfiguration getDefaultInstance ()
* @param aConfig
* The configuration object to be used. May not be null
.
*/
- public AS4CryptoFactoryConfiguration (@Nonnull final IConfig aConfig)
- {
- this (aConfig, "org.apache.wss4j.crypto.merlin.");
- }
-
- /**
- * This constructor takes the configuration object and uses the provided
- * configuration prefix. This is kind of the default constructor.
- *
- * @param aConfig
- * The configuration object to be used. May not be null
.
- * @param sConfigPrefix
- * The configuration prefix to be used. May neither be
- * null
nor empty and must end with a dot ('.').
- */
- public AS4CryptoFactoryConfiguration (@Nonnull final IConfig aConfig, @Nonnull @Nonempty final String sConfigPrefix)
+ public AS4CryptoFactoryConfiguration (@Nonnull final IConfigWithFallback aConfig)
{
- ValueEnforcer.notNull (aConfig, "Config");
- ValueEnforcer.notEmpty (sConfigPrefix, "ConfigPrefix");
- ValueEnforcer.isTrue ( () -> StringHelper.endsWith (sConfigPrefix, '.'), "ConfigPrefix must end with a dot");
-
- // Key Store
- m_eKeyStoreType = EKeyStoreType.getFromIDCaseInsensitiveOrDefault (aConfig.getAsString (sConfigPrefix +
- "keystore.type"),
- DEFAULT_KEYSTORE_TYPE);
- m_sKeyStorePath = aConfig.getAsString (sConfigPrefix + "keystore.file");
- m_sKeyStorePassword = aConfig.getAsString (sConfigPrefix + "keystore.password");
-
- // Key Store Key
- m_sKeyAlias = aConfig.getAsString (sConfigPrefix + "keystore.alias");
- m_sKeyPassword = aConfig.getAsString (sConfigPrefix + "keystore.private.password");
-
- // Trust Store
- m_eTrustStoreType = EKeyStoreType.getFromIDCaseInsensitiveOrDefault (aConfig.getAsString (sConfigPrefix +
- "truststore.type"),
- DEFAULT_KEYSTORE_TYPE);
- m_sTrustStorePath = aConfig.getAsString (sConfigPrefix + "truststore.file");
- m_sTrustStorePassword = aConfig.getAsString (sConfigPrefix + "truststore.password");
+ this (aConfig, DEFAULT_CONFIG_PREFIX);
}
- /**
- * Helper method to create a WSS4J {@link Merlin} instance based on the
- * configured keystore and truststore.
- *
- * @return A new {@link Merlin} object.
- * @throws IllegalStateException
- * if creation failed
- */
- @Nonnull
- public Merlin createMerlin ()
+ @Nullable
+ private static IAS4KeyStoreDescriptor _loadKeyStore (@Nonnull final IConfigWithFallback aConfig,
+ @Nonnull @Nonempty final String sConfigPrefix)
{
- try
+ final IAS4KeyStoreDescriptor aDescriptor = AS4KeyStoreDescriptor.createFromConfig (aConfig, sConfigPrefix, null);
+ final LoadedKeyStore aLKS = aDescriptor.loadKeyStore ();
+ if (aLKS.getKeyStore () == null)
{
- final Merlin ret = new Merlin ();
- ret.setKeyStore (getKeyStore ());
- ret.setTrustStore (getTrustStore ());
- return ret;
+ LOGGER.error ("Failed to load the key store from the properties starting with '" +
+ sConfigPrefix +
+ "': " +
+ aLKS.getErrorText (Locale.ROOT));
}
- catch (final RuntimeException ex)
- {
- throw new IllegalStateException ("Failed to create Merlin object", ex);
- }
- }
-
- /**
- * Lazily create a {@link Merlin} instance using the configured keystore and
- * truststore.
- */
- @Nonnull
- public final Crypto getCrypto (@Nonnull final ECryptoMode eCryptoMode)
- {
- Merlin ret = m_aCrypto;
- if (ret == null)
+ else
{
- // Create only once and cache
- ret = m_aCrypto = createMerlin ();
+ final LoadedKey aLK = aDescriptor.loadKey ();
+ if (aLK.getKeyEntry () == null)
+ {
+ LOGGER.error ("Failed to load the prvate key from the key store properties starting with '" +
+ sConfigPrefix +
+ "': " +
+ aLK.getErrorText (Locale.ROOT));
+ }
}
- return ret;
+ return aDescriptor;
}
@Nullable
- public final KeyStore getKeyStore ()
+ private static IAS4TrustStoreDescriptor _loadTrustStore (@Nonnull final IConfigWithFallback aConfig,
+ @Nonnull @Nonempty final String sConfigPrefix)
{
- KeyStore ret = m_aKeyStore;
- if (ret == null)
+ final IAS4TrustStoreDescriptor aDescriptor = AS4TrustStoreDescriptor.createFromConfig (aConfig,
+ sConfigPrefix,
+ null);
+ final LoadedKeyStore aLTS = aDescriptor.loadTrustStore ();
+ if (aLTS.getKeyStore () == null)
{
- ret = m_aKeyStore = KeyStoreHelper.loadKeyStore (m_eKeyStoreType, m_sKeyStorePath, m_sKeyStorePassword)
- .getKeyStore ();
+ LOGGER.error ("Failed to load the trust store from the properties starting with '" +
+ sConfigPrefix +
+ "': " +
+ aLTS.getErrorText (Locale.ROOT));
}
- return ret;
- }
-
- @Nullable
- public final String getKeyAlias ()
- {
- return m_sKeyAlias;
- }
-
- @Nullable
- public String getKeyPasswordPerAlias (@Nullable final String sSearchKeyAlias)
- {
- final String sKeyAlias = m_sKeyAlias;
-
- // Use case insensitive compare, depends on the keystore type
- if (sKeyAlias != null && sSearchKeyAlias != null && sKeyAlias.equalsIgnoreCase (sSearchKeyAlias))
- return m_sKeyPassword;
-
- return null;
+ return aDescriptor;
}
- @Nullable
- public final KeyStore getTrustStore ()
+ /**
+ * This constructor takes the configuration object and uses the provided
+ * configuration prefix. This is kind of the default constructor.
+ *
+ * @param aConfig
+ * The configuration object to be used. May not be null
.
+ * @param sConfigPrefix
+ * The configuration prefix to be used. May neither be
+ * null
nor empty and must end with a dot ('.').
+ */
+ public AS4CryptoFactoryConfiguration (@Nonnull final IConfigWithFallback aConfig,
+ @Nonnull @Nonempty final String sConfigPrefix)
{
- KeyStore ret = m_aTrustStore;
- if (ret == null)
- {
- // Load only once and cache then
- ret = m_aTrustStore = KeyStoreHelper.loadKeyStore (m_eTrustStoreType, m_sTrustStorePath, m_sTrustStorePassword)
- .getKeyStore ();
- }
- return ret;
+ super (_loadKeyStore (aConfig, sConfigPrefix), _loadTrustStore (aConfig, sConfigPrefix));
}
}
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryInMemoryKeyStore.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryInMemoryKeyStore.java
index fe8f2a0ea..47134b1ac 100644
--- a/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryInMemoryKeyStore.java
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryInMemoryKeyStore.java
@@ -42,12 +42,29 @@ public class AS4CryptoFactoryInMemoryKeyStore extends AbstractAS4CryptoFactory
{
private final KeyStore m_aKeyStore;
private final String m_sKeyAlias;
- private final String m_sKeyPassword;
+ private final char [] m_aKeyPassword;
private final KeyStore m_aTrustStore;
// Lazy initialized
private Merlin m_aCrypto;
+ /**
+ * Constructor using the key store and trust store descriptors.
+ *
+ * @param aKeyStoreDesc
+ * The key store descriptor. May not be null
.
+ * @param aTrustStoreDesc
+ * The trust store descriptor. May not be null
.
+ */
+ protected AS4CryptoFactoryInMemoryKeyStore (@Nonnull final IAS4KeyStoreDescriptor aKeyStoreDesc,
+ @Nonnull final IAS4TrustStoreDescriptor aTrustStoreDesc)
+ {
+ this (aKeyStoreDesc.loadKeyStore ().getKeyStore (),
+ aKeyStoreDesc.getKeyAlias (),
+ aKeyStoreDesc.getKeyPassword (),
+ aTrustStoreDesc.loadTrustStore ().getKeyStore ());
+ }
+
/**
* Default constructor.
*
@@ -56,7 +73,7 @@ public class AS4CryptoFactoryInMemoryKeyStore extends AbstractAS4CryptoFactory
* @param sKeyAlias
* The key alias to be used. May neither be null
nor
* empty.
- * @param sKeyPassword
+ * @param aKeyPassword
* The key password to be used. May not be null
but maybe
* empty.
* @param aTrustStore
@@ -65,15 +82,15 @@ public class AS4CryptoFactoryInMemoryKeyStore extends AbstractAS4CryptoFactory
*/
public AS4CryptoFactoryInMemoryKeyStore (@Nonnull final KeyStore aKeyStore,
@Nonnull @Nonempty final String sKeyAlias,
- @Nonnull final String sKeyPassword,
+ @Nonnull final char [] aKeyPassword,
@Nullable final KeyStore aTrustStore)
{
ValueEnforcer.notNull (aKeyStore, "KeyStore");
ValueEnforcer.notEmpty (sKeyAlias, "KeyAlias");
- ValueEnforcer.notNull (sKeyPassword, "KeyPassword");
+ ValueEnforcer.notNull (aKeyPassword, "KeyPassword");
m_aKeyStore = aKeyStore;
m_sKeyAlias = sKeyAlias;
- m_sKeyPassword = sKeyPassword;
+ m_aKeyPassword = aKeyPassword;
m_aTrustStore = aTrustStore;
}
@@ -109,11 +126,11 @@ public final String getKeyAlias ()
}
@Nullable
- public String getKeyPasswordPerAlias (@Nullable final String sSearchKeyAlias)
+ public char [] getKeyPasswordPerAliasCharArray (@Nullable final String sSearchKeyAlias)
{
// Use case insensitive compare, depends on the keystore type
if (m_sKeyAlias != null && sSearchKeyAlias != null && m_sKeyAlias.equalsIgnoreCase (sSearchKeyAlias))
- return m_sKeyPassword;
+ return m_aKeyPassword;
return null;
}
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryProperties.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryProperties.java
index 49edc17e8..aac34a051 100644
--- a/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryProperties.java
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryProperties.java
@@ -149,13 +149,16 @@ public final String getKeyAlias ()
}
@Nullable
- public String getKeyPasswordPerAlias (@Nullable final String sSearchKeyAlias)
+ public char [] getKeyPasswordPerAliasCharArray (@Nullable final String sSearchKeyAlias)
{
final String sKeyAlias = getKeyAlias ();
// Use case insensitive compare, depends on the keystore type
if (sKeyAlias != null && sSearchKeyAlias != null && sKeyAlias.equalsIgnoreCase (sSearchKeyAlias))
- return m_aCryptoProps.getKeyPassword ();
+ {
+ final String ret = m_aCryptoProps.getKeyPassword ();
+ return ret == null ? null : ret.toCharArray ();
+ }
return null;
}
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoProperties.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoProperties.java
index a31d2b928..78941b218 100644
--- a/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoProperties.java
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoProperties.java
@@ -76,8 +76,8 @@ public class AS4CryptoProperties implements Serializable, ICloneable m_aLK;
+
+ public AS4KeyStoreDescriptor (@Nonnull final IKeyStoreType aType,
+ @Nonnull @Nonempty final String sPath,
+ @Nonnull final char [] aPassword,
+ @Nullable final Provider aProvider,
+ @Nonnull @Nonempty final String sKeyAlias,
+ @Nonnull final char [] aKeyPassword)
+ {
+ ValueEnforcer.notNull (aType, "Type");
+ ValueEnforcer.notEmpty (sPath, "Path");
+ ValueEnforcer.notNull (aPassword, "Password");
+ ValueEnforcer.notEmpty (sKeyAlias, "KeyAlias");
+ ValueEnforcer.notNull (aKeyPassword, "KeyPassword");
+ m_aType = aType;
+ m_sPath = sPath;
+ m_aPassword = aPassword;
+ m_aProvider = aProvider;
+ m_sKeyAlias = sKeyAlias;
+ m_aKeyPassword = aKeyPassword;
+ }
+
+ @Nonnull
+ public IKeyStoreType getKeyStoreType ()
+ {
+ return m_aType;
+ }
+
+ @Nonnull
+ @Nonempty
+ public String getKeyStorePath ()
+ {
+ return m_sPath;
+ }
+
+ @Nonnull
+ @ReturnsMutableObject
+ public char [] getKeyStorePassword ()
+ {
+ return m_aPassword;
+ }
+
+ @Nullable
+ public Provider getProvider ()
+ {
+ return m_aProvider;
+ }
+
+ @Nonnull
+ public LoadedKeyStore loadKeyStore ()
+ {
+ LoadedKeyStore ret = m_aLKS;
+ if (ret == null)
+ ret = m_aLKS = KeyStoreHelper.loadKeyStore (m_aType, m_sPath, new String (m_aPassword), m_aProvider);
+ return ret;
+ }
+
+ @Nonnull
+ @Nonempty
+ public String getKeyAlias ()
+ {
+ return m_sKeyAlias;
+ }
+
+ @Nonnull
+ @ReturnsMutableObject
+ public char [] getKeyPassword ()
+ {
+ return m_aKeyPassword;
+ }
+
+ @Nonnull
+ public LoadedKey loadKey ()
+ {
+ LoadedKey ret = m_aLK;
+ if (ret == null)
+ {
+ ret = m_aLK = KeyStoreHelper.loadPrivateKey (loadKeyStore ().getKeyStore (),
+ m_sPath,
+ m_sKeyAlias,
+ m_aKeyPassword);
+ }
+ return ret;
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new ToStringGenerator (null).append ("Type", m_aType)
+ .append ("Path", m_sPath)
+ .appendPassword ("Password")
+ .appendIfNotNull ("Provider", m_aProvider)
+ .append ("KeyAlias", m_sKeyAlias)
+ .appendPassword ("KeyPassword")
+ .getToString ();
+ }
+
+ /**
+ * Create the key store descriptor from the provided configuration item. The
+ * following configuration properties are used, relative to the configuration
+ * prefix:
+ *
+ * keystore.type
- the key store type
+ * keystore.file
- the key store path
+ * keystore.password
- the key store password
+ * keystore.alias
- the key store alias
+ * keystore.private.password
- the key store key
+ * password
+ *
+ *
+ * @param aConfig
+ * The configuration object to be used. May not be null
.
+ * @param sConfigPrefix
+ * The configuration prefix to be used. May neither be
+ * null
nor empty and must end with a dot ('.').
+ * @param aProvider
+ * The Java security provider for loading the key store. May be
+ * null
to use the default.
+ * @return A new {@link AS4KeyStoreDescriptor} object and never
+ * null
.
+ */
+ @Nonnull
+ public static AS4KeyStoreDescriptor createFromConfig (@Nonnull final IConfigWithFallback aConfig,
+ @Nonnull @Nonempty final String sConfigPrefix,
+ @Nullable final Provider aProvider)
+ {
+ ValueEnforcer.notNull (aConfig, "Config");
+ ValueEnforcer.notEmpty (sConfigPrefix, "ConfigPrefix");
+ ValueEnforcer.isTrue ( () -> StringHelper.endsWith (sConfigPrefix, '.'), "ConfigPrefix must end with a dot");
+
+ // Key Store
+ final String sType = aConfig.getAsString (sConfigPrefix + "keystore.type");
+ final EKeyStoreType aType = EKeyStoreType.getFromIDCaseInsensitiveOrDefault (sType,
+ CAS4Crypto.DEFAULT_KEY_STORE_TYPE);
+ final String sPath = aConfig.getAsString (sConfigPrefix + "keystore.file");
+ final char [] aPassword = aConfig.getAsCharArray (sConfigPrefix + "keystore.password");
+
+ // Key Store Key
+ final String sKeyAlias = aConfig.getAsString (sConfigPrefix + "keystore.alias");
+ final char [] aKeyPassword = aConfig.getAsCharArray (sConfigPrefix + "keystore.private.password");
+
+ return new AS4KeyStoreDescriptor (aType, sPath, aPassword, aProvider, sKeyAlias, aKeyPassword);
+ }
+}
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4TrustStoreDescriptor.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4TrustStoreDescriptor.java
new file mode 100644
index 000000000..deb1d450f
--- /dev/null
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/AS4TrustStoreDescriptor.java
@@ -0,0 +1,133 @@
+package com.helger.phase4.crypto;
+
+import java.security.Provider;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.helger.commons.ValueEnforcer;
+import com.helger.commons.annotation.Nonempty;
+import com.helger.commons.annotation.ReturnsMutableObject;
+import com.helger.commons.string.StringHelper;
+import com.helger.commons.string.ToStringGenerator;
+import com.helger.config.fallback.IConfigWithFallback;
+import com.helger.security.keystore.EKeyStoreType;
+import com.helger.security.keystore.IKeyStoreType;
+import com.helger.security.keystore.KeyStoreHelper;
+import com.helger.security.keystore.LoadedKeyStore;
+
+/**
+ * The default implementation of {@link IAS4TrustStoreDescriptor}.
+ *
+ * @author Philip Helger
+ * @since 3.0.0
+ */
+public class AS4TrustStoreDescriptor implements IAS4TrustStoreDescriptor
+{
+ private final IKeyStoreType m_aType;
+ private final String m_sPath;
+ private final char [] m_aPassword;
+ private final Provider m_aProvider;
+ // Lazily initialized
+ private LoadedKeyStore m_aLTS;
+
+ public AS4TrustStoreDescriptor (@Nonnull final IKeyStoreType aType,
+ @Nonnull @Nonempty final String sPath,
+ @Nonnull final char [] aPassword,
+ @Nullable final Provider aProvider)
+ {
+ ValueEnforcer.notNull (aType, "Type");
+ ValueEnforcer.notEmpty (sPath, "Path");
+ ValueEnforcer.notNull (aPassword, "Password");
+ m_aType = aType;
+ m_sPath = sPath;
+ m_aPassword = aPassword;
+ m_aProvider = aProvider;
+ }
+
+ @Nonnull
+ public IKeyStoreType getTrustStoreType ()
+ {
+ return m_aType;
+ }
+
+ @Nonnull
+ @Nonempty
+ public String getTrustStorePath ()
+ {
+ return m_sPath;
+ }
+
+ @Nonnull
+ @ReturnsMutableObject
+ public char [] getTrustStorePassword ()
+ {
+ return m_aPassword;
+ }
+
+ @Nullable
+ public Provider getProvider ()
+ {
+ return m_aProvider;
+ }
+
+ @Nonnull
+ public LoadedKeyStore loadTrustStore ()
+ {
+ LoadedKeyStore ret = m_aLTS;
+ if (ret == null)
+ ret = m_aLTS = KeyStoreHelper.loadKeyStore (m_aType, m_sPath, new String (m_aPassword), m_aProvider);
+ return ret;
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new ToStringGenerator (null).append ("Type", m_aType)
+ .append ("Path", m_sPath)
+ .appendPassword ("Password")
+ .appendIfNotNull ("Provider", m_aProvider)
+ .getToString ();
+ }
+
+ /**
+ * Create the trust store descriptor from the provided configuration item. The
+ * following configuration properties are used, relative to the configuration
+ * prefix:
+ *
+ * truststore.type
- the trust store type
+ * truststore.file
- the trust store path
+ * truststore.password
- the trust store password
+ * password
+ *
+ *
+ * @param aConfig
+ * The configuration object to be used. May not be null
.
+ * @param sConfigPrefix
+ * The configuration prefix to be used. May neither be
+ * null
nor empty and must end with a dot ('.').
+ * @param aProvider
+ * The Java security provider for loading the trust store. May be
+ * null
to use the default.
+ * @return A new {@link AS4TrustStoreDescriptor} object and never
+ * null
.
+ */
+ @Nonnull
+ public static AS4TrustStoreDescriptor createFromConfig (@Nonnull final IConfigWithFallback aConfig,
+ @Nonnull @Nonempty final String sConfigPrefix,
+ @Nullable final Provider aProvider)
+ {
+ ValueEnforcer.notNull (aConfig, "Config");
+ ValueEnforcer.notEmpty (sConfigPrefix, "ConfigPrefix");
+ ValueEnforcer.isTrue ( () -> StringHelper.endsWith (sConfigPrefix, '.'), "ConfigPrefix must end with a dot");
+
+ // Trust Store
+ final String sType = aConfig.getAsString (sConfigPrefix + "truststore.type");
+ final EKeyStoreType aType = EKeyStoreType.getFromIDCaseInsensitiveOrDefault (sType,
+ CAS4Crypto.DEFAULT_TRUST_STORE_TYPE);
+ final String sPath = aConfig.getAsString (sConfigPrefix + "truststore.file");
+ final char [] aPassword = aConfig.getAsCharArray (sConfigPrefix + "truststore.password");
+
+ return new AS4TrustStoreDescriptor (aType, sPath, aPassword, aProvider);
+ }
+}
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/AbstractAS4CryptoFactory.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/AbstractAS4CryptoFactory.java
index dc466ef4e..bffae0da4 100644
--- a/phase4-lib/src/main/java/com/helger/phase4/crypto/AbstractAS4CryptoFactory.java
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/AbstractAS4CryptoFactory.java
@@ -21,7 +21,6 @@
import javax.annotation.Nullable;
-import com.helger.commons.collection.ArrayHelper;
import com.helger.security.keystore.KeyStoreHelper;
/**
@@ -51,12 +50,8 @@ public KeyStore.PrivateKeyEntry getPrivateKeyEntry ()
return null;
final String sKeyAlias = getKeyAlias ();
- final String sKeyPassword = getKeyPasswordPerAlias (sKeyAlias);
- return KeyStoreHelper.loadPrivateKey (aKeyStore,
- "phase4 CryptoFactory KeyStore",
- sKeyAlias,
- sKeyPassword == null ? ArrayHelper.EMPTY_CHAR_ARRAY
- : sKeyPassword.toCharArray ())
+ final char [] aKeyPassword = getKeyPasswordPerAliasCharArray (sKeyAlias);
+ return KeyStoreHelper.loadPrivateKey (aKeyStore, "phase4 CryptoFactory KeyStore", sKeyAlias, aKeyPassword)
.getKeyEntry ();
}
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/CAS4Crypto.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/CAS4Crypto.java
new file mode 100644
index 000000000..4bf007c08
--- /dev/null
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/CAS4Crypto.java
@@ -0,0 +1,20 @@
+package com.helger.phase4.crypto;
+
+import javax.annotation.concurrent.Immutable;
+
+import com.helger.security.keystore.EKeyStoreType;
+
+/**
+ * Constant values for the AS4 cryptography.
+ *
+ * @author Philip Helger
+ */
+@Immutable
+public final class CAS4Crypto
+{
+ public static final EKeyStoreType DEFAULT_KEY_STORE_TYPE = EKeyStoreType.JKS;
+ public static final EKeyStoreType DEFAULT_TRUST_STORE_TYPE = EKeyStoreType.JKS;
+
+ private CAS4Crypto ()
+ {}
+}
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4CryptoFactory.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4CryptoFactory.java
index 469e01f1a..7454be3dd 100644
--- a/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4CryptoFactory.java
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4CryptoFactory.java
@@ -26,8 +26,8 @@
/**
* The basic phase4 crypto interface.
*
- * - See {@link AS4CryptoFactoryProperties} for an implementation of this
- * interface using a properties based approach
+ * - See {@link AS4CryptoFactoryConfiguration} for an implementation of this
+ * interface based on the global configuration
*
*
* @author Philip Helger
@@ -65,6 +65,19 @@ public interface IAS4CryptoFactory
@Nullable
String getKeyAlias ();
+ /**
+ * Returns the password for the key represented by the provided alias.
+ *
+ * @param sSearchKeyAlias
+ * The alias of the key whose password is to be retrieved.
+ * @return The password for the key represented by the provided by the alias
+ * or null
if the factory doesn't have a password for the
+ * key.
+ * @since 3.0.0
+ */
+ @Nullable
+ char [] getKeyPasswordPerAliasCharArray (@Nullable String sSearchKeyAlias);
+
/**
* Returns the password for the key represented by the provided alias.
*
@@ -76,7 +89,11 @@ public interface IAS4CryptoFactory
* @since 1.4.1
*/
@Nullable
- String getKeyPasswordPerAlias (@Nullable String sSearchKeyAlias);
+ default String getKeyPasswordPerAlias (@Nullable final String sSearchKeyAlias)
+ {
+ final char [] ret = getKeyPasswordPerAliasCharArray (sSearchKeyAlias);
+ return ret == null ? null : new String (ret);
+ }
/**
* @return The trust store to be used or null
if none is
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4KeyStoreDescriptor.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4KeyStoreDescriptor.java
new file mode 100644
index 000000000..db09117fd
--- /dev/null
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4KeyStoreDescriptor.java
@@ -0,0 +1,80 @@
+package com.helger.phase4.crypto;
+
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.Provider;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.helger.commons.annotation.Nonempty;
+import com.helger.security.keystore.IKeyStoreType;
+import com.helger.security.keystore.LoadedKey;
+import com.helger.security.keystore.LoadedKeyStore;
+
+/**
+ * Interface describing the parameters needed to reference a key store.
+ *
+ * @author Philip Helger
+ * @since 3.0.0
+ */
+public interface IAS4KeyStoreDescriptor
+{
+ /**
+ * @return The type of the key store. May not be null
.
+ */
+ @Nonnull
+ IKeyStoreType getKeyStoreType ();
+
+ /**
+ * @return The path to the key store. May neither be null
nor
+ * empty. The interpretation of the path is implementation dependent.
+ */
+ @Nonnull
+ @Nonempty
+ String getKeyStorePath ();
+
+ /**
+ * @return The password required to open the key store. May not be
+ * null
but may be empty.
+ */
+ @Nonnull
+ char [] getKeyStorePassword ();
+
+ /**
+ * @return The Java security provider for loading the key store. May be
+ * null
.
+ */
+ @Nullable
+ Provider getProvider ();
+
+ /**
+ * @return The loaded key store based on the parameters in this descriptor.
+ * Never null
.
+ */
+ @Nonnull
+ LoadedKeyStore loadKeyStore ();
+
+ /**
+ * Note: the case sensitivity of the key alias depends on the key store type.
+ *
+ * @return The alias of the key inside a key store. May neither be
+ * null
nor empty.
+ */
+ @Nonnull
+ @Nonempty
+ String getKeyAlias ();
+
+ /**
+ * @return The password required to access the key inside the key store. May
+ * not be null
but may be empty.
+ */
+ @Nonnull
+ char [] getKeyPassword ();
+
+ /**
+ * @return The loaded key based on the loaded key store and the parameters in
+ * this descriptor.
+ */
+ @Nonnull
+ LoadedKey loadKey ();
+}
diff --git a/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4TrustStoreDescriptor.java b/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4TrustStoreDescriptor.java
new file mode 100644
index 000000000..ae891ab30
--- /dev/null
+++ b/phase4-lib/src/main/java/com/helger/phase4/crypto/IAS4TrustStoreDescriptor.java
@@ -0,0 +1,54 @@
+package com.helger.phase4.crypto;
+
+import java.security.Provider;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.helger.commons.annotation.Nonempty;
+import com.helger.security.keystore.IKeyStoreType;
+import com.helger.security.keystore.LoadedKeyStore;
+
+/**
+ * Interface describing the parameters needed to reference a trust store.
+ *
+ * @author Philip Helger
+ * @since 3.0.0
+ */
+public interface IAS4TrustStoreDescriptor
+{
+ /**
+ * @return The type of the trust store. May not be null
.
+ */
+ @Nonnull
+ IKeyStoreType getTrustStoreType ();
+
+ /**
+ * @return The path to the trust store. May neither be null
nor
+ * empty. The interpretation of the path is implementation dependent.
+ */
+ @Nonnull
+ @Nonempty
+ String getTrustStorePath ();
+
+ /**
+ * @return The password required to open the trust store. May not be
+ * null
but may be empty.
+ */
+ @Nonnull
+ char [] getTrustStorePassword ();
+
+ /**
+ * @return The Java security provider for loading the trust store. May be
+ * null
.
+ */
+ @Nullable
+ Provider getProvider ();
+
+ /**
+ * @return The loaded trust store based on the parameters in this descriptor.
+ * Never null
.
+ */
+ @Nonnull
+ LoadedKeyStore loadTrustStore ();
+}
diff --git a/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java b/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java
index 0df2f217b..3250b3505 100644
--- a/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java
+++ b/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java
@@ -40,7 +40,7 @@
import com.helger.phase4.client.IAS4ClientBuildMessageCallback;
import com.helger.phase4.client.IAS4RetryCallback;
import com.helger.phase4.crypto.AS4CryptParams;
-import com.helger.phase4.crypto.AS4CryptoFactoryProperties;
+import com.helger.phase4.crypto.AS4CryptoFactoryConfiguration;
import com.helger.phase4.crypto.AS4SigningParams;
import com.helger.phase4.crypto.IAS4CryptoFactory;
import com.helger.phase4.crypto.IAS4DecryptParameterModifier;
@@ -114,7 +114,7 @@ protected AbstractAS4MessageBuilder ()
{
httpClientFactory (new HttpClientFactory ());
// By default set the same for sign and crypt
- cryptoFactory (AS4CryptoFactoryProperties.getDefaultInstance ());
+ cryptoFactory (AS4CryptoFactoryConfiguration.getDefaultInstance ());
soapVersion (ESoapVersion.SOAP_12);
pmodeResolver (DefaultPModeResolver.DEFAULT_PMODE_RESOLVER);
incomingAttachmentFactory (IAS4IncomingAttachmentFactory.DEFAULT_INSTANCE);
@@ -212,7 +212,7 @@ public final IAS4CryptoFactory cryptoFactorySign ()
/**
* Set the crypto factory to be used for signing. The default crypto factory
* is set in the constructor to
- * {@link AS4CryptoFactoryProperties#getDefaultInstance()}.
+ * {@link AS4CryptoFactoryConfiguration#getDefaultInstance()}.
*
* @param aCryptoFactorySign
* The crypto factory to be used. May be null
.
@@ -241,7 +241,7 @@ public final IAS4CryptoFactory cryptoFactoryCrypt ()
/**
* Set the crypto factory to be used for crypting. The default crypto factory
* is set in the constructor to
- * {@link AS4CryptoFactoryProperties#getDefaultInstance()}.
+ * {@link AS4CryptoFactoryConfiguration#getDefaultInstance()}.
*
* @param aCryptoFactoryCrypt
* The crypto factory to be used. May be null
.
@@ -258,7 +258,7 @@ public final IMPLTYPE cryptoFactoryCrypt (@Nullable final IAS4CryptoFactory aCry
/**
* Set the crypto factory to be used for signing and crypting. The default
* crypto factory is set in the constructor to
- * {@link AS4CryptoFactoryProperties#getDefaultInstance()}.
+ * {@link AS4CryptoFactoryConfiguration#getDefaultInstance()}.
*
* @param aCryptoFactory
* The crypto factory to be used. May be null
.
diff --git a/phase4-lib/src/main/java/com/helger/phase4/servlet/AS4XServletHandler.java b/phase4-lib/src/main/java/com/helger/phase4/servlet/AS4XServletHandler.java
index a6937572d..0a775f5d7 100644
--- a/phase4-lib/src/main/java/com/helger/phase4/servlet/AS4XServletHandler.java
+++ b/phase4-lib/src/main/java/com/helger/phase4/servlet/AS4XServletHandler.java
@@ -33,7 +33,7 @@
import com.helger.commons.mime.IMimeType;
import com.helger.http.EHttpVersion;
import com.helger.phase4.attachment.IAS4IncomingAttachmentFactory;
-import com.helger.phase4.crypto.AS4CryptoFactoryProperties;
+import com.helger.phase4.crypto.AS4CryptoFactoryConfiguration;
import com.helger.phase4.incoming.AS4IncomingMessageMetadata;
import com.helger.phase4.incoming.AS4IncomingReceiverConfiguration;
import com.helger.phase4.incoming.AS4RequestHandler;
@@ -206,7 +206,7 @@ protected void handleRequest (@Nonnull final IRequestWebScopeWithoutResponse aRe
try (final AS4RequestHandler aHandler = new AS4RequestHandler (aMessageMetadata))
{
// Set default values in handler
- aHandler.setCryptoFactory (AS4CryptoFactoryProperties.getDefaultInstance ());
+ aHandler.setCryptoFactory (AS4CryptoFactoryConfiguration.getDefaultInstance ());
aHandler.setPModeResolver (DefaultPModeResolver.DEFAULT_PMODE_RESOLVER);
aHandler.setIncomingAttachmentFactory (IAS4IncomingAttachmentFactory.DEFAULT_INSTANCE);
aHandler.setIncomingSecurityConfiguration (AS4IncomingSecurityConfiguration.createDefaultInstance ());
diff --git a/phase4-lib/src/test/java/com/helger/phase4/client/MainOldAS4Client.java b/phase4-lib/src/test/java/com/helger/phase4/client/MainOldAS4Client.java
index 63b81e471..0ca68d416 100644
--- a/phase4-lib/src/test/java/com/helger/phase4/client/MainOldAS4Client.java
+++ b/phase4-lib/src/test/java/com/helger/phase4/client/MainOldAS4Client.java
@@ -46,7 +46,7 @@
import com.helger.phase4.attachment.AS4OutgoingAttachment;
import com.helger.phase4.attachment.WSS4JAttachment;
import com.helger.phase4.crypto.AS4CryptParams;
-import com.helger.phase4.crypto.AS4CryptoFactoryProperties;
+import com.helger.phase4.crypto.AS4CryptoFactoryConfiguration;
import com.helger.phase4.crypto.AS4SigningParams;
import com.helger.phase4.crypto.IAS4CryptoFactory;
import com.helger.phase4.messaging.crypto.AS4Encryptor;
@@ -117,7 +117,7 @@ public static void main (final String [] args)
final ICommonsList aAttachments = new CommonsArrayList <> ();
final Node aPayload = DOMReader.readXMLDOM (new ClassPathResource ("SOAPBodyPayload.xml"));
final ESoapVersion eSoapVersion = ESoapVersion.SOAP_12;
- final IAS4CryptoFactory aCryptoFactory = AS4CryptoFactoryProperties.getDefaultInstance ();
+ final IAS4CryptoFactory aCryptoFactory = AS4CryptoFactoryConfiguration.getDefaultInstance ();
switch (4)
{
diff --git a/phase4-lib/src/test/java/com/helger/phase4/client/MockClientMessages.java b/phase4-lib/src/test/java/com/helger/phase4/client/MockClientMessages.java
index 04dddee68..6068a3771 100644
--- a/phase4-lib/src/test/java/com/helger/phase4/client/MockClientMessages.java
+++ b/phase4-lib/src/test/java/com/helger/phase4/client/MockClientMessages.java
@@ -31,7 +31,7 @@
import com.helger.commons.collection.impl.ICommonsList;
import com.helger.phase4.CAS4;
import com.helger.phase4.attachment.WSS4JAttachment;
-import com.helger.phase4.crypto.AS4CryptoFactoryProperties;
+import com.helger.phase4.crypto.AS4CryptoFactoryConfiguration;
import com.helger.phase4.crypto.AS4SigningParams;
import com.helger.phase4.ebms3header.Ebms3CollaborationInfo;
import com.helger.phase4.ebms3header.Ebms3Error;
@@ -71,7 +71,7 @@ public static Document createUserMessageSigned (@Nonnull final ESoapVersion eSoa
@Nonnull @WillNotClose final AS4ResourceHelper aResHelper) throws WSSecurityException
{
final AS4UserMessage aMsg = createUserMessageNotSigned (eSoapVersion, aPayload, aAttachments);
- return AS4Signer.createSignedMessage (AS4CryptoFactoryProperties.getDefaultInstance (),
+ return AS4Signer.createSignedMessage (AS4CryptoFactoryConfiguration.getDefaultInstance (),
aMsg.getAsSoapDocument (aPayload),
eSoapVersion,
aMsg.getMessagingID (),
@@ -90,7 +90,7 @@ public static Document createErrorMessageSigned (@Nonnull final ESoapVersion eSo
.build ());
final AS4ErrorMessage aErrorMsg = AS4ErrorMessage.create (eSoapVersion, "srcmsgid", aEbms3ErrorList)
.setMustUnderstand (true);
- final Document aSignedDoc = AS4Signer.createSignedMessage (AS4CryptoFactoryProperties.getDefaultInstance (),
+ final Document aSignedDoc = AS4Signer.createSignedMessage (AS4CryptoFactoryConfiguration.getDefaultInstance (),
aErrorMsg.getAsSoapDocument (),
eSoapVersion,
aErrorMsg.getMessagingID (),
@@ -115,10 +115,11 @@ public static Document createReceiptMessageSigned (@Nonnull final ESoapVersion e
null,
aUserMessage,
true,
- null).setMustUnderstand (true);
+ null)
+ .setMustUnderstand (true);
final Document aDoc = aReceiptMsg.getAsSoapDocument ();
- return AS4Signer.createSignedMessage (AS4CryptoFactoryProperties.getDefaultInstance (),
+ return AS4Signer.createSignedMessage (AS4CryptoFactoryConfiguration.getDefaultInstance (),
aDoc,
eSoapVersion,
aReceiptMsg.getMessagingID (),
@@ -162,7 +163,8 @@ public static AS4UserMessage createUserMessageNotSigned (@Nonnull final ESoapVer
aEbms3PartyInfo,
aEbms3MessageProperties,
null,
- eSoapVersion).setMustUnderstand (true);
+ eSoapVersion)
+ .setMustUnderstand (true);
return aDoc;
}
@@ -198,7 +200,8 @@ public static Document createUserMessageSoapNotSignedNotPModeConform (@Nonnull f
aEbms3PartyInfo,
aEbms3MessageProperties,
null,
- eSoapVersion).setMustUnderstand (true);
+ eSoapVersion)
+ .setMustUnderstand (true);
return aDoc.getAsSoapDocument (aPayload);
}
@@ -233,7 +236,8 @@ public static Document createEmptyUserMessage (@Nonnull final ESoapVersion eSoap
aEbms3PartyInfo,
aEbms3MessageProperties,
null,
- eSoapVersion).setMustUnderstand (true);
+ eSoapVersion)
+ .setMustUnderstand (true);
return aDoc.getAsSoapDocument (aPayload);
}
}
diff --git a/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderExpiredKeystore.java b/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderExpiredKeystore.java
index 131c38a45..2e6fc35bb 100644
--- a/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderExpiredKeystore.java
+++ b/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderExpiredKeystore.java
@@ -77,7 +77,7 @@ public static void main (final String [] args)
"peppol-expired-ap-cert-pw-peppol.p12",
"peppol"),
"cert",
- "peppol",
+ "peppol".toCharArray (),
KeyStoreHelper.loadKeyStore (PeppolKeyStoreHelper.TRUSTSTORE_TYPE,
PeppolKeyStoreHelper.Config2018.TRUSTSTORE_AP_PILOT_CLASSPATH,
PeppolKeyStoreHelper.TRUSTSTORE_PASSWORD)
diff --git a/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderInMemoryKeyStore.java b/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderInMemoryKeyStore.java
index cb74c910b..b88b7868d 100644
--- a/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderInMemoryKeyStore.java
+++ b/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderInMemoryKeyStore.java
@@ -24,6 +24,7 @@
import org.w3c.dom.Element;
import com.helger.peppol.sml.ESML;
+import com.helger.peppol.utils.PeppolKeyStoreHelper;
import com.helger.peppolid.IParticipantIdentifier;
import com.helger.phase4.crypto.AS4CryptoFactoryInMemoryKeyStore;
import com.helger.phase4.crypto.IAS4CryptoFactory;
@@ -62,13 +63,10 @@ public static void main (final String [] args)
final KeyStore aKS = KeyStoreHelper.loadKeyStoreDirect (EKeyStoreType.PKCS12, "test-ap.p12", "peppol");
if (aKS == null)
throw new IllegalStateException ();
- final KeyStore aTS = KeyStoreHelper.loadKeyStoreDirect (EKeyStoreType.JKS, "complete-truststore.jks", "peppol");
- if (aTS == null)
- throw new IllegalStateException ();
final IAS4CryptoFactory aInMemoryCryptoFactory = new AS4CryptoFactoryInMemoryKeyStore (aKS,
"openpeppol aisbl id von pop000306",
- "peppol",
- aTS);
+ "peppol".toCharArray (),
+ PeppolKeyStoreHelper.Config2018.TRUSTSTORE_AP_PILOT);
final EAS4UserMessageSendResult eResult;
eResult = Phase4PeppolSender.builder ()
.documentTypeID (Phase4PeppolSender.IF.createDocumentTypeIdentifierWithDefaultScheme ("urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1"))
diff --git a/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderNonPeppolKeystore.java b/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderNonPeppolKeystore.java
index 90d97d4ae..e711f1c08 100644
--- a/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderNonPeppolKeystore.java
+++ b/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/MainPhase4PeppolSenderNonPeppolKeystore.java
@@ -75,13 +75,10 @@ public static void main (final String [] args)
// Invalid certificate is valid until 2029
final IAS4CryptoFactory cf = new AS4CryptoFactoryInMemoryKeyStore (KeyStoreHelper.loadKeyStoreDirect (EKeyStoreType.JKS,
"invalid-keystore-pw-peppol.jks",
- "peppol"),
+ "peppol".toCharArray ()),
"1",
- "peppol",
- KeyStoreHelper.loadKeyStore (PeppolKeyStoreHelper.TRUSTSTORE_TYPE,
- PeppolKeyStoreHelper.Config2018.TRUSTSTORE_AP_PILOT_CLASSPATH,
- PeppolKeyStoreHelper.TRUSTSTORE_PASSWORD)
- .getKeyStore ());
+ "peppol".toCharArray (),
+ PeppolKeyStoreHelper.Config2018.TRUSTSTORE_AP_PILOT);
final EAS4UserMessageSendResult eResult;
eResult = Phase4PeppolSender.builder ()
diff --git a/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/receivers/MainPhase4PeppolSenderQvalia.java b/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/receivers/MainPhase4PeppolSenderQvalia.java
index e7db50bf8..151de8bd9 100644
--- a/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/receivers/MainPhase4PeppolSenderQvalia.java
+++ b/phase4-peppol-client/src/test/java/com/helger/phase4/peppol/receivers/MainPhase4PeppolSenderQvalia.java
@@ -106,7 +106,7 @@ public void onAS4Message (final AbstractAS4Message > aMsg)
"invalid-keystore-pw-peppol.jks",
"peppol"),
"1",
- "peppol",
+ "peppol".toCharArray (),
KeyStoreHelper.loadKeyStore (PeppolKeyStoreHelper.TRUSTSTORE_TYPE,
PeppolKeyStoreHelper.Config2018.TRUSTSTORE_AP_PRODUCTION_CLASSPATH,
PeppolKeyStoreHelper.TRUSTSTORE_PASSWORD)
diff --git a/phase4-test/src/test/java/com/helger/phase4/ScopedAS4Configuration.java b/phase4-test/src/test/java/com/helger/phase4/ScopedAS4Configuration.java
index e7c6d4ab5..796ff2526 100644
--- a/phase4-test/src/test/java/com/helger/phase4/ScopedAS4Configuration.java
+++ b/phase4-test/src/test/java/com/helger/phase4/ScopedAS4Configuration.java
@@ -23,8 +23,9 @@
import com.helger.commons.collection.attr.IStringMap;
import com.helger.commons.io.resource.FileSystemResource;
import com.helger.commons.io.resource.IReadableResource;
-import com.helger.config.Config;
import com.helger.config.IConfig;
+import com.helger.config.fallback.ConfigWithFallback;
+import com.helger.config.fallback.IConfigWithFallback;
import com.helger.config.source.EConfigSourceType;
import com.helger.config.source.MultiConfigurationValueProvider;
import com.helger.config.source.appl.ConfigurationSourceFunction;
@@ -42,9 +43,9 @@ public final class ScopedAS4Configuration implements AutoCloseable
{
private static final String TEST_CONFIG_FILE = "src/test/resources/test-phase4.properties";
- private final IConfig m_aOldConfig;
+ private final IConfigWithFallback m_aOldConfig;
- private ScopedAS4Configuration (@Nonnull final IConfig aConfig)
+ private ScopedAS4Configuration (@Nonnull final IConfigWithFallback aConfig)
{
m_aOldConfig = AS4Configuration.setConfig (aConfig);
}
@@ -61,7 +62,7 @@ public static ScopedAS4Configuration create (@Nonnull final IStringMap aMap)
final MultiConfigurationValueProvider aVP = AS4Configuration.createPhase4ValueProvider ();
aVP.addConfigurationSource (new ConfigurationSourceFunction (aMap::getAsString),
EConfigSourceType.RESOURCE.getDefaultPriority () + 20);
- return new ScopedAS4Configuration (new Config (aVP));
+ return new ScopedAS4Configuration (new ConfigWithFallback (aVP));
}
@Nonnull
@@ -74,7 +75,7 @@ public static ScopedAS4Configuration create (@Nonnull final IReadableResource aR
// By default priority must be higher than the default
aVP.addConfigurationSource (new ConfigurationSourceProperties (aRes),
EConfigSourceType.RESOURCE.getDefaultPriority () + 10);
- return new ScopedAS4Configuration (new Config (aVP));
+ return new ScopedAS4Configuration (new ConfigWithFallback (aVP));
}
@Nonnull
@@ -91,6 +92,6 @@ public static ScopedAS4Configuration createTestConfig (@Nonnull final IStringMap
EConfigSourceType.RESOURCE.getDefaultPriority () + 20);
aVP.addConfigurationSource (new ConfigurationSourceProperties (new FileSystemResource (TEST_CONFIG_FILE)),
EConfigSourceType.RESOURCE.getDefaultPriority () + 10);
- return new ScopedAS4Configuration (new Config (aVP));
+ return new ScopedAS4Configuration (new ConfigWithFallback (aVP));
}
}