[plt-scheme] Bug in FFI with Byte Strings or SHA1 Planet Package
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.