• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "src/core/lib/security/credentials/external/aws_request_signer.h"
18 
19 #include <gmock/gmock.h>
20 #include <grpc/grpc_security.h>
21 
22 #include "test/core/util/test_config.h"
23 
24 namespace testing {
25 
26 namespace {
27 // Test cases of Aws endpoints that the aws-sourced credentials will depend
28 // on.
29 const char* kAmzTestAccessKeyId = "ASIARD4OQDT6A77FR3CL";
30 const char* kAmzTestSecretAccessKey =
31     "Y8AfSaucF37G4PpvfguKZ3/l7Id4uocLXxX0+VTx";
32 const char* kAmzTestToken =
33     "IQoJb3JpZ2luX2VjEIz//////////wEaCXVzLWVhc3QtMiJGMEQCIH7MHX/Oy/"
34     "OB8OlLQa9GrqU1B914+iMikqWQW7vPCKlgAiA/"
35     "Lsv8Jcafn14owfxXn95FURZNKaaphj0ykpmS+Ki+"
36     "CSq0AwhlEAAaDDA3NzA3MTM5MTk5NiIMx9sAeP1ovlMTMKLjKpEDwuJQg41/"
37     "QUKx0laTZYjPlQvjwSqS3OB9P1KAXPWSLkliVMMqaHqelvMF/WO/"
38     "glv3KwuTfQsavRNs3v5pcSEm4SPO3l7mCs7KrQUHwGP0neZhIKxEXy+Ls//1C/"
39     "Bqt53NL+LSbaGv6RPHaX82laz2qElphg95aVLdYgIFY6JWV5fzyjgnhz0DQmy62/"
40     "Vi8pNcM2/"
41     "VnxeCQ8CC8dRDSt52ry2v+nc77vstuI9xV5k8mPtnaPoJDRANh0bjwY5Sdwkbp+"
42     "mGRUJBAQRlNgHUJusefXQgVKBCiyJY4w3Csd8Bgj9IyDV+"
43     "Azuy1jQqfFZWgP68LSz5bURyIjlWDQunO82stZ0BgplKKAa/"
44     "KJHBPCp8Qi6i99uy7qh76FQAqgVTsnDuU6fGpHDcsDSGoCls2HgZjZFPeOj8mmRhFk1Xqvkb"
45     "juz8V1cJk54d3gIJvQt8gD2D6yJQZecnuGWd5K2e2HohvCc8Fc9kBl1300nUJPV+k4tr/"
46     "A5R/0QfEKOZL1/"
47     "k5lf1g9CREnrM8LVkGxCgdYMxLQow1uTL+QU67AHRRSp5PhhGX4Rek+"
48     "01vdYSnJCMaPhSEgcLqDlQkhk6MPsyT91QMXcWmyO+cAZwUPwnRamFepuP4K8k2KVXs/"
49     "LIJHLELwAZ0ekyaS7CptgOqS7uaSTFG3U+vzFZLEnGvWQ7y9IPNQZ+"
50     "Dffgh4p3vF4J68y9049sI6Sr5d5wbKkcbm8hdCDHZcv4lnqohquPirLiFQ3q7B17V9krMPu3"
51     "mz1cg4Ekgcrn/"
52     "E09NTsxAqD8NcZ7C7ECom9r+"
53     "X3zkDOxaajW6hu3Az8hGlyylDaMiFfRbBJpTIlxp7jfa7CxikNgNtEKLH9iCzvuSg2vhA==";
54 const char* kAmzTestDate = "20200811T065522Z";
55 
56 // Test cases derived from the Aws signature v4 test suite.
57 // https://github.com/boto/botocore/tree/master/tests/unit/auth/aws4_testsuite
58 const char* kBotoTestAccessKeyId = "AKIDEXAMPLE";
59 const char* kBotoTestSecretAccessKey =
60     "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY";
61 const char* kBotoTestToken = "";
62 const char* kBotoTestDate = "Mon, 09 Sep 2011 23:36:00 GMT";
63 }  // namespace
64 
65 // AWS official example from the developer doc.
66 // https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
TEST(GrpcAwsRequestSignerTest,AWSOfficialExample)67 TEST(GrpcAwsRequestSignerTest, AWSOfficialExample) {
68   grpc_error_handle error = GRPC_ERROR_NONE;
69   grpc_core::AwsRequestSigner signer(
70       "AKIDEXAMPLE", "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", "", "GET",
71       "https://iam.amazonaws.com/?Action=ListUsers&Version=2010-05-08",
72       "us-east-1", "",
73       {{"content-type", "application/x-www-form-urlencoded; charset=utf-8"},
74        {"x-amz-date", "20150830T123600Z"}},
75       &error);
76   EXPECT_EQ(error, GRPC_ERROR_NONE);
77   EXPECT_EQ(signer.GetSignedRequestHeaders()["Authorization"],
78             "AWS4-HMAC-SHA256 "
79             "Credential=AKIDEXAMPLE/20150830/us-east-1/iam/aws4_request, "
80             "SignedHeaders=content-type;host;x-amz-date, "
81             "Signature="
82             "5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7");
83 }
84 
TEST(GrpcAwsRequestSignerTest,GetDescribeRegions)85 TEST(GrpcAwsRequestSignerTest, GetDescribeRegions) {
86   grpc_error_handle error = GRPC_ERROR_NONE;
87   grpc_core::AwsRequestSigner signer(
88       kAmzTestAccessKeyId, kAmzTestSecretAccessKey, kAmzTestToken, "GET",
89       "https://"
90       "ec2.us-east-2.amazonaws.com?Action=DescribeRegions&Version=2013-10-15",
91       "us-east-2", "", {{"x-amz-date", kAmzTestDate}}, &error);
92   EXPECT_EQ(error, GRPC_ERROR_NONE);
93   EXPECT_EQ(
94       signer.GetSignedRequestHeaders()["Authorization"],
95       "AWS4-HMAC-SHA256 "
96       "Credential=ASIARD4OQDT6A77FR3CL/20200811/us-east-2/ec2/aws4_request, "
97       "SignedHeaders=host;x-amz-date;x-amz-security-token, "
98       "Signature="
99       "631ea80cddfaa545fdadb120dc92c9f18166e38a5c47b50fab9fce476e022855");
100 }
101 
TEST(GrpcAwsRequestSignerTest,PostGetCallerIdentity)102 TEST(GrpcAwsRequestSignerTest, PostGetCallerIdentity) {
103   grpc_error_handle error = GRPC_ERROR_NONE;
104   grpc_core::AwsRequestSigner signer(
105       kAmzTestAccessKeyId, kAmzTestSecretAccessKey, kAmzTestToken, "POST",
106       "https://"
107       "sts.us-east-2.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
108       "us-east-2", "", {{"x-amz-date", kAmzTestDate}}, &error);
109   EXPECT_EQ(error, GRPC_ERROR_NONE);
110   EXPECT_EQ(
111       signer.GetSignedRequestHeaders()["Authorization"],
112       "AWS4-HMAC-SHA256 "
113       "Credential=ASIARD4OQDT6A77FR3CL/20200811/us-east-2/sts/aws4_request, "
114       "SignedHeaders=host;x-amz-date;x-amz-security-token, "
115       "Signature="
116       "73452984e4a880ffdc5c392355733ec3f5ba310d5e0609a89244440cadfe7a7a");
117 }
118 
TEST(GrpcAwsRequestSignerTest,PostGetCallerIdentityNoToken)119 TEST(GrpcAwsRequestSignerTest, PostGetCallerIdentityNoToken) {
120   grpc_error_handle error = GRPC_ERROR_NONE;
121   grpc_core::AwsRequestSigner signer(
122       kAmzTestAccessKeyId, kAmzTestSecretAccessKey, "", "POST",
123       "https://"
124       "sts.us-east-2.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
125       "us-east-2", "", {{"x-amz-date", kAmzTestDate}}, &error);
126   EXPECT_EQ(error, GRPC_ERROR_NONE);
127   EXPECT_EQ(
128       signer.GetSignedRequestHeaders()["Authorization"],
129       "AWS4-HMAC-SHA256 "
130       "Credential=ASIARD4OQDT6A77FR3CL/20200811/us-east-2/sts/aws4_request, "
131       "SignedHeaders=host;x-amz-date, "
132       "Signature="
133       "d095ba304919cd0d5570ba8a3787884ee78b860f268ed040ba23831d55536d56");
134 }
135 
TEST(GrpcAwsRequestSignerTest,GetHost)136 TEST(GrpcAwsRequestSignerTest, GetHost) {
137   grpc_error_handle error = GRPC_ERROR_NONE;
138   grpc_core::AwsRequestSigner signer(kBotoTestAccessKeyId,
139                                      kBotoTestSecretAccessKey, kBotoTestToken,
140                                      "GET", "https://host.foo.com", "us-east-1",
141                                      "", {{"date", kBotoTestDate}}, &error);
142   EXPECT_EQ(error, GRPC_ERROR_NONE);
143   EXPECT_EQ(signer.GetSignedRequestHeaders()["Authorization"],
144             "AWS4-HMAC-SHA256 "
145             "Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, "
146             "SignedHeaders=date;host, "
147             "Signature="
148             "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470");
149 }
150 
TEST(GrpcAwsRequestSignerTest,GetHostDuplicateQueryParam)151 TEST(GrpcAwsRequestSignerTest, GetHostDuplicateQueryParam) {
152   grpc_error_handle error = GRPC_ERROR_NONE;
153   grpc_core::AwsRequestSigner signer(
154       kBotoTestAccessKeyId, kBotoTestSecretAccessKey, kBotoTestToken, "GET",
155       "https://host.foo.com/?foo=Zoo&foo=aha", "us-east-1", "",
156       {{"date", kBotoTestDate}}, &error);
157   EXPECT_EQ(error, GRPC_ERROR_NONE);
158   EXPECT_EQ(signer.GetSignedRequestHeaders()["Authorization"],
159             "AWS4-HMAC-SHA256 "
160             "Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, "
161             "SignedHeaders=date;host, "
162             "Signature="
163             "be7148d34ebccdc6423b19085378aa0bee970bdc61d144bd1a8c48c33079ab09");
164 }
165 
TEST(GrpcAwsRequestSignerTest,PostWithUpperCaseHeaderKey)166 TEST(GrpcAwsRequestSignerTest, PostWithUpperCaseHeaderKey) {
167   grpc_error_handle error = GRPC_ERROR_NONE;
168   grpc_core::AwsRequestSigner signer(
169       kBotoTestAccessKeyId, kBotoTestSecretAccessKey, kBotoTestToken, "POST",
170       "https://host.foo.com/", "us-east-1", "",
171       {{"date", kBotoTestDate}, {"ZOO", "zoobar"}}, &error);
172   EXPECT_EQ(error, GRPC_ERROR_NONE);
173   EXPECT_EQ(signer.GetSignedRequestHeaders()["Authorization"],
174             "AWS4-HMAC-SHA256 "
175             "Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, "
176             "SignedHeaders=date;host;zoo, "
177             "Signature="
178             "b7a95a52518abbca0964a999a880429ab734f35ebbf1235bd79a5de87756dc4a");
179 }
180 
TEST(GrpcAwsRequestSignerTest,PostWithUpperCaseHeaderValue)181 TEST(GrpcAwsRequestSignerTest, PostWithUpperCaseHeaderValue) {
182   grpc_error_handle error = GRPC_ERROR_NONE;
183   grpc_core::AwsRequestSigner signer(
184       kBotoTestAccessKeyId, kBotoTestSecretAccessKey, kBotoTestToken, "POST",
185       "https://host.foo.com/", "us-east-1", "",
186       {{"date", kBotoTestDate}, {"zoo", "ZOOBAR"}}, &error);
187   EXPECT_EQ(error, GRPC_ERROR_NONE);
188   EXPECT_EQ(signer.GetSignedRequestHeaders()["Authorization"],
189             "AWS4-HMAC-SHA256 "
190             "Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, "
191             "SignedHeaders=date;host;zoo, "
192             "Signature="
193             "273313af9d0c265c531e11db70bbd653f3ba074c1009239e8559d3987039cad7");
194 }
195 
TEST(GrpcAwsRequestSignerTest,SignPostWithHeader)196 TEST(GrpcAwsRequestSignerTest, SignPostWithHeader) {
197   grpc_error_handle error = GRPC_ERROR_NONE;
198   grpc_core::AwsRequestSigner signer(
199       kBotoTestAccessKeyId, kBotoTestSecretAccessKey, kBotoTestToken, "POST",
200       "https://host.foo.com/", "us-east-1", "",
201       {{"date", kBotoTestDate}, {"p", "phfft"}}, &error);
202   EXPECT_EQ(error, GRPC_ERROR_NONE);
203   EXPECT_EQ(signer.GetSignedRequestHeaders()["Authorization"],
204             "AWS4-HMAC-SHA256 "
205             "Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, "
206             "SignedHeaders=date;host;p, "
207             "Signature="
208             "debf546796015d6f6ded8626f5ce98597c33b47b9164cf6b17b4642036fcb592");
209 }
210 
TEST(GrpcAwsRequestSignerTest,PostWithBodyNoCustomHeaders)211 TEST(GrpcAwsRequestSignerTest, PostWithBodyNoCustomHeaders) {
212   grpc_error_handle error = GRPC_ERROR_NONE;
213   grpc_core::AwsRequestSigner signer(
214       kBotoTestAccessKeyId, kBotoTestSecretAccessKey, kBotoTestToken, "POST",
215       "https://host.foo.com/", "us-east-1", "foo=bar",
216       {{"date", kBotoTestDate},
217        {"Content-Type", "application/x-www-form-urlencoded"}},
218       &error);
219   EXPECT_EQ(error, GRPC_ERROR_NONE);
220   EXPECT_EQ(signer.GetSignedRequestHeaders()["Authorization"],
221             "AWS4-HMAC-SHA256 "
222             "Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, "
223             "SignedHeaders=content-type;date;host, "
224             "Signature="
225             "5a15b22cf462f047318703b92e6f4f38884e4a7ab7b1d6426ca46a8bd1c26cbc");
226 }
227 
TEST(GrpcAwsRequestSignerTest,SignPostWithQueryString)228 TEST(GrpcAwsRequestSignerTest, SignPostWithQueryString) {
229   grpc_error_handle error = GRPC_ERROR_NONE;
230   grpc_core::AwsRequestSigner signer(
231       kBotoTestAccessKeyId, kBotoTestSecretAccessKey, kBotoTestToken, "POST",
232       "https://host.foo.com/?foo=bar", "us-east-1", "",
233       {{"date", kBotoTestDate}}, &error);
234   EXPECT_EQ(error, GRPC_ERROR_NONE);
235   EXPECT_EQ(signer.GetSignedRequestHeaders()["Authorization"],
236             "AWS4-HMAC-SHA256 "
237             "Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, "
238             "SignedHeaders=date;host, "
239             "Signature="
240             "b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92");
241 }
242 
TEST(GrpcAwsRequestSignerTest,InvalidUrl)243 TEST(GrpcAwsRequestSignerTest, InvalidUrl) {
244   grpc_error_handle error = GRPC_ERROR_NONE;
245   grpc_core::AwsRequestSigner signer("access_key_id", "secret_access_key",
246                                      "token", "POST", "invalid_url",
247                                      "us-east-1", "", {}, &error);
248   grpc_slice expected_error_description =
249       grpc_slice_from_static_string("Invalid Aws request url.");
250   grpc_slice actual_error_description;
251   GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION,
252                                 &actual_error_description));
253   EXPECT_TRUE(grpc_slice_cmp(expected_error_description,
254                              actual_error_description) == 0);
255   GRPC_ERROR_UNREF(error);
256 }
257 
TEST(GrpcAwsRequestSignerTest,DuplicateRequestDate)258 TEST(GrpcAwsRequestSignerTest, DuplicateRequestDate) {
259   grpc_error_handle error = GRPC_ERROR_NONE;
260   grpc_core::AwsRequestSigner signer(
261       "access_key_id", "secret_access_key", "token", "POST", "invalid_url",
262       "us-east-1", "", {{"date", kBotoTestDate}, {"x-amz-date", kAmzTestDate}},
263       &error);
264   grpc_slice expected_error_description = grpc_slice_from_static_string(
265       "Only one of {date, x-amz-date} can be specified, not both.");
266   grpc_slice actual_error_description;
267   GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION,
268                                 &actual_error_description));
269   EXPECT_TRUE(grpc_slice_cmp(expected_error_description,
270                              actual_error_description) == 0);
271   GRPC_ERROR_UNREF(error);
272 }
273 
274 }  // namespace testing
275 
main(int argc,char ** argv)276 int main(int argc, char** argv) {
277   grpc::testing::TestEnvironment env(argc, argv);
278   ::testing::InitGoogleTest(&argc, argv);
279   grpc_init();
280   int ret = RUN_ALL_TESTS();
281   grpc_shutdown();
282   return ret;
283 }
284