12
var _ = Suite(&SigningSuite{})
14
type SigningSuite struct{}
16
// TODO(katco-): The signing methodology is a "one size fits all"
17
// approach. The hashes we check against don't include headers that
18
// are added in as requisite parts for S3. That doesn't mean the tests
19
// are invalid, or that signing is broken for these examples, but as
20
// long as we're adding heads in, it's impossible to know what the new
21
// signature should be. We should revaluate these later. See:
22
// https://github.com/go-amz/amz/issues/29
23
const v4skipReason = `Extra headers present - cannot predict generated signature (issue #29).`
25
// EC2 ReST authentication docs: http://goo.gl/fQmAN
26
var testAuth = Auth{"user", "secret"}
28
func (s *SigningSuite) TestV4SignedUrl(c *C) {
30
auth := Auth{"AKIAIOSFODNN7EXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}
31
req, err := http.NewRequest("GET", "https://examplebucket.s3.amazonaws.com/test.txt", nil)
32
req.Header.Add("date", "Fri, 24 May 2013 00:00:00 GMT")
34
err = SignV4URL(req, auth, USEast.Name, "s3", 86400*time.Second)
37
c.Check(req.URL.String(), Equals, "https://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-Signature=aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404&X-Amz-SignedHeaders=host")
40
func (s *SigningSuite) TestV4SignedUrlReserved(c *C) {
42
auth := Auth{"AKIAIOSFODNN7EXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}
43
req, err := http.NewRequest("GET", "https://examplebucket.s3.amazonaws.com/some:reserved,characters", nil)
44
req.Header.Add("date", "Fri, 24 May 2013 00:00:00 GMT")
46
err = SignV4URL(req, auth, USEast.Name, "s3", 86400*time.Second)
49
c.Check(req.URL.String(), Equals, "https://examplebucket.s3.amazonaws.com/some:reserved,characters?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-Signature=ac81e03593d6fc22ac045b9353b0242da755be2af80b981eb13917d8b9cf20a4&X-Amz-SignedHeaders=host")
52
func (s *SigningSuite) TestV4StringToSign(c *C) {
54
mockTime, err := time.Parse(time.RFC3339, "2011-09-09T23:36:00Z")
56
stringToSign, err := stringToSign(
58
"3511de7e95d28ecd39e9513b642aee07e54f4941150d8df8bf94b328ef7e55e2",
59
"20110909/us-east-1/iam/aws4_request",
63
const expected = `AWS4-HMAC-SHA256
65
20110909/us-east-1/iam/aws4_request
66
3511de7e95d28ecd39e9513b642aee07e54f4941150d8df8bf94b328ef7e55e2`
67
c.Assert(stringToSign, Equals, expected)
70
func (s *SigningSuite) TestV4CanonicalRequest(c *C) {
74
body := new(bytes.Buffer)
75
_, err := fmt.Fprint(body, "Action=ListUsers&Version=2010-05-08")
78
req, err := http.NewRequest("POST", "https://iam.amazonaws.com", body)
81
req.Header.Add("content-type", "application/x-www-form-urlencoded; charset=utf-8")
82
req.Header.Add("host", req.URL.Host)
83
req.Header.Add("x-amz-date", "20110909T233600Z")
85
canonReq, canonReqHash, _, err := canonicalRequest(
92
const expected = `POST
95
content-type:application/x-www-form-urlencoded; charset=utf-8
96
host:iam.amazonaws.com
97
x-amz-date:20110909T233600Z
99
content-type;host;x-amz-date
100
b6359072c78d70ebee1e81adcbab4f01bf2c23245fa365ef83fe8f1f955085e2`
102
c.Assert(canonReq, Equals, expected)
103
c.Assert(canonReqHash, Equals, "3511de7e95d28ecd39e9513b642aee07e54f4941150d8df8bf94b328ef7e55e2")
106
func (s *SigningSuite) TestV4SigningKey(c *C) {
110
mockTime, err := time.Parse(time.RFC3339, "2011-09-09T23:36:00Z")
113
fmt.Sprintf("%v", signingKey(mockTime, testAuth.SecretKey, USEast.Name, "iam")),
115
"[152 241 216 137 254 196 244 66 26 220 82 43 171 12 225 248 46 105 41 194 98 237 21 229 169 76 144 239 209 227 176 231]")
118
func (s *SigningSuite) TestV4BasicSignatureV4(c *C) {
122
body := new(bytes.Buffer)
124
req, err := http.NewRequest("POST / http/1.1", "https://host.foo.com", body)
127
req.Header.Add("Host", req.URL.Host)
128
req.Header.Add("Date", "Mon, 09 Sep 2011 23:36:00 GMT")
131
AccessKey: "AKIDEXAMPLE",
132
SecretKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
134
err = SignV4(req, testAuth, USEast.Name, "host")
137
c.Assert(req.Header.Get("Authorization"), Equals, `AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request,SignedHeaders=date;host,Signature=22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726`)
140
func (s *SigningSuite) TestV4MoreCompleteSignature(c *C) {
142
req, err := http.NewRequest("GET", "https://examplebucket.s3.amazonaws.com/test.txt", nil)
145
req.Header.Set("x-amz-date", "20130524T000000Z")
146
req.Header.Set("Range", "bytes=0-9")
149
AccessKey: "AKIAIOSFODNN7EXAMPLE",
150
SecretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
152
err = SignV4(req, testAuth, USEast.Name, "s3")
154
c.Check(req.Header.Get("Authorization"), Equals, "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request, SignedHeaders=host;range;x-amz-content-sha256;x-amz-date, Signature=f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41")
161
func (s *SigningSuite) TestV2BasicSignature(c *C) {
162
req, err := http.NewRequest("GET", "http://localhost/path", nil)
165
SignV2(req, testAuth)
167
query := req.URL.Query()
169
c.Assert(query.Get("SignatureVersion"), Equals, "2")
170
c.Assert(query.Get("SignatureMethod"), Equals, "HmacSHA256")
171
expected := "6lSe5QyXum0jMVc7cOUz32/52ZnL7N5RyKRk/09yiK4="
172
c.Assert(query.Get("Signature"), Equals, expected)
175
func (s *SigningSuite) TestV2ParamSignature(c *C) {
177
req, err := http.NewRequest("GET", "http://localhost/path", nil)
180
query := req.URL.Query()
181
for i := 1; i <= 3; i++ {
182
query.Add(fmt.Sprintf("param%d", i), fmt.Sprintf("value%d", i))
184
req.URL.RawQuery = query.Encode()
186
SignV2(req, testAuth)
188
expected := "XWOR4+0lmK8bD8CGDGZ4kfuSPbb2JibLJiCl/OPu1oU="
189
c.Assert(req.URL.Query().Get("Signature"), Equals, expected)
192
func (s *SigningSuite) TestV2ManyParams(c *C) {
194
req, err := http.NewRequest("GET", "http://localhost/path", nil)
197
query := req.URL.Query()
198
orderedVals := []int{10, 2, 3, 4, 5, 6, 7, 8, 9, 1}
199
for i, val := range orderedVals {
200
query.Add(fmt.Sprintf("param%d", i+1), fmt.Sprintf("value%d", val))
202
req.URL.RawQuery = query.Encode()
204
SignV2(req, testAuth)
206
expected := "di0sjxIvezUgQ1SIL6i+C/H8lL+U0CQ9frLIak8jkVg="
207
c.Assert(req.URL.Query().Get("Signature"), Equals, expected)
210
func (s *SigningSuite) TestV2Escaping(c *C) {
212
req, err := http.NewRequest("GET", "http://localhost/path", nil)
215
query := req.URL.Query()
216
query.Add("Nonce", "+ +")
217
req.URL.RawQuery = query.Encode()
219
err = SignV2(req, testAuth)
222
query = req.URL.Query()
223
c.Assert(query.Get("Nonce"), Equals, "+ +")
225
expected := "bqffDELReIqwjg/W0DnsnVUmfLK4wXVLO4/LuG+1VFA="
226
c.Assert(query.Get("Signature"), Equals, expected)
229
func (s *SigningSuite) TestV2SignatureExample1(c *C) {
231
req, err := http.NewRequest("GET", "http://sdb.amazonaws.com/", nil)
234
query := req.URL.Query()
235
query.Add("Timestamp", "2009-02-01T12:53:20+00:00")
236
query.Add("Version", "2007-11-07")
237
query.Add("Action", "ListDomains")
238
req.URL.RawQuery = query.Encode()
240
SignV2(req, Auth{"access", "secret"})
242
expected := "okj96/5ucWBSc1uR2zXVfm6mDHtgfNv657rRtt/aunQ="
243
c.Assert(req.URL.Query().Get("Signature"), Equals, expected)
246
// Tests example from:
247
// http://docs.aws.amazon.com/general/latest/gr/signature-version-2.html
248
// Specifically, good for testing case when URL does not contain a /
249
func (s *SigningSuite) TestV2SignatureTutorialExample(c *C) {
251
req, err := http.NewRequest("GET", "https://elasticmapreduce.amazonaws.com/", nil)
254
query := req.URL.Query()
255
query.Add("Timestamp", "2011-10-03T15:19:30")
256
query.Add("Version", "2009-03-31")
257
query.Add("Action", "DescribeJobFlows")
258
req.URL.RawQuery = query.Encode()
260
testAuth := Auth{"AKIAIOSFODNN7EXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}
261
err = SignV2(req, testAuth)
263
c.Assert(req.URL.Query().Get("Signature"), Equals, "i91nKc4PWAt0JJIdXwz9HxZCJDdiy6cf/Mj6vPxyYIs=")
266
// https://bugs.launchpad.net/goamz/+bug/1022749
267
func (s *SigningSuite) TestSignatureWithEndpointPath(c *C) {
269
req, err := http.NewRequest("GET", "http://localhost:4444/services/Cloud", nil)
272
queryStr := req.URL.Query()
273
queryStr.Add("Action", "RebootInstances")
274
queryStr.Add("Version", "2011-12-15")
275
queryStr.Add("InstanceId.1", "i-10a64379")
276
queryStr.Add("Timestamp", time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC).In(time.UTC).Format(time.RFC3339))
277
req.URL.RawQuery = queryStr.Encode()
279
err = SignV2(req, Auth{"abc", "123"})
281
c.Assert(req.URL.Query().Get("Signature"), Equals, "gdG/vEm+c6ehhhfkrJy3+wuVzw/rzKR42TYelMwti7M=")
282
err = req.ParseForm()
284
c.Assert(req.Form["Signature"], DeepEquals, []string{"gdG/vEm+c6ehhhfkrJy3+wuVzw/rzKR42TYelMwti7M="})