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)); } }