amazon-archives/aws-sdk-core-ruby

Aws::Json::Builder.format chokes on StringIO inputs

Closed this issue · 2 comments

Having generated a KMS data key using code such as:
kms = Aws::KMS::Client.new(region: REGION)
data_key_resp = kms.generate_data_key(key_id: KEY_ARN,
key_spec: "AES_256")

I later try to decrypt the encrypted copy of the resulting data key using code such as:

kms = Aws::KMS::Client.new(region: REGION)
res = kms.decrypt(ciphertext_blob: blob)

This results in an exception with the following stack trace:

/usr/lib/ruby/2.1.0/base64.rb:65:in `pack': no implicit conversion of StringIO into String (TypeError)
        from /usr/lib/ruby/2.1.0/base64.rb:65:in `strict_encode64'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/builder.rb:54:in `format'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/builder.rb:24:in `block in structure'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/builder.rb:20:in `each'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/builder.rb:20:in `with_object'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/builder.rb:20:in `structure'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/builder.rb:50:in `format'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/builder.rb:11:in `to_json'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/rpc_body_handler.rb:20:in `build_json'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/rpc_body_handler.rb:8:in `call'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/json/rpc_headers_handler.rb:10:in `call'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/plugins/user_agent.rb:12:in `call'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/seahorse/client/plugins/restful_bindings.rb:13:in `call'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/seahorse/client/plugins/endpoint.rb:35:in `call'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/seahorse/client/plugins/param_validation.rb:22:in `call'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/seahorse/client/plugins/raise_response_errors.rb:14:in `call'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/seahorse/client/plugins/param_conversion.rb:22:in `call'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/aws-sdk-core/plugins/response_paging.rb:10:in `call'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/seahorse/client/request.rb:70:in `send_request'
        from /home/noahm/.gems/gems/aws-sdk-core-2.0.16/lib/seahorse/client/base.rb:215:in `block (2 levels) in define_operation_methods'

If I modify json/builder.rb to explicitly call value.read when value is a StringIO object, then the base64 encoding is done correctly and the key is successfully decrypted. The diff that I used is below. I'm not sure that this is the right place to be performing this operation, though.

--- builder.rb.orig     2014-12-20 13:10:54.607131907 -0800
+++ builder.rb  2014-12-20 13:12:39.691133795 -0800
@@ -51,7 +51,12 @@
         when 'list'      then list(shape, value)
         when 'map'       then map(shape, value)
         when 'timestamp' then shape.format_time(value, 'unixTimestamp')
-        when 'blob'      then Base64.strict_encode64(value)
+        when 'blob'      then 
+            if(value.is_a? StringIO)
+                Base64.strict_encode64(value.read)
+            else
+                Base64.strict_encode64(value)
+            end
         else value
         end
       end

Closing as a duplicate of #179, fixed by #180. I'm going to try to cut a patch release shortly with this fix.

This has been resolved the fix is available in 2.0.17.