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 0635abf4..e16d5e3c 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 @@ -45,6 +45,8 @@ import com.helger.phase4.client.AS4ClientSentMessage; import com.helger.phase4.crypto.AS4CryptoFactoryProperties; import com.helger.phase4.crypto.AS4CryptoProperties; +import com.helger.phase4.crypto.ECryptoAlgorithmC14N; +import com.helger.phase4.crypto.ECryptoKeyEncryptionAlgorithm; import com.helger.phase4.dump.AS4DumpManager; import com.helger.phase4.dump.AS4IncomingDumperFileBased; import com.helger.phase4.dump.AS4OutgoingDumperFileBased; @@ -55,9 +57,13 @@ import com.helger.phase4.model.error.EEbmsError; import com.helger.phase4.model.mpc.IMPCManager; import com.helger.phase4.model.mpc.MPC; +import com.helger.phase4.model.pmode.IPMode; +import com.helger.phase4.model.pmode.leg.PModeLeg; import com.helger.phase4.profile.euctp.EEuCtpAction; import com.helger.phase4.profile.euctp.EEuCtpService; import com.helger.phase4.profile.euctp.EuCtpPMode; +import com.helger.phase4.sender.AbstractAS4MessageBuilder; +import com.helger.phase4.sender.AbstractAS4UserMessageBuilder; import com.helger.phase4.sender.EAS4UserMessageSendResult; import com.helger.phase4.util.AS4ResourceHelper; import com.helger.phase4.util.Phase4Exception; @@ -193,58 +199,102 @@ private static void _sendPullRequest (final Phase4EuCtpHttpClientSettings aHttpC if (eSuccess.isSuccess () && aUserMessageHolder.isSet ()) { - // Send another Receipt - final Ebms3UserMessage aUserMessage = aUserMessageHolder.get (); - final String sUserMessageID = aUserMessage.getMessageInfo ().getMessageId (); - try (final AS4ResourceHelper aResHelper = new AS4ResourceHelper ()) + _sendReceipt(aUserMessageHolder, aSoapDocHolder, prBuilder); + } + } + + private static void _sendReceipt(Wrapper aUserMessageHolder, Wrapper aSoapDocHolder, EuCtpPullRequestBuilder prBuilder) + { + // Send another Receipt + final Ebms3UserMessage aUserMessage = aUserMessageHolder.get (); + final String sUserMessageID = aUserMessage.getMessageInfo ().getMessageId (); + try (final AS4ResourceHelper aResHelper = new AS4ResourceHelper ()) + { + final AS4ClientSentMessage aSentMessage; + // TODO decide what to do + if (true) { - final AS4ClientSentMessage aSentMessage; - // TODO decide what to do - if (true) + // receipt + final AS4ClientReceiptMessage aReceiptMessage = new AS4ClientReceiptMessage (aResHelper); + aReceiptMessage.setRefToMessageID(sUserMessageID); + aReceiptMessage.setNonRepudiation(EuCtpPMode.DEFAULT_SEND_RECEIPT_NON_REPUDIATION); + aReceiptMessage.setSoapDocument(aSoapDocHolder.get()); + aReceiptMessage.setReceiptShouldBeSigned(true); + aReceiptMessage.getHttpPoster().setHttpClientFactory(prBuilder.httpClientFactory()); + aReceiptMessage.setCryptoFactorySign(prBuilder.cryptoFactorySign()); + aReceiptMessage.setCryptoFactoryCrypt(prBuilder.cryptoFactoryCrypt()); + aReceiptMessage.setEbms3UserMessage(aUserMessage); + + IPMode aPMode = prBuilder.pmode(); + if (aPMode != null) { - // receipt - final AS4ClientReceiptMessage aReceiptMessage = new AS4ClientReceiptMessage (aResHelper); - aReceiptMessage.setRefToMessageID (sUserMessageID); - aReceiptMessage.setNonRepudiation (EuCtpPMode.DEFAULT_SEND_RECEIPT_NON_REPUDIATION); - aReceiptMessage.setSoapDocument (aSoapDocHolder.get ()); - aReceiptMessage.setReceiptShouldBeSigned (true); - aReceiptMessage.getHttpPoster ().setHttpClientFactory (prBuilder.httpClientFactory ()); - prBuilder.signingParams ().cloneTo (aReceiptMessage.signingParams ()); - aSentMessage = aReceiptMessage.sendMessageWithRetries (prBuilder.endpointURL (), - new ResponseHandlerByteArray (), - prBuilder.buildMessageCallback (), - prBuilder.outgoingDumper (), - prBuilder.retryCallback ()); + final PModeLeg aEffectiveLeg = prBuilder.useLeg1() ? aPMode.getLeg1() : aPMode.getLeg2(); + aReceiptMessage.signingParams().setFromPMode(aEffectiveLeg.getSecurity()); } - else - { - // error - final AS4ClientErrorMessage aErrorMessage = new AS4ClientErrorMessage (aResHelper); - aErrorMessage.errorMessages () - .add (EEbmsError.EBMS_OTHER.errorBuilder (Locale.US) - .refToMessageInError (sUserMessageID) - .errorDetail ("This is why it failed") - .build ()); - aErrorMessage.setRefToMessageID (sUserMessageID); - aErrorMessage.setErrorShouldBeSigned (true); - aErrorMessage.getHttpPoster ().setHttpClientFactory (prBuilder.httpClientFactory ()); - prBuilder.signingParams ().cloneTo (aErrorMessage.signingParams ()); - aSentMessage = aErrorMessage.sendMessageWithRetries (prBuilder.endpointURL (), + + aReceiptMessage.cryptParams ().setKeyIdentifierType (AbstractEuCtpUserMessageBuilder.DEFAULT_KEY_IDENTIFIER_TYPE_CRYPT); + aReceiptMessage.cryptParams ().setKeyEncAlgorithm (ECryptoKeyEncryptionAlgorithm.ECDH_ES_KEYWRAP_AES_128); + aReceiptMessage.cryptParams ().setEncryptSymmetricSessionKey (false); + + // Other signing parameters are located in the PMode security part + aReceiptMessage.signingParams ().setKeyIdentifierType (AbstractEuCtpUserMessageBuilder.DEFAULT_KEY_IDENTIFIER_TYPE_SIGN); + aReceiptMessage.signingParams ().setAlgorithmC14N (ECryptoAlgorithmC14N.C14N_EXCL_OMIT_COMMENTS); + // Use the BST value type "#X509PKIPathv1" + aReceiptMessage.signingParams ().setUseSingleCertificate (false); + + aSentMessage = aReceiptMessage.sendMessageWithRetries (prBuilder.endpointURL (), new ResponseHandlerByteArray (), prBuilder.buildMessageCallback (), prBuilder.outgoingDumper (), prBuilder.retryCallback ()); - } - - if (aSentMessage.hasResponseStatusLine ()) - LOGGER.info ("Receipt response: " + aSentMessage.getResponseStatusLine ()); - if (aSentMessage.hasResponseContent ()) - LOGGER.info ("Receipt content length: " + aSentMessage.getResponseContent ().length); } - catch (IOException | WSSecurityException | MessagingException ex) + else { - LOGGER.error ("Failed to send back Error/Receipt", ex); + // error + final AS4ClientErrorMessage aErrorMessage = new AS4ClientErrorMessage (aResHelper); + aErrorMessage.errorMessages () + .add (EEbmsError.EBMS_OTHER.errorBuilder (Locale.US) + .refToMessageInError (sUserMessageID) + .errorDetail ("This is why it failed") + .build ()); + aErrorMessage.setRefToMessageID (sUserMessageID); + aErrorMessage.setErrorShouldBeSigned (true); + aErrorMessage.getHttpPoster ().setHttpClientFactory (prBuilder.httpClientFactory ()); + aErrorMessage.setCryptoFactorySign(prBuilder.cryptoFactorySign()); + aErrorMessage.setCryptoFactoryCrypt(prBuilder.cryptoFactoryCrypt()); + + IPMode aPMode = prBuilder.pmode(); + if (aPMode != null) + { + final PModeLeg aEffectiveLeg = prBuilder.useLeg1() ? aPMode.getLeg1() : aPMode.getLeg2(); + aErrorMessage.signingParams().setFromPMode(aEffectiveLeg.getSecurity()); + } + + aErrorMessage.cryptParams ().setKeyIdentifierType (AbstractEuCtpUserMessageBuilder.DEFAULT_KEY_IDENTIFIER_TYPE_CRYPT); + aErrorMessage.cryptParams ().setKeyEncAlgorithm (ECryptoKeyEncryptionAlgorithm.ECDH_ES_KEYWRAP_AES_128); + aErrorMessage.cryptParams ().setEncryptSymmetricSessionKey (false); + + // Other signing parameters are located in the PMode security part + aErrorMessage.signingParams ().setKeyIdentifierType (AbstractEuCtpUserMessageBuilder.DEFAULT_KEY_IDENTIFIER_TYPE_SIGN); + aErrorMessage.signingParams ().setAlgorithmC14N (ECryptoAlgorithmC14N.C14N_EXCL_OMIT_COMMENTS); + // Use the BST value type "#X509PKIPathv1" + aErrorMessage.signingParams ().setUseSingleCertificate (false); + + aSentMessage = aErrorMessage.sendMessageWithRetries (prBuilder.endpointURL (), + new ResponseHandlerByteArray (), + prBuilder.buildMessageCallback (), + prBuilder.outgoingDumper (), + prBuilder.retryCallback ()); } + + if (aSentMessage.hasResponseStatusLine ()) + LOGGER.info ("Receipt response: " + aSentMessage.getResponseStatusLine ()); + if (aSentMessage.hasResponseContent ()) + LOGGER.info ("Receipt content length: " + aSentMessage.getResponseContent ().length); + } + catch (IOException | WSSecurityException | MessagingException ex) + { + LOGGER.error ("Failed to send back Error/Receipt", ex); } } diff --git a/phase4-profile-euctp/src/main/java/com/helger/phase4/profile/euctp/EuCtpCompatibilityValidator.java b/phase4-profile-euctp/src/main/java/com/helger/phase4/profile/euctp/EuCtpCompatibilityValidator.java index 1449df9f..f6833b5b 100644 --- a/phase4-profile-euctp/src/main/java/com/helger/phase4/profile/euctp/EuCtpCompatibilityValidator.java +++ b/phase4-profile-euctp/src/main/java/com/helger/phase4/profile/euctp/EuCtpCompatibilityValidator.java @@ -268,7 +268,8 @@ public void validatePMode (@Nonnull final IPMode aPMode, final EMEP eMEP = aPMode.getMEP (); final EMEPBinding eMEPBinding = aPMode.getMEPBinding (); - if (eMEP == EMEP.ONE_WAY && eMEPBinding == EMEPBinding.PUSH) + if (eMEP == EMEP.ONE_WAY + && (eMEPBinding == EMEPBinding.PUSH || eMEPBinding == EMEPBinding.PULL)) { // Valid } @@ -278,7 +279,7 @@ public void validatePMode (@Nonnull final IPMode aPMode, eMEP + ") and MEP binding (" + eMEPBinding + - ") was specified, only one-way/push is valid.")); + ") was specified, only one-way/push/pull is valid.")); } // Leg1 must be present diff --git a/phase4-profile-euctp/src/main/java/com/helger/phase4/profile/euctp/EuCtpPMode.java b/phase4-profile-euctp/src/main/java/com/helger/phase4/profile/euctp/EuCtpPMode.java index fb10dc24..b1f4a761 100644 --- a/phase4-profile-euctp/src/main/java/com/helger/phase4/profile/euctp/EuCtpPMode.java +++ b/phase4-profile-euctp/src/main/java/com/helger/phase4/profile/euctp/EuCtpPMode.java @@ -251,7 +251,7 @@ public static PMode createEuCtpPullPMode (@Nonnull @Nonempty final String sIniti EMEP.ONE_WAY, EMEPBinding.PULL, generatePModeLeg (sAddress), - null, + generatePModeLeg (sAddress), generatePModePayloadService (), generatePModeReceptionAwareness ());