Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to enforce signature and encryption for receiving messages? #162

Closed
phax opened this issue Aug 29, 2023 Discussed in #161 · 9 comments
Closed

How to enforce signature and encryption for receiving messages? #162

phax opened this issue Aug 29, 2023 Discussed in #161 · 9 comments
Assignees
Labels

Comments

@phax
Copy link
Owner

phax commented Aug 29, 2023

Discussed in #161

Originally posted by sopgreg August 29, 2023
Is there a way to enforce a (valid) signature and encryption in the receiving AS4 message? Right now, it seems that it's possible to send a completely unencrypted, unsigned message to the AS4IncomingHandler and it will process the message without any warnings.

Is there an interface/propery to enforce signatures and encryption?

E.g. here, if the SOAP does not contain a Security element, this is just logged in debug mode.

grafik

@phax phax added Profile BDEW BDEW AS4 related enhancement labels Aug 29, 2023
@phax phax self-assigned this Aug 29, 2023
@phax
Copy link
Owner Author

phax commented Sep 14, 2023

@sopgreg what you can do today already, is to query the signature and decryption state in your code via the IAS4MessageState:

  • aState.isSoapSignatureChecked () returns true if the message was signed
  • aState.isSoapDecrypted() returns true if the message was decrypted

@sopgreg
Copy link
Contributor

sopgreg commented Sep 15, 2023

Thanks @phax! I put this in our IAS4ServletMessageProcessorSPI#processAS4UserMessage. Would that be a "correct" implementation where the sender receives the proper reason for failed processing of his message?

if (!messageState.isSoapDecrypted()) {
    processingErrorMessages.add(EEbmsError.EBMS_FAILED_DECRYPTION.getAsEbms3Error(Locale.getDefault(), null));

    String errorMessage = String.format("Incoming AS4 message from %s to %s was not encrypted",
                                        initiatorID, responderID);
    LOGGER.error(errorMessage);
    return AS4MessageProcessorResult.createFailure(errorMessage);
}

if (!messageState.isSoapSignatureChecked()) {
    processingErrorMessages.add(EEbmsError.EBMS_FAILED_AUTHENTICATION.getAsEbms3Error(Locale.getDefault(), null));

    String errorMessage = String.format("Incoming AS4 message from %s to %s had no signature or signature verification failed",
                                        initiatorID, responderID);
    LOGGER.error(errorMessage);
    return AS4MessageProcessorResult.createFailure(errorMessage);
}

The usage of both the processingErrorMessages and the error message in createFailure seems a bit redundant to me. Is there a variant you would recommend?

@phax
Copy link
Owner Author

phax commented Sep 15, 2023

Yes that looks good. I am working on an additional "profile requirement" to make that check on a deeper level automatically as you suggested.
Additionally your comment on AS4MessageProcessorResult.createFailure(errorMessage); is totally right. As this messgae is never used, it will be also be deprecated in the upcoming release. processingErrorMessages is the way to go

@phax
Copy link
Owner Author

phax commented Sep 15, 2023

Regarding the error code I would vouch for EBMS:0103:
grafik

@sopgreg
Copy link
Contributor

sopgreg commented Sep 15, 2023

Regarding the error code I would vouch for EBMS:0103:

EBMS:0103 sounds fine, thanks.

Additionally your comment on AS4MessageProcessorResult.createFailure(errorMessage); is totally right. As this messgae is never used, it will be also be deprecated in the upcoming release. processingErrorMessages is the way to go

I actually do like the error message in AS4MessageProcessorResult.createFailure(errorMessage) as it is automatically mapped to an Ebms error with a correct refToMessageInError in AS4RequestHandler:

grafik

There is no easy way to get that refToMessageInError in the SPI, is there? Apart from copying the same code from AS4RequestHandler:

final String sMessageID = bIsUserMessage ? aEbmsUserMessage.getMessageInfo ().getMessageId () : aEbmsSignalMessage
                                                                                                                      .getMessageInfo ()
                                                                                                                      .getMessageId ();

EDIT: seems that messageState.getMessage() seems to be the way to go.

Yes that looks good. I am working on an additional "profile requirement" to make that check on a deeper level automatically as you suggested.

Great if this can be handled on a deeper level, then we could remove our code in the SPI again later.

@phax
Copy link
Owner Author

phax commented Sep 15, 2023

To access the "RefToMessageID" please use

String IAS4MessageState.getRefToMessageID ();

The problem with the createFailure(String) is, that it allows only 1 error message. In some cases multiple error messages make sense. And as I consider it bad style to offer the same functionality in 2 different ways, I opt for the generic one using processingErrorMessages.add (...)

@phax
Copy link
Owner Author

phax commented Sep 15, 2023

@sopgreg I thought this through a little more and I stumbled upon an issue we haven't considered previously: when making the decision in the profile, it means that this applies to ALL messages. As Receipts may not be encrypted and Error Messages may not even be signed, I decided to remove this feature from the release.
Having the check in your "User Message Receiption" code is the safest atm.

It would be an option to configure this requirement in the PMode on a per message type basis (UserMessage, PullRequest, Error, Receipt), but that looks like too much overhead. Any thoughts from you on this?

@sopgreg
Copy link
Contributor

sopgreg commented Sep 15, 2023

I also can't image all possible combinations right now when and under which circumstances a response message may or may not be signed/encrypted. At least for BDEW, PullRequests are out of scope. So any UserMessage and all signal that do not contain errors should be technically signed and encrypted. Is this assumption correct or did I miss some edge cases?

To access the "RefToMessageID" please use
String IAS4MessageState.getRefToMessageID ();

In the code you committed today you used #getMessageId. Was this on purpose or is getRefToMessageId the correct one?

@phax
Copy link
Owner Author

phax commented Sep 15, 2023

Okay, thanks for your understanding.

getMessageId() is used to get the message ID of the currently processed message.

getRefToMessageId() is used in Receipt or Error Messages to refence the MessageId of the source message. So the answer message referring to the source message.

When dealing with the "source user message" getMessageId() is what you are looking for

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants