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

allow configuration of which base64-encoding scheme to use for outbound messages #36

Merged
merged 4 commits into from
Feb 16, 2024

Conversation

alexdean
Copy link
Owner

@alexdean alexdean commented Feb 5, 2024

up to this point we have always used Base64.strict_encode64, which is RFC-4648 rules.

a partner using MuleSoft AS2 was unable to successfully receive messages encoded this way. they are able to receive messages encoded using RFC-2045 rules, which is Base64.encode64 in ruby.

differences between the 2 schemes

There are differences in the exact alphabet of characters used, but for our purposes the most important difference is this:

RFC-2045 specifies a maximum line length of 78 characters. \n is inserted between 78-character segments to form the final output.

The encoded output stream must be represented in lines of no more
than 76 characters each.
https://datatracker.ietf.org/doc/html/rfc2045#section-6.8

RFC-4648 does not have any requirement to break lines, so does not insert any \n characters.

Effects on MIC calculation

MIC values must be calculated on canonicalized message bodies.

For any signed messages, the MIC to be returned is calculated on the RFC1767 /RFC3023 MIME header and content. Canonicalization on the MIME headers MUST be performed before the MIC is calculated, since the sender requesting the signed receipt was also REQUIRED to canonicalize.

https://datatracker.ietf.org/doc/html/rfc4130#section-7.3.1

This means we must replace the \n in any RFC-2045 encoded text with \r\n in order to calculate a correct MIC value. This canonicalization (via regex) was already being performed in a few other places in the codebase, so this has been extracted into a new As2.canonicalize_line_endings method for clarity.

  * encode64: "This method complies with RFC 2045"
  * strict_encode64: "This method complies with RFC 4648. No line feeds are added."

https://ruby-doc.org/stdlib-3.0.4/libdoc/base64/rdoc/Base64.html
@alexdean alexdean self-assigned this Feb 5, 2024
@alexdean alexdean changed the title use RFC-2045 rather than RFC-2628 rules for base64 encoding allow configuration of which base64-encoding scheme to use for outbound messages Feb 14, 2024
@alexdean alexdean marked this pull request as ready for review February 16, 2024 20:14
@@ -172,7 +172,7 @@ def format_body_v0(document_content, content_type:, file_name:)
document_payload << "Content-Transfer-Encoding: base64\r\n"
document_payload << "Content-Disposition: attachment; filename=#{file_name}\r\n"
document_payload << "\r\n"
document_payload << Base64.strict_encode64(document_content)
document_payload << base64_encode(document_content)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are now canonicalizing line-endings after encoding.

this will not be a behavior change for existing configs (which all use RFC-4648, aka .strict_encode) since RFC-4648 base64 will not contain any line endings.

@alexdean alexdean merged commit 1d98329 into master Feb 16, 2024
4 checks passed
@alexdean alexdean deleted the base64-nonstrict branch February 16, 2024 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant