sabato 22 settembre 2007

RESTful Web Services Example 3.19 - SHA1 Signing

The Amazon S3 examples explained in Chapter 3 of the RESTful Web Services book have a top-down order: the first examples explain the high-level workings of the system, while the final ones explain details such as request signing etc.
Since in this conversion notes I assume you are familiar with Richardson & Ruby’s book, I will start from the bottom and climb my way up to the most high-level examples.

For these reason I’ll start with a helper method that is used to sign the HTTP requests: #signString:.

If you load the package RWS-gc.10 from the RWS repository, you’ll see a new class called S3Object:
Object subclass: #S3Object
instanceVariableNames: 'publicKey privateKey'
classVariableNames: 'AmazonHeaderPrefix InterestingHeaders'
poolDictionaries: ''
category: 'RWS-Examples'

This class plays the same role as the Ruby S3::Authorized module. All the Squeak classes in the examples will be subclasses of S3Object.

S3Object has two instance variables to hold the public and private keys that Amazon has assigned to you when you signed up for its Amazon Web Services program.
It also has two class variables that hold useful constants. These class variables are initialized in the S3Object class>>initialize method:
S3Object class>>initialize
InterestingHeaders := #('content-type' 'content-md5' 'date').
AmazonHeaderPrefix := 'x-amz-'

The example I’ll show here is the #signString: method. This method computes a base64 encoding of the HMAC-SHA1 digest of its argument.
signString: aString
| hmac digest |
"Signs a string with the client's secret access key, and encodes the
resulting binary string into plain ASCII with base64.
Code taken from RESTful Web Services. Copyright © 2007 O'Reilly Media, Inc.
All rights reserved. Used with permission."
hmac := SHA1 new hmac.
hmac key: privateKey asByteArray.
digest := hmac digestMessage: aString asByteArray.
^ Base64MimeConverter mimeEncode: (ReadStream on: digest)

The Smalltalk code is similar to the Ruby source, but with a couple of lesser differences.
The first is that Squeak’s HMAC class requires instances of the ByteArray class instead of plain strings, due to the multilingual support built into the latest version of Squeak. The second difference is that Squeak’s base64 requires a stream instead of a String or a ByteArray, as per the standard Smalltalk idiom.

In the next post, I’ll show another helper method, canonicalStringFor:path:headers:expires:.

Nessun commento: