[plt-scheme] Bug in FFI with Byte Strings or SHA1 Planet Package

From: Ray Racine (ray.racine at comcast.net)
Date: Mon Sep 3 09:31:02 EDT 2007

I'm playing around with a DrScheme <-> Amazon S3 DSL and ran into an
issue.

As part of a S3 simple RPC command you have to sign a fixed subset of
the URL your sending. The example strings and the signing algo are from
Amazon's S3 technical doc.

(require (lib "base64.ss" "net")
         (planet "hmac-sha1.ss" ("jaymccarthy" "hmac-sha1.plt" 1 0)))
  
(let ((key (string->bytes/utf-8
"OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV")))
  (map 
   (lambda(s)
     (base64-encode (HMAC-SHA1 key (string->bytes/utf-8 s))))
   '(
  "PUT\nc8fdb181845a4ca6b8fec737b3581d76\ntext/html\nThu, 17 Nov 2005
18:49:58 GMT\nx-amz-magic:abracadabra\nx-amz-meta-author:foo at bar.com
\n/quotes/nelson"
  "GET\n\n\n\nx-amz-date:Thu, 17 Nov 2005 18:49:58 GMT
\nx-amz-magic:abracadabra\n/quotes/nelson"
  "GET\n\n\n1141889120\n/quotes/nelson")))

Note: Note the explicit \n are part of the spec.  The strings are being
wrapped by the email.

The result of running the above in DrScheme is:

(#"jZNOcbfWmD/A/f3hSvVzXZjM2HU=\r\n" 
 #"5m+HAmc5JsrgyDelh9+a2dNrzN8=\r\n" 
 #"vjbyPxybdZaNmGa+yT272YE=\r\n")

Ignore the trailing \r\n as they are not a problem.

The first two results are _correct_, per the manual as well as some
example Python code from Amazon.  However, the third answer is not
correct and I think is being truncated in the FFI.

Here, according to Amazon's S3 manual, is the correct answer in Python
for the third example.

Python 2.4.4 (#1, Oct 23 2006, 13:58:00) 
[GCC 4.1.1 20061011 (Red Hat 4.1.1-30)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> import hmac
>>> import sha
>>> import urllib
>>> h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV",
...              "GET\n\n\n1141889120\n/quotes/nelson",
...              sha)
>>> base64.encodestring(h.digest()).strip()
'vjbyPxybdZaNmGa+yT272YEAiv4='
>>> 

So we have:
DrScheme -> 
  #"vjbyPxybdZaNmGa+yT272YE=\r\n"
Python and Amazon Manual -> 
  'vjbyPxybdZaNmGa+yT272YEAiv4='

The last 4 bytes were dropped in DrScheme.

If I just run the digest in Python I see the following byte string.

>>> h.digest()
'\xbe6\xf2?\x1c\x9bu\x96\x8d\x98f\xbe\xc9=\xbb\xd9\x81\x00\x8a\xfe'

I think the premature truncation may be in the FFI from the x00 null
byte near the end of the result.  And certainly 0x00 is a valid byte
value.

I'm using Jay McCarthy's package from Planet to invoke the SHA1 digest.

  (planet "hmac-sha1.ss" ("jaymccarthy" "hmac-sha1.plt" 1 0)))
 
Fedora 7.  DrScheme up-to-date with CVS.


Am I doing something wrong?  
Did Jay miss something in the FFI construction?  
Or is there a bug in the FFI regarding byte strings/arrays?
Or something else?

I will not touch that dial in anticipation of some generous person's
kind response.





Posted on the users mailing list.