You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

541 lines
29 KiB

  1. package aws_test
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strings"
  6. "time"
  7. "github.com/goamz/goamz/aws"
  8. . "gopkg.in/check.v1"
  9. )
  10. var _ = Suite(&V4SignerSuite{})
  11. type V4SignerSuite struct {
  12. auth aws.Auth
  13. region aws.Region
  14. cases []V4SignerSuiteCase
  15. }
  16. type V4SignerSuiteCase struct {
  17. label string
  18. request V4SignerSuiteCaseRequest
  19. canonicalRequest string
  20. stringToSign string
  21. signature string
  22. authorization string
  23. }
  24. type V4SignerSuiteCaseRequest struct {
  25. method string
  26. host string
  27. url string
  28. headers []string
  29. body string
  30. }
  31. func (s *V4SignerSuite) SetUpSuite(c *C) {
  32. s.auth = aws.Auth{AccessKey: "AKIDEXAMPLE", SecretKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"}
  33. s.region = aws.USEast
  34. // Test cases from the Signature Version 4 Test Suite (http://goo.gl/nguvs0)
  35. s.cases = append(s.cases,
  36. // get-header-key-duplicate
  37. V4SignerSuiteCase{
  38. label: "get-header-key-duplicate",
  39. request: V4SignerSuiteCaseRequest{
  40. method: "POST",
  41. host: "host.foo.com",
  42. url: "/",
  43. headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "ZOO:zoobar", "zoo:foobar", "zoo:zoobar"},
  44. },
  45. canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\nzoo:foobar,zoobar,zoobar\n\ndate;host;zoo\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  46. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n3c52f0eaae2b61329c0a332e3fa15842a37bc5812cf4d80eb64784308850e313",
  47. signature: "54afcaaf45b331f81cd2edb974f7b824ff4dd594cbbaa945ed636b48477368ed",
  48. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;zoo, Signature=54afcaaf45b331f81cd2edb974f7b824ff4dd594cbbaa945ed636b48477368ed",
  49. },
  50. // get-header-value-order
  51. V4SignerSuiteCase{
  52. label: "get-header-value-order",
  53. request: V4SignerSuiteCaseRequest{
  54. method: "POST",
  55. host: "host.foo.com",
  56. url: "/",
  57. headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "p:z", "p:a", "p:p", "p:a"},
  58. },
  59. canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\np:a,a,p,z\n\ndate;host;p\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  60. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n94c0389fefe0988cbbedc8606f0ca0b485b48da010d09fc844b45b697c8924fe",
  61. signature: "d2973954263943b11624a11d1c963ca81fb274169c7868b2858c04f083199e3d",
  62. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;p, Signature=d2973954263943b11624a11d1c963ca81fb274169c7868b2858c04f083199e3d",
  63. },
  64. // get-header-value-trim
  65. V4SignerSuiteCase{
  66. label: "get-header-value-trim",
  67. request: V4SignerSuiteCaseRequest{
  68. method: "POST",
  69. host: "host.foo.com",
  70. url: "/",
  71. headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "p: phfft "},
  72. },
  73. canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\np:phfft\n\ndate;host;p\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  74. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ndddd1902add08da1ac94782b05f9278c08dc7468db178a84f8950d93b30b1f35",
  75. signature: "debf546796015d6f6ded8626f5ce98597c33b47b9164cf6b17b4642036fcb592",
  76. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;p, Signature=debf546796015d6f6ded8626f5ce98597c33b47b9164cf6b17b4642036fcb592",
  77. },
  78. // get-relative-relative
  79. V4SignerSuiteCase{
  80. label: "get-relative-relative",
  81. request: V4SignerSuiteCaseRequest{
  82. method: "GET",
  83. host: "host.foo.com",
  84. url: "/foo/bar/../..",
  85. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  86. },
  87. canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  88. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
  89. signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  90. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  91. },
  92. // get-relative
  93. V4SignerSuiteCase{
  94. label: "get-relative",
  95. request: V4SignerSuiteCaseRequest{
  96. method: "GET",
  97. host: "host.foo.com",
  98. url: "/foo/..",
  99. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  100. },
  101. canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  102. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
  103. signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  104. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  105. },
  106. // get-slash-dot-slash
  107. V4SignerSuiteCase{
  108. label: "get-slash-dot-slash",
  109. request: V4SignerSuiteCaseRequest{
  110. method: "GET",
  111. host: "host.foo.com",
  112. url: "/./",
  113. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  114. },
  115. canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  116. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
  117. signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  118. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  119. },
  120. // get-slash-pointless-dot
  121. V4SignerSuiteCase{
  122. label: "get-slash-pointless-dot",
  123. request: V4SignerSuiteCaseRequest{
  124. method: "GET",
  125. host: "host.foo.com",
  126. url: "/./foo",
  127. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  128. },
  129. canonicalRequest: "GET\n/foo\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  130. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n8021a97572ee460f87ca67f4e8c0db763216d84715f5424a843a5312a3321e2d",
  131. signature: "910e4d6c9abafaf87898e1eb4c929135782ea25bb0279703146455745391e63a",
  132. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=910e4d6c9abafaf87898e1eb4c929135782ea25bb0279703146455745391e63a",
  133. },
  134. // get-slash
  135. V4SignerSuiteCase{
  136. label: "get-slash",
  137. request: V4SignerSuiteCaseRequest{
  138. method: "GET",
  139. host: "host.foo.com",
  140. url: "//",
  141. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  142. },
  143. canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  144. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
  145. signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  146. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  147. },
  148. // get-slashes
  149. V4SignerSuiteCase{
  150. label: "get-slashes",
  151. request: V4SignerSuiteCaseRequest{
  152. method: "GET",
  153. host: "host.foo.com",
  154. url: "//foo//",
  155. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  156. },
  157. canonicalRequest: "GET\n/foo/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  158. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n6bb4476ee8745730c9cb79f33a0c70baa6d8af29c0077fa12e4e8f1dd17e7098",
  159. signature: "b00392262853cfe3201e47ccf945601079e9b8a7f51ee4c3d9ee4f187aa9bf19",
  160. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b00392262853cfe3201e47ccf945601079e9b8a7f51ee4c3d9ee4f187aa9bf19",
  161. },
  162. // get-space
  163. V4SignerSuiteCase{
  164. label: "get-space",
  165. request: V4SignerSuiteCaseRequest{
  166. method: "GET",
  167. host: "host.foo.com",
  168. url: "/%20/foo",
  169. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  170. },
  171. canonicalRequest: "GET\n/%20/foo\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  172. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n69c45fb9fe3fd76442b5086e50b2e9fec8298358da957b293ef26e506fdfb54b",
  173. signature: "f309cfbd10197a230c42dd17dbf5cca8a0722564cb40a872d25623cfa758e374",
  174. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=f309cfbd10197a230c42dd17dbf5cca8a0722564cb40a872d25623cfa758e374",
  175. },
  176. // get-unreserved
  177. V4SignerSuiteCase{
  178. label: "get-unreserved",
  179. request: V4SignerSuiteCaseRequest{
  180. method: "GET",
  181. host: "host.foo.com",
  182. url: "/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
  183. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  184. },
  185. canonicalRequest: "GET\n/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  186. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ndf63ee3247c0356c696a3b21f8d8490b01fa9cd5bc6550ef5ef5f4636b7b8901",
  187. signature: "830cc36d03f0f84e6ee4953fbe701c1c8b71a0372c63af9255aa364dd183281e",
  188. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=830cc36d03f0f84e6ee4953fbe701c1c8b71a0372c63af9255aa364dd183281e",
  189. },
  190. // get-utf8
  191. V4SignerSuiteCase{
  192. label: "get-utf8",
  193. request: V4SignerSuiteCaseRequest{
  194. method: "GET",
  195. host: "host.foo.com",
  196. url: "/%E1%88%B4",
  197. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  198. },
  199. canonicalRequest: "GET\n/%E1%88%B4\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  200. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n27ba31df5dbc6e063d8f87d62eb07143f7f271c5330a917840586ac1c85b6f6b",
  201. signature: "8d6634c189aa8c75c2e51e106b6b5121bed103fdb351f7d7d4381c738823af74",
  202. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=8d6634c189aa8c75c2e51e106b6b5121bed103fdb351f7d7d4381c738823af74",
  203. },
  204. // get-vanilla-empty-query-key
  205. V4SignerSuiteCase{
  206. label: "get-vanilla-empty-query-key",
  207. request: V4SignerSuiteCaseRequest{
  208. method: "GET",
  209. host: "host.foo.com",
  210. url: "/?foo=bar",
  211. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  212. },
  213. canonicalRequest: "GET\n/\nfoo=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  214. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n0846c2945b0832deb7a463c66af5c4f8bd54ec28c438e67a214445b157c9ddf8",
  215. signature: "56c054473fd260c13e4e7393eb203662195f5d4a1fada5314b8b52b23f985e9f",
  216. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=56c054473fd260c13e4e7393eb203662195f5d4a1fada5314b8b52b23f985e9f",
  217. },
  218. // get-vanilla-space-query-parameters
  219. V4SignerSuiteCase{
  220. label: "get-vanilla-space-query-parameters",
  221. request: V4SignerSuiteCaseRequest{
  222. method: "GET",
  223. host: "host.foo.com",
  224. url: "/?foo foo=bar bar",
  225. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  226. },
  227. canonicalRequest: "GET\n/\nfoo%20foo=bar%20bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  228. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n6a81658ae0a0a4f73aa72ca7d3b01c9cb0c5d4099f7a5ee897f5a571bfe6f7ff",
  229. signature: "c8556bc676129d0806ea8fe6ef182dc095666f4c1582c3d9751d47e4306037c9",
  230. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=c8556bc676129d0806ea8fe6ef182dc095666f4c1582c3d9751d47e4306037c9",
  231. },
  232. // get-vanilla-query-order-key-case
  233. V4SignerSuiteCase{
  234. label: "get-vanilla-query-order-key-case",
  235. request: V4SignerSuiteCaseRequest{
  236. method: "GET",
  237. host: "host.foo.com",
  238. url: "/?foo=Zoo&foo=aha",
  239. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  240. },
  241. canonicalRequest: "GET\n/\nfoo=Zoo&foo=aha\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  242. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ne25f777ba161a0f1baf778a87faf057187cf5987f17953320e3ca399feb5f00d",
  243. signature: "be7148d34ebccdc6423b19085378aa0bee970bdc61d144bd1a8c48c33079ab09",
  244. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=be7148d34ebccdc6423b19085378aa0bee970bdc61d144bd1a8c48c33079ab09",
  245. },
  246. // get-vanilla-query-order-key
  247. V4SignerSuiteCase{
  248. label: "get-vanilla-query-order-key",
  249. request: V4SignerSuiteCaseRequest{
  250. method: "GET",
  251. host: "host.foo.com",
  252. url: "/?a=foo&b=foo",
  253. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  254. },
  255. canonicalRequest: "GET\n/\na=foo&b=foo\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  256. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n2f23d14fe13caebf6dfda346285c6d9c14f49eaca8f5ec55c627dd7404f7a727",
  257. signature: "0dc122f3b28b831ab48ba65cb47300de53fbe91b577fe113edac383730254a3b",
  258. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=0dc122f3b28b831ab48ba65cb47300de53fbe91b577fe113edac383730254a3b",
  259. },
  260. // get-vanilla-query-order-value
  261. V4SignerSuiteCase{
  262. label: "get-vanilla-query-order-value",
  263. request: V4SignerSuiteCaseRequest{
  264. method: "GET",
  265. host: "host.foo.com",
  266. url: "/?foo=b&foo=a",
  267. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  268. },
  269. canonicalRequest: "GET\n/\nfoo=a&foo=b\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  270. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n33dffc220e89131f8f6157a35c40903daa658608d9129ff9489e5cf5bbd9b11b",
  271. signature: "feb926e49e382bec75c9d7dcb2a1b6dc8aa50ca43c25d2bc51143768c0875acc",
  272. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=feb926e49e382bec75c9d7dcb2a1b6dc8aa50ca43c25d2bc51143768c0875acc",
  273. },
  274. // get-vanilla-query-unreserved
  275. V4SignerSuiteCase{
  276. label: "get-vanilla-query-unreserved",
  277. request: V4SignerSuiteCaseRequest{
  278. method: "GET",
  279. host: "host.foo.com",
  280. url: "/?-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
  281. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  282. },
  283. canonicalRequest: "GET\n/\n-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  284. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\nd2578f3156d4c9d180713d1ff20601d8a3eed0dd35447d24603d7d67414bd6b5",
  285. signature: "f1498ddb4d6dae767d97c466fb92f1b59a2c71ca29ac954692663f9db03426fb",
  286. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=f1498ddb4d6dae767d97c466fb92f1b59a2c71ca29ac954692663f9db03426fb",
  287. },
  288. // get-vanilla-query
  289. V4SignerSuiteCase{
  290. label: "get-vanilla-query",
  291. request: V4SignerSuiteCaseRequest{
  292. method: "GET",
  293. host: "host.foo.com",
  294. url: "/",
  295. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  296. },
  297. canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  298. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
  299. signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  300. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  301. },
  302. // get-vanilla-ut8-query
  303. V4SignerSuiteCase{
  304. label: "get-vanilla-ut8-query",
  305. request: V4SignerSuiteCaseRequest{
  306. method: "GET",
  307. host: "host.foo.com",
  308. url: "/?ሴ=bar",
  309. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  310. },
  311. canonicalRequest: "GET\n/\n%E1%88%B4=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  312. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\nde5065ff39c131e6c2e2bd19cd9345a794bf3b561eab20b8d97b2093fc2a979e",
  313. signature: "6fb359e9a05394cc7074e0feb42573a2601abc0c869a953e8c5c12e4e01f1a8c",
  314. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=6fb359e9a05394cc7074e0feb42573a2601abc0c869a953e8c5c12e4e01f1a8c",
  315. },
  316. // get-vanilla
  317. V4SignerSuiteCase{
  318. label: "get-vanilla",
  319. request: V4SignerSuiteCaseRequest{
  320. method: "GET",
  321. host: "host.foo.com",
  322. url: "/",
  323. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  324. },
  325. canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  326. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
  327. signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  328. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
  329. },
  330. // post-header-key-case
  331. V4SignerSuiteCase{
  332. label: "post-header-key-case",
  333. request: V4SignerSuiteCaseRequest{
  334. method: "POST",
  335. host: "host.foo.com",
  336. url: "/",
  337. headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT"},
  338. },
  339. canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  340. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n05da62cee468d24ae84faff3c39f1b85540de60243c1bcaace39c0a2acc7b2c4",
  341. signature: "22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726",
  342. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726",
  343. },
  344. // post-header-key-sort
  345. V4SignerSuiteCase{
  346. label: "post-header-key-sort",
  347. request: V4SignerSuiteCaseRequest{
  348. method: "POST",
  349. host: "host.foo.com",
  350. url: "/",
  351. headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "ZOO:zoobar"},
  352. },
  353. canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\nzoo:zoobar\n\ndate;host;zoo\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  354. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n34e1bddeb99e76ee01d63b5e28656111e210529efeec6cdfd46a48e4c734545d",
  355. signature: "b7a95a52518abbca0964a999a880429ab734f35ebbf1235bd79a5de87756dc4a",
  356. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;zoo, Signature=b7a95a52518abbca0964a999a880429ab734f35ebbf1235bd79a5de87756dc4a",
  357. },
  358. // post-header-value-case
  359. V4SignerSuiteCase{
  360. label: "post-header-value-case",
  361. request: V4SignerSuiteCaseRequest{
  362. method: "POST",
  363. host: "host.foo.com",
  364. url: "/",
  365. headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "zoo:ZOOBAR"},
  366. },
  367. canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\nzoo:ZOOBAR\n\ndate;host;zoo\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  368. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n3aae6d8274b8c03e2cc96fc7d6bda4b9bd7a0a184309344470b2c96953e124aa",
  369. signature: "273313af9d0c265c531e11db70bbd653f3ba074c1009239e8559d3987039cad7",
  370. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;zoo, Signature=273313af9d0c265c531e11db70bbd653f3ba074c1009239e8559d3987039cad7",
  371. },
  372. // post-vanilla-empty-query-value
  373. V4SignerSuiteCase{
  374. label: "post-vanilla-empty-query-value",
  375. request: V4SignerSuiteCaseRequest{
  376. method: "POST",
  377. host: "host.foo.com",
  378. url: "/?foo=bar",
  379. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  380. },
  381. canonicalRequest: "POST\n/\nfoo=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  382. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ncd4f39132d8e60bb388831d734230460872b564871c47f5de62e62d1a68dbe1e",
  383. signature: "b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92",
  384. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92",
  385. },
  386. // post-vanilla-query
  387. V4SignerSuiteCase{
  388. label: "post-vanilla-query",
  389. request: V4SignerSuiteCaseRequest{
  390. method: "POST",
  391. host: "host.foo.com",
  392. url: "/?foo=bar",
  393. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  394. },
  395. canonicalRequest: "POST\n/\nfoo=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  396. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ncd4f39132d8e60bb388831d734230460872b564871c47f5de62e62d1a68dbe1e",
  397. signature: "b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92",
  398. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92",
  399. },
  400. // post-vanilla
  401. V4SignerSuiteCase{
  402. label: "post-vanilla",
  403. request: V4SignerSuiteCaseRequest{
  404. method: "POST",
  405. host: "host.foo.com",
  406. url: "/",
  407. headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  408. },
  409. canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  410. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n05da62cee468d24ae84faff3c39f1b85540de60243c1bcaace39c0a2acc7b2c4",
  411. signature: "22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726",
  412. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726",
  413. },
  414. // post-x-www-form-urlencoded-parameters
  415. V4SignerSuiteCase{
  416. label: "post-x-www-form-urlencoded-parameters",
  417. request: V4SignerSuiteCaseRequest{
  418. method: "POST",
  419. host: "host.foo.com",
  420. url: "/",
  421. headers: []string{"Content-Type:application/x-www-form-urlencoded; charset=utf8", "Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  422. body: "foo=bar",
  423. },
  424. canonicalRequest: "POST\n/\n\ncontent-type:application/x-www-form-urlencoded; charset=utf8\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ncontent-type;date;host\n3ba8907e7a252327488df390ed517c45b96dead033600219bdca7107d1d3f88a",
  425. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\nc4115f9e54b5cecf192b1eaa23b8e88ed8dc5391bd4fde7b3fff3d9c9fe0af1f",
  426. signature: "b105eb10c6d318d2294de9d49dd8b031b55e3c3fe139f2e637da70511e9e7b71",
  427. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=content-type;date;host, Signature=b105eb10c6d318d2294de9d49dd8b031b55e3c3fe139f2e637da70511e9e7b71",
  428. },
  429. // post-x-www-form-urlencoded
  430. V4SignerSuiteCase{
  431. label: "post-x-www-form-urlencoded",
  432. request: V4SignerSuiteCaseRequest{
  433. method: "POST",
  434. host: "host.foo.com",
  435. url: "/",
  436. headers: []string{"Content-Type:application/x-www-form-urlencoded", "Date:Mon, 09 Sep 2011 23:36:00 GMT"},
  437. body: "foo=bar",
  438. },
  439. canonicalRequest: "POST\n/\n\ncontent-type:application/x-www-form-urlencoded\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ncontent-type;date;host\n3ba8907e7a252327488df390ed517c45b96dead033600219bdca7107d1d3f88a",
  440. stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n4c5c6e4b52fb5fb947a8733982a8a5a61b14f04345cbfe6e739236c76dd48f74",
  441. signature: "5a15b22cf462f047318703b92e6f4f38884e4a7ab7b1d6426ca46a8bd1c26cbc",
  442. authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=content-type;date;host, Signature=5a15b22cf462f047318703b92e6f4f38884e4a7ab7b1d6426ca46a8bd1c26cbc",
  443. },
  444. )
  445. }
  446. func (s *V4SignerSuite) TestCases(c *C) {
  447. signer := aws.NewV4Signer(s.auth, "host", s.region)
  448. for _, testCase := range s.cases {
  449. req, err := http.NewRequest(testCase.request.method, "http://"+testCase.request.host+testCase.request.url, strings.NewReader(testCase.request.body))
  450. c.Assert(err, IsNil, Commentf("Testcase: %s", testCase.label))
  451. for _, v := range testCase.request.headers {
  452. h := strings.SplitN(v, ":", 2)
  453. req.Header.Add(h[0], h[1])
  454. }
  455. req.Header.Set("host", req.Host)
  456. t := signer.RequestTime(req)
  457. canonicalRequest := signer.CanonicalRequest(req)
  458. c.Check(canonicalRequest, Equals, testCase.canonicalRequest, Commentf("Testcase: %s", testCase.label))
  459. stringToSign := signer.StringToSign(t, canonicalRequest)
  460. c.Check(stringToSign, Equals, testCase.stringToSign, Commentf("Testcase: %s", testCase.label))
  461. signature := signer.Signature(t, stringToSign)
  462. c.Check(signature, Equals, testCase.signature, Commentf("Testcase: %s", testCase.label))
  463. authorization := signer.Authorization(req.Header, t, signature)
  464. c.Check(authorization, Equals, testCase.authorization, Commentf("Testcase: %s", testCase.label))
  465. signer.Sign(req)
  466. c.Check(req.Header.Get("Authorization"), Equals, testCase.authorization, Commentf("Testcase: %s", testCase.label))
  467. }
  468. }
  469. func ExampleV4Signer() {
  470. // Get auth from env vars
  471. auth, err := aws.EnvAuth()
  472. if err != nil {
  473. fmt.Println(err)
  474. }
  475. // Create a signer with the auth, name of the service, and aws region
  476. signer := aws.NewV4Signer(auth, "dynamodb", aws.USEast)
  477. // Create a request
  478. req, err := http.NewRequest("POST", aws.USEast.DynamoDBEndpoint, strings.NewReader("sample_request"))
  479. if err != nil {
  480. fmt.Println(err)
  481. }
  482. // Date or x-amz-date header is required to sign a request
  483. req.Header.Add("Date", time.Now().UTC().Format(http.TimeFormat))
  484. // Sign the request
  485. signer.Sign(req)
  486. // Issue signed request
  487. http.DefaultClient.Do(req)
  488. }