| Ah, I see what's going on. Ruby has 2 methods for base64 decoding. One is strict (follows RFC 4648) and other is not strict (follows RFC 2045). Puppet calls unpack("m0") which calls the former, while unpack("m") would call the latter. The = character is used to pad the base64 encoded value, see https://en.wikipedia.org/wiki/Base64#Output_padding. If the padding is omitted (which your server must be doing), then non-strict decode will succeed, but strict decode will fail:
irb(main):034:0> Base64.strict_decode64("DugzajWJUDvLA8eIWVDJCQ==") |
=> "\x0E\xE83j5\x89P;\xCB\x03\xC7\x88YP\xC9\t" |
irb(main):035:0> Base64.strict_decode64("DugzajWJUDvLA8eIWVDJCQ") |
Traceback (most recent call last): |
4: from /usr/local/opt/rbenv/versions/2.5.3/bin/irb:11:in `<main>' |
3: from (irb):35 |
2: from /usr/local/Cellar/rbenv/1.1.2/versions/2.5.3/lib/ruby/2.5.0/base64.rb:74:in `strict_decode64' |
1: from /usr/local/Cellar/rbenv/1.1.2/versions/2.5.3/lib/ruby/2.5.0/base64.rb:74:in `unpack1' |
ArgumentError (invalid base64)
|
So we could change puppet to accept non-strict decode (RFC 2045). Or we could add 0-2 characters of padding, and then strictly decode as we do now. I'm inclined to do the latter, as it seems consistent with https://tools.ietf.org/html/rfc4648#section-3.2, since in this case, we know the size exactly (24 bytes)
In some circumstances, the use of padding ("=") in base-encoded data is not required or used. In the general case, when assumptions about the size of transported data cannot be made, padding is required to yield correct decoded data.
|