Merge lp:~therve/txaws/old-signature into lp:txaws

Proposed by Thomas Herve
Status: Merged
Merge reported by: Thomas Herve
Merged at revision: not available
Proposed branch: lp:~therve/txaws/old-signature
Merge into: lp:txaws
Diff against target: 144 lines (+52/-8)
3 files modified
txaws/credentials.py (+2/-0)
txaws/ec2/client.py (+22/-3)
txaws/ec2/tests/test_client.py (+28/-5)
To merge this branch: bzr merge lp:~therve/txaws/old-signature
Reviewer Review Type Date Requested Status
Free Ekanayaka (community) Approve
Review via email: mp+25335@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote :

Nice branch, thanks for implementing it.

review: Approve
Revision history for this message
Robert Collins (lifeless) wrote :

Why not pass the right hmac around, rather than strings?

Revision history for this message
Thomas Herve (therve) wrote :

Robert: I guess it's how it was done in trunk. I think it's also slightly more user-friendly for external usage (no need to import the functions from the util module).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'txaws/credentials.py'
2--- txaws/credentials.py 2009-11-05 22:19:12 +0000
3+++ txaws/credentials.py 2010-05-14 14:49:22 +0000
4@@ -44,3 +44,5 @@
5 return hmac_sha256(self.secret_key, bytes)
6 elif hash_type == "sha1":
7 return hmac_sha1(self.secret_key, bytes)
8+ else:
9+ raise RuntimeError("Unsupported hash type: '%s'" % hash_type)
10
11=== modified file 'txaws/ec2/client.py'
12--- txaws/ec2/client.py 2010-03-24 18:26:32 +0000
13+++ txaws/ec2/client.py 2010-05-14 14:49:22 +0000
14@@ -764,7 +764,6 @@
15 self.params = {
16 "Version": api_version,
17 "SignatureVersion": "2",
18- "SignatureMethod": "HmacSHA256",
19 "Action": self.action,
20 "AWSAccessKeyId": self.creds.access_key,
21 "Timestamp": iso8601time(time_tuple),
22@@ -794,18 +793,38 @@
23 self.get_canonical_query_params())
24 return result
25
26+ def old_signing_text(self):
27+ """Return the text needed for signing using SignatureVersion 1."""
28+ result = []
29+ lower_cmp = lambda x, y: cmp(x[0].lower(), y[0].lower())
30+ for key, value in sorted(self.params.items(), cmp=lower_cmp):
31+ result.append("%s%s" % (key, value))
32+ return "".join(result)
33+
34 def sorted_params(self):
35 """Return the query parameters sorted appropriately for signing."""
36 return sorted(self.params.items())
37
38- def sign(self):
39+ def sign(self, hash_type="sha256"):
40 """Sign this query using its built in credentials.
41
42+ @param hash_type: if the SignatureVersion is 2, specify the type of
43+ hash to use, either "sha1" or "sha256". It defaults to the latter.
44+
45 This prepares it to be sent, and should be done as the last step before
46 submitting the query. Signing is done automatically - this is a public
47 method to facilitate testing.
48 """
49- self.params["Signature"] = self.creds.sign(self.signing_text())
50+ version = self.params["SignatureVersion"]
51+ if version == "1":
52+ self.params["Signature"] = self.creds.sign(
53+ self.old_signing_text(), "sha1")
54+ elif version == "2":
55+ self.params["SignatureMethod"] = "Hmac%s" % hash_type.upper()
56+ self.params["Signature"] = self.creds.sign(
57+ self.signing_text(), hash_type)
58+ else:
59+ raise RuntimeError("Unsupported SignatureVersion: '%s'" % version)
60
61 def submit(self):
62 """Submit this query.
63
64=== modified file 'txaws/ec2/tests/test_client.py'
65--- txaws/ec2/tests/test_client.py 2010-03-29 17:16:46 +0000
66+++ txaws/ec2/tests/test_client.py 2010-05-14 14:49:22 +0000
67@@ -1417,7 +1417,6 @@
68 query.params,
69 {"AWSAccessKeyId": "foo",
70 "Action": "DescribeInstances",
71- "SignatureMethod": "HmacSHA256",
72 "SignatureVersion": "2",
73 "Version": "2008-12-01"})
74
75@@ -1431,7 +1430,6 @@
76 {"AWSAccessKeyId": "foo",
77 "Action": "DescribeInstances",
78 "InstanceId.0": "12345",
79- "SignatureMethod": "HmacSHA256",
80 "SignatureVersion": "2",
81 "Timestamp": "2007-11-12T13:14:15Z",
82 "Version": "2008-12-01"})
83@@ -1444,7 +1442,6 @@
84 self.assertEqual([
85 ("AWSAccessKeyId", "foo"),
86 ("Action", "DescribeInstances"),
87- ("SignatureMethod", "HmacSHA256"),
88 ("SignatureVersion", "2"),
89 ("Timestamp", "2007-11-12T13:14:15Z"),
90 ("Version", "2008-12-01"),
91@@ -1475,7 +1472,7 @@
92 time_tuple=(2007,11,12,13,14,15,0,0,0))
93 expected_query = ("AWSAccessKeyId=foo&Action=DescribeInstances"
94 "&InstanceId.1=i-1234"
95- "&SignatureMethod=HmacSHA256&SignatureVersion=2&"
96+ "&SignatureVersion=2&"
97 "Timestamp=2007-11-12T13%3A14%3A15Z&Version=2008-12-01&"
98 "argwithnovalue=&fu%20n=g%2Fames")
99 self.assertEqual(expected_query, query.get_canonical_query_params())
100@@ -1486,10 +1483,20 @@
101 endpoint=self.endpoint, time_tuple=(2007,11,12,13,14,15,0,0,0))
102 signing_text = ("GET\n%s\n/\n" % self.endpoint.host +
103 "AWSAccessKeyId=foo&Action=DescribeInstances&"
104- "SignatureMethod=HmacSHA256&SignatureVersion=2&"
105+ "SignatureVersion=2&"
106 "Timestamp=2007-11-12T13%3A14%3A15Z&Version=2008-12-01")
107 self.assertEqual(signing_text, query.signing_text())
108
109+ def test_old_signing_text(self):
110+ query = client.Query(
111+ action="DescribeInstances", creds=self.creds,
112+ endpoint=self.endpoint, time_tuple=(2007,11,12,13,14,15,0,0,0),
113+ other_params={"SignatureVersion": "1"})
114+ signing_text = (
115+ "ActionDescribeInstancesAWSAccessKeyIdfooSignatureVersion1"
116+ "Timestamp2007-11-12T13:14:15ZVersion2008-12-01")
117+ self.assertEqual(signing_text, query.old_signing_text())
118+
119 def test_sign(self):
120 query = client.Query(
121 action="DescribeInstances", creds=self.creds,
122@@ -1499,6 +1506,22 @@
123 self.assertEqual("aDmLr0Ktjsmt17UJD/EZf6DrfKWT1JW0fq2FDUCOPic=",
124 query.params["Signature"])
125
126+ def test_old_sign(self):
127+ query = client.Query(
128+ action="DescribeInstances", creds=self.creds,
129+ endpoint=self.endpoint, time_tuple=(2007,11,12,13,14,15,0,0,0),
130+ other_params={"SignatureVersion": "1"})
131+ query.sign()
132+ self.assertEqual(
133+ "MBKyHoxqCd/lBQLVkCZYpwAtNJg=", query.params["Signature"])
134+
135+ def test_unsupported_sign(self):
136+ query = client.Query(
137+ action="DescribeInstances", creds=self.creds,
138+ endpoint=self.endpoint, time_tuple=(2007,11,12,13,14,15,0,0,0),
139+ other_params={"SignatureVersion": "0"})
140+ self.assertRaises(RuntimeError, query.sign)
141+
142 def test_submit_400(self):
143 """A 4xx response status from EC2 should raise a txAWS EC2Error."""
144 status = 400

Subscribers

People subscribed via source and target branches

to all changes: