| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func niceError(code APIErrorCode) string { | 
					
						
							|  |  |  | 	// Special-handle ErrNone
 | 
					
						
							|  |  |  | 	if code == ErrNone { | 
					
						
							|  |  |  | 		return "ErrNone" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 17:25:52 +08:00
										 |  |  | 	return fmt.Sprintf("%s (%s)", errorCodes[code].Code, errorCodes[code].Description) | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestDoesPolicySignatureMatch(t *testing.T) { | 
					
						
							|  |  |  | 	credentialTemplate := "%s/%s/%s/s3/aws4_request" | 
					
						
							| 
									
										
										
										
											2017-03-19 02:28:41 +08:00
										 |  |  | 	now := UTCNow() | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	accessKey := globalActiveCred.AccessKey | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							| 
									
										
										
										
											2017-03-14 05:41:13 +08:00
										 |  |  | 		form     http.Header | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		expected APIErrorCode | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		// (0) It should fail if 'X-Amz-Credential' is missing.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-03-14 05:41:13 +08:00
										 |  |  | 			form:     http.Header{}, | 
					
						
							| 
									
										
										
										
											2020-08-24 13:06:22 +08:00
										 |  |  | 			expected: ErrCredMalformed, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		// (1) It should fail if the access key is incorrect.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-03-14 05:41:13 +08:00
										 |  |  | 			form: http.Header{ | 
					
						
							|  |  |  | 				"X-Amz-Credential": []string{fmt.Sprintf(credentialTemplate, "EXAMPLEINVALIDEXAMPL", now.Format(yyyymmdd), globalMinioDefaultRegion)}, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			expected: ErrInvalidAccessKeyID, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (2) It should fail with a bad signature.
 | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-03-14 05:41:13 +08:00
										 |  |  | 			form: http.Header{ | 
					
						
							|  |  |  | 				"X-Amz-Credential": []string{fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion)}, | 
					
						
							|  |  |  | 				"X-Amz-Date":       []string{now.Format(iso8601Format)}, | 
					
						
							|  |  |  | 				"X-Amz-Signature":  []string{"invalidsignature"}, | 
					
						
							|  |  |  | 				"Policy":           []string{"policy"}, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			expected: ErrSignatureDoesNotMatch, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (3) It should succeed if everything is correct.
 | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-03-14 05:41:13 +08:00
										 |  |  | 			form: http.Header{ | 
					
						
							|  |  |  | 				"X-Amz-Credential": []string{ | 
					
						
							|  |  |  | 					fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion), | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				"X-Amz-Date": []string{now.Format(iso8601Format)}, | 
					
						
							|  |  |  | 				"X-Amz-Signature": []string{ | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 					getSignature(getSigningKey(globalActiveCred.SecretKey, now, | 
					
						
							| 
									
										
										
										
											2019-02-28 09:46:55 +08:00
										 |  |  | 						globalMinioDefaultRegion, serviceS3), "policy"), | 
					
						
							| 
									
										
										
										
											2017-03-14 05:41:13 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 				"Policy": []string{"policy"}, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			expected: ErrNone, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Run each test case individually.
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2021-03-04 00:47:08 +08:00
										 |  |  | 		_, code := doesPolicySignatureMatch(testCase.form) | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		if code != testCase.expected { | 
					
						
							|  |  |  | 			t.Errorf("(%d) expected to get %s, instead got %s", i, niceError(testCase.expected), niceError(code)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestDoesPresignedSignatureMatch(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-08-15 12:41:47 +08:00
										 |  |  | 	obj, fsDir, err := prepareFS() | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-15 12:41:47 +08:00
										 |  |  | 	defer os.RemoveAll(fsDir) | 
					
						
							|  |  |  | 	if err = newTestConfig(globalMinioDefaultRegion, obj); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 	// sha256 hash of "payload"
 | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 	payloadSHA256 := "239f59ed55e737c77147cf55ad0c1b030b6d7ee748a7426952f9b852d5a935e5" | 
					
						
							| 
									
										
										
										
											2017-03-19 02:28:41 +08:00
										 |  |  | 	now := UTCNow() | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 	credentialTemplate := "%s/%s/%s/s3/aws4_request" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-26 05:06:25 +08:00
										 |  |  | 	region := globalSite.Region | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	accessKeyID := globalActiveCred.AccessKey | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 	testCases := []struct { | 
					
						
							| 
									
										
										
										
											2016-09-30 06:51:00 +08:00
										 |  |  | 		queryParams map[string]string | 
					
						
							|  |  |  | 		headers     map[string]string | 
					
						
							|  |  |  | 		region      string | 
					
						
							|  |  |  | 		expected    APIErrorCode | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 	}{ | 
					
						
							|  |  |  | 		// (0) Should error without a set URL query.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  | 			region:   globalMinioDefaultRegion, | 
					
						
							| 
									
										
										
										
											2016-09-30 06:51:00 +08:00
										 |  |  | 			expected: ErrInvalidQueryParams, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		// (1) Should error on an invalid access key.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			queryParams: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Algorithm":     signV4Algorithm, | 
					
						
							|  |  |  | 				"X-Amz-Date":          now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Expires":       "60", | 
					
						
							|  |  |  | 				"X-Amz-Signature":     "badsignature", | 
					
						
							|  |  |  | 				"X-Amz-SignedHeaders": "host;x-amz-content-sha256;x-amz-date", | 
					
						
							|  |  |  | 				"X-Amz-Credential":    fmt.Sprintf(credentialTemplate, "Z7IXGOO6BZ0REAN1Q26I", now.Format(yyyymmdd), "us-west-1"), | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-09-30 06:51:00 +08:00
										 |  |  | 			region:   "us-west-1", | 
					
						
							|  |  |  | 			expected: ErrInvalidAccessKeyID, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (2) Should NOT fail with an invalid region if it doesn't verify it.
 | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			queryParams: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Algorithm":      signV4Algorithm, | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Expires":        "60", | 
					
						
							|  |  |  | 				"X-Amz-Signature":      "badsignature", | 
					
						
							|  |  |  | 				"X-Amz-SignedHeaders":  "host;x-amz-content-sha256;x-amz-date", | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 				"X-Amz-Credential":     fmt.Sprintf(credentialTemplate, accessKeyID, now.Format(yyyymmdd), "us-west-1"), | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-09-30 06:51:00 +08:00
										 |  |  | 			region:   "us-west-1", | 
					
						
							|  |  |  | 			expected: ErrUnsignedHeaders, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (3) Should fail to extract headers if the host header is not signed.
 | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			queryParams: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Algorithm":      signV4Algorithm, | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Expires":        "60", | 
					
						
							|  |  |  | 				"X-Amz-Signature":      "badsignature", | 
					
						
							|  |  |  | 				"X-Amz-SignedHeaders":  "x-amz-content-sha256;x-amz-date", | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 				"X-Amz-Credential":     fmt.Sprintf(credentialTemplate, accessKeyID, now.Format(yyyymmdd), region), | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 			region:   region, | 
					
						
							| 
									
										
										
										
											2016-09-30 06:51:00 +08:00
										 |  |  | 			expected: ErrUnsignedHeaders, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (4) Should give an expired request if it has expired.
 | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			queryParams: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Algorithm":      signV4Algorithm, | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.AddDate(0, 0, -2).Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Expires":        "60", | 
					
						
							|  |  |  | 				"X-Amz-Signature":      "badsignature", | 
					
						
							|  |  |  | 				"X-Amz-SignedHeaders":  "host;x-amz-content-sha256;x-amz-date", | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 				"X-Amz-Credential":     fmt.Sprintf(credentialTemplate, accessKeyID, now.Format(yyyymmdd), region), | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			headers: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.AddDate(0, 0, -2).Format(iso8601Format), | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 			region:   region, | 
					
						
							| 
									
										
										
										
											2016-09-30 06:51:00 +08:00
										 |  |  | 			expected: ErrExpiredPresignRequest, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (5) Should error if the signature is incorrect.
 | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			queryParams: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Algorithm":      signV4Algorithm, | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Expires":        "60", | 
					
						
							|  |  |  | 				"X-Amz-Signature":      "badsignature", | 
					
						
							|  |  |  | 				"X-Amz-SignedHeaders":  "host;x-amz-content-sha256;x-amz-date", | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 				"X-Amz-Credential":     fmt.Sprintf(credentialTemplate, accessKeyID, now.Format(yyyymmdd), region), | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			headers: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.Format(iso8601Format), | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 			region:   region, | 
					
						
							| 
									
										
										
										
											2016-09-30 06:51:00 +08:00
										 |  |  | 			expected: ErrSignatureDoesNotMatch, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (6) Should error if the request is not ready yet, ie X-Amz-Date is in the future.
 | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			queryParams: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Algorithm":      signV4Algorithm, | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.Add(1 * time.Hour).Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Expires":        "60", | 
					
						
							|  |  |  | 				"X-Amz-Signature":      "badsignature", | 
					
						
							|  |  |  | 				"X-Amz-SignedHeaders":  "host;x-amz-content-sha256;x-amz-date", | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 				"X-Amz-Credential":     fmt.Sprintf(credentialTemplate, accessKeyID, now.Format(yyyymmdd), region), | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			headers: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 			region:   region, | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 			expected: ErrRequestNotReadyYet, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (7) Should not error with invalid region instead, call should proceed
 | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 		// with sigature does not match.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			queryParams: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Algorithm":      signV4Algorithm, | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Expires":        "60", | 
					
						
							|  |  |  | 				"X-Amz-Signature":      "badsignature", | 
					
						
							|  |  |  | 				"X-Amz-SignedHeaders":  "host;x-amz-content-sha256;x-amz-date", | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 				"X-Amz-Credential":     fmt.Sprintf(credentialTemplate, accessKeyID, now.Format(yyyymmdd), region), | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			headers: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			region:   "", | 
					
						
							|  |  |  | 			expected: ErrSignatureDoesNotMatch, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (8) Should error with signature does not match. But handles
 | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 		// query params which do not precede with "x-amz-" header.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			queryParams: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Algorithm":       signV4Algorithm, | 
					
						
							|  |  |  | 				"X-Amz-Date":            now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Expires":         "60", | 
					
						
							|  |  |  | 				"X-Amz-Signature":       "badsignature", | 
					
						
							|  |  |  | 				"X-Amz-SignedHeaders":   "host;x-amz-content-sha256;x-amz-date", | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 				"X-Amz-Credential":      fmt.Sprintf(credentialTemplate, accessKeyID, now.Format(yyyymmdd), region), | 
					
						
							| 
									
										
										
										
											2016-11-07 03:47:16 +08:00
										 |  |  | 				"X-Amz-Content-Sha256":  payloadSHA256, | 
					
						
							|  |  |  | 				"response-content-type": "application/json", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			headers: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Date":           now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Content-Sha256": payloadSHA256, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			region:   "", | 
					
						
							|  |  |  | 			expected: ErrSignatureDoesNotMatch, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		// (9) Should error with unsigned headers.
 | 
					
						
							| 
									
										
										
										
											2016-11-11 13:57:15 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			queryParams: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Algorithm":       signV4Algorithm, | 
					
						
							|  |  |  | 				"X-Amz-Date":            now.Format(iso8601Format), | 
					
						
							|  |  |  | 				"X-Amz-Expires":         "60", | 
					
						
							|  |  |  | 				"X-Amz-Signature":       "badsignature", | 
					
						
							|  |  |  | 				"X-Amz-SignedHeaders":   "host;x-amz-content-sha256;x-amz-date", | 
					
						
							|  |  |  | 				"X-Amz-Credential":      fmt.Sprintf(credentialTemplate, accessKeyID, now.Format(yyyymmdd), region), | 
					
						
							|  |  |  | 				"X-Amz-Content-Sha256":  payloadSHA256, | 
					
						
							|  |  |  | 				"response-content-type": "application/json", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			headers: map[string]string{ | 
					
						
							|  |  |  | 				"X-Amz-Date": now.Format(iso8601Format), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			region:   "", | 
					
						
							|  |  |  | 			expected: ErrUnsignedHeaders, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Run each test case individually.
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		// Turn the map[string]string into map[string][]string, because Go.
 | 
					
						
							|  |  |  | 		query := url.Values{} | 
					
						
							|  |  |  | 		for key, value := range testCase.queryParams { | 
					
						
							|  |  |  | 			query.Set(key, value) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Create a request to use.
 | 
					
						
							|  |  |  | 		req, e := http.NewRequest(http.MethodGet, "http://host/a/b?"+query.Encode(), nil) | 
					
						
							|  |  |  | 		if e != nil { | 
					
						
							|  |  |  | 			t.Errorf("(%d) failed to create http.Request, got %v", i, e) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Do the same for the headers.
 | 
					
						
							|  |  |  | 		for key, value := range testCase.headers { | 
					
						
							|  |  |  | 			req.Header.Set(key, value) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-08 13:43:01 +08:00
										 |  |  | 		// parse form.
 | 
					
						
							|  |  |  | 		req.ParseForm() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		// Check if it matches!
 | 
					
						
							| 
									
										
										
										
											2019-02-28 09:46:55 +08:00
										 |  |  | 		err := doesPresignedSignatureMatch(payloadSHA256, req, testCase.region, serviceS3) | 
					
						
							| 
									
										
										
										
											2016-08-17 08:02:35 +08:00
										 |  |  | 		if err != testCase.expected { | 
					
						
							|  |  |  | 			t.Errorf("(%d) expected to get %s, instead got %s", i, niceError(testCase.expected), niceError(err)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |