Skip to content

Commit

Permalink
AS4RequestHandler: Different keystores for decryption and signing of…
Browse files Browse the repository at this point in the history
… response message #139
  • Loading branch information
sopgreg committed Jun 29, 2023
1 parent d339c0e commit e7c8c04
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import javax.annotation.Nullable;
import javax.annotation.WillClose;

import com.helger.phase4.crypto.IAS4PModeAwareCryptoFactory;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.slf4j.Logger;
Expand Down Expand Up @@ -360,6 +361,7 @@ public boolean hasAsyncResponseURL ()

private final AS4ResourceHelper m_aResHelper;
private final IAS4CryptoFactory m_aCryptoFactory;
private final IAS4CryptoFactory m_aResponseCryptoFactory;
private final IPModeResolver m_aPModeResolver;
private final IAS4IncomingAttachmentFactory m_aIAF;
private IAS4IncomingProfileSelector m_aIncomingProfileSelector = AS4IncomingProfileSelectorFromGlobal.INSTANCE;
Expand All @@ -378,14 +380,25 @@ public AS4RequestHandler (@Nonnull final IAS4CryptoFactory aCryptoFactory,
@Nonnull final IPModeResolver aPModeResolver,
@Nonnull final IAS4IncomingAttachmentFactory aIAF,
@Nonnull final IAS4IncomingMessageMetadata aMessageMetadata)
{
this(aCryptoFactory, aCryptoFactory, aPModeResolver, aIAF, aMessageMetadata);
}

public AS4RequestHandler (@Nonnull final IAS4CryptoFactory aCryptoFactory,
@Nonnull final IAS4CryptoFactory aResponseCryptoFactory,
@Nonnull final IPModeResolver aPModeResolver,
@Nonnull final IAS4IncomingAttachmentFactory aIAF,
@Nonnull final IAS4IncomingMessageMetadata aMessageMetadata)
{
ValueEnforcer.notNull (aCryptoFactory, "CryptoFactory");
ValueEnforcer.notNull (aResponseCryptoFactory, "ResponseCryptoFactory");
ValueEnforcer.notNull (aPModeResolver, "PModeResolver");
ValueEnforcer.notNull (aIAF, "IAF");
ValueEnforcer.notNull (aMessageMetadata, "MessageMetadata");
// Create dynamically here, to avoid leaving too many streams open
m_aResHelper = new AS4ResourceHelper ();
m_aCryptoFactory = aCryptoFactory;
m_aResponseCryptoFactory = aResponseCryptoFactory;
m_aPModeResolver = aPModeResolver;
m_aIAF = aIAF;
m_aMessageMetadata = aMessageMetadata;
Expand Down Expand Up @@ -1089,7 +1102,7 @@ private Document _signResponseIfNeeded (@Nullable final ICommonsList <WSS4JAttac
{
// Sign
final boolean bMustUnderstand = true;
ret = AS4Signer.createSignedMessage (m_aCryptoFactory,
ret = AS4Signer.createSignedMessage (m_aResponseCryptoFactory,
aDocToBeSigned,
eSoapVersion,
sMessagingID,
Expand Down Expand Up @@ -1201,7 +1214,7 @@ private AS4MimeMessage _createMimeMessageForResponse (@Nonnull final Document aR
aMimeMsg = AS4Encryptor.encryptMimeMessage (eSoapVersion,
aResponseDoc,
aResponseAttachments,
m_aCryptoFactory,
m_aResponseCryptoFactory,
bMustUnderstand,
m_aResHelper,
aCryptParms);
Expand Down Expand Up @@ -1298,6 +1311,13 @@ private IAS4ResponseFactory _handleSoapMessage (@Nonnull final HttpHeaderMap aHt
m_aIncomingProfileSelector,
aErrorMessagesTarget);
final IPMode aPMode = aState.getPMode ();

// response CryptoFactory might also be dependent on the detected PMode, assign it
if (aPMode != null && m_aResponseCryptoFactory instanceof IAS4PModeAwareCryptoFactory)
{
((IAS4PModeAwareCryptoFactory) m_aResponseCryptoFactory).setContextPMode (aPMode);
}

final PModeLeg aEffectiveLeg = aState.getEffectivePModeLeg ();
final String sMessageID = aState.getMessageID ();
final ICommonsList <WSS4JAttachment> aDecryptedAttachments = aState.hasDecryptedAttachments () ? aState.getDecryptedAttachments ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ default void customizeAfterHandling (@Nonnull final IRequestWebScopeWithoutRespo
private static final Logger LOGGER = LoggerFactory.getLogger (AS4XServletHandler.class);

private Supplier <? extends IAS4CryptoFactory> m_aCryptoFactorySupplier;
private Supplier <? extends IAS4CryptoFactory> m_aResponseCryptoFactorySupplier;
private IPModeResolver m_aPModeResolver;
private IAS4IncomingAttachmentFactory m_aIAF;
private IHandlerCustomizer m_aHandlerCustomizer;
Expand Down Expand Up @@ -118,8 +119,31 @@ public AS4XServletHandler ()
public AS4XServletHandler (@Nonnull final Supplier <? extends IAS4CryptoFactory> aCryptoFactorySupplier,
@Nonnull final IPModeResolver aPModeResolver,
@Nonnull final IAS4IncomingAttachmentFactory aIAF)
{
this(aCryptoFactorySupplier, aCryptoFactorySupplier, aPModeResolver, aIAF);
}

/**
* Constructor
*
* @param aCryptoFactorySupplier
* Crypto factory supplier. May not be <code>null</code>.
* @param aResponseCryptoFactorySupplier
* Crypto factory supplier for response messages. May not be <code>null</code>.
* @param aPModeResolver
* PMode resolved to be used. May not be <code>null</code>.
* @param aIAF
* The attachment factory for incoming attachments. May not be
* <code>null</code>.
* @since v0.9.8
*/
public AS4XServletHandler (@Nonnull final Supplier <? extends IAS4CryptoFactory> aCryptoFactorySupplier,
@Nonnull final Supplier <? extends IAS4CryptoFactory> aResponseCryptoFactorySupplier,
@Nonnull final IPModeResolver aPModeResolver,
@Nonnull final IAS4IncomingAttachmentFactory aIAF)
{
setCryptoFactorySupplier (aCryptoFactorySupplier);
setResponseCryptoFactorySupplier (aResponseCryptoFactorySupplier);
setPModeResolver (aPModeResolver);
setIncomingAttachmentFactory (aIAF);
}
Expand Down Expand Up @@ -149,6 +173,31 @@ public final AS4XServletHandler setCryptoFactorySupplier (@Nonnull final Supplie
return this;
}

/**
* @return The supplier for the {@link IAS4CryptoFactory} for response messages. May not be
* <code>null</code>.
* @since x.x.x
*/
@Nonnull
public final Supplier <? extends IAS4CryptoFactory> getResponseCryptoFactorySupplier ()
{
return m_aResponseCryptoFactorySupplier;
}

/**
* @param aResponseCryptoFactorySupplier
* Crypto factory supplier for response messages. May not be <code>null</code>.
* @return this for chaining
* @since x.x.x
*/
@Nonnull
public final AS4XServletHandler setResponseCryptoFactorySupplier (@Nonnull final Supplier <? extends IAS4CryptoFactory> aResponseCryptoFactorySupplier)
{
ValueEnforcer.notNull (aResponseCryptoFactorySupplier, "ResponseCryptoFactorySupplier");
m_aResponseCryptoFactorySupplier = aResponseCryptoFactorySupplier;
return this;
}

/**
* @return The {@link IPModeResolver} to be used. Never <code>null</code>.
* @since 0.9.15
Expand Down Expand Up @@ -287,14 +336,15 @@ protected AS4IncomingMessageMetadata createIncomingMessageMetadata (@Nonnull fin
protected void handleRequest (@Nonnull final IRequestWebScopeWithoutResponse aRequestScope,
@Nonnull final AS4UnifiedResponse aHttpResponse,
@Nonnull final IAS4CryptoFactory aCF,
@Nonnull final IAS4CryptoFactory aResponseCF,
@Nonnull final IPModeResolver aPModeResolver,
@Nonnull final IAS4IncomingAttachmentFactory aIAF,
@Nullable final IHandlerCustomizer aHandlerCustomizer) throws Exception
{
// Start metadata
final IAS4IncomingMessageMetadata aMessageMetadata = createIncomingMessageMetadata (aRequestScope);

try (final AS4RequestHandler aHandler = new AS4RequestHandler (aCF, aPModeResolver, aIAF, aMessageMetadata))
try (final AS4RequestHandler aHandler = new AS4RequestHandler (aCF, aResponseCF, aPModeResolver, aIAF, aMessageMetadata))
{
// Customize before handling
if (aHandlerCustomizer != null)
Expand Down Expand Up @@ -337,13 +387,18 @@ public void handleRequest (@Nonnull final IRequestWebScopeWithoutResponse aReque
{
// Resolved once per request
final IAS4CryptoFactory aCF = m_aCryptoFactorySupplier.get ();
// Fallback to regular CryptoFactory if no specific CryptoFactory for response messages was provided
final IAS4CryptoFactory aResponseCF = (m_aResponseCryptoFactorySupplier != null) ? m_aResponseCryptoFactorySupplier.get () : aCF;
if (aCF == null)
throw new IllegalStateException ("Failed to get an AS4 CryptoFactory");
if (aResponseCF == null)
throw new IllegalStateException ("Failed to get an AS4 response CryptoFactory");

// Created above in #createUnifiedResponse
handleRequest (aRequestScope,
(AS4UnifiedResponse) aUnifiedResponse,
aCF,
aResponseCF,
m_aPModeResolver,
m_aIAF,
m_aHandlerCustomizer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ public MyAS4Servlet ()
settings ().setMultipartEnabled (false);
// HTTP POST only
final AS4XServletHandler hdl = new AS4XServletHandler ();
// This method refers to the outer static methid
// This method refers to the outer static method
hdl.setCryptoFactorySupplier (ServletConfig::getCryptoFactoryToUse);
hdl.setResponseCryptoFactorySupplier (ServletConfig::getCryptoFactoryToUse);
handlerRegistry ().registerHandler (EHttpMethod.POST, hdl);
}
}
Expand Down

0 comments on commit e7c8c04

Please sign in to comment.