Imported Upstream version 1.21.0
[platform/upstream/grpc.git] / test / core / security / credentials_test.cc
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 #include <grpc/support/port_platform.h>
20
21 #include "src/core/lib/security/credentials/credentials.h"
22
23 #include <openssl/rsa.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <grpc/slice.h>
28
29 #include <grpc/support/alloc.h>
30 #include <grpc/support/log.h>
31 #include <grpc/support/string_util.h>
32 #include <grpc/support/time.h>
33
34 #include "src/core/lib/gpr/env.h"
35 #include "src/core/lib/gpr/string.h"
36 #include "src/core/lib/gpr/tmpfile.h"
37 #include "src/core/lib/http/httpcli.h"
38 #include "src/core/lib/security/credentials/composite/composite_credentials.h"
39 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
40 #include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
41 #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
42 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
43 #include "src/core/lib/security/transport/auth_filters.h"
44 #include "test/core/util/test_config.h"
45
46 using grpc_core::internal::grpc_flush_cached_google_default_credentials;
47 using grpc_core::internal::set_gce_tenancy_checker_for_testing;
48
49 /* -- Constants. -- */
50
51 static const char test_google_iam_authorization_token[] = "blahblahblhahb";
52 static const char test_google_iam_authority_selector[] = "respectmyauthoritah";
53 static const char test_oauth2_bearer_token[] =
54     "Bearer blaaslkdjfaslkdfasdsfasf";
55
56 /* This JSON key was generated with the GCE console and revoked immediately.
57    The identifiers have been changed as well.
58    Maximum size for a string literal is 509 chars in C89, yay!  */
59 static const char test_json_key_str_part1[] =
60     "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----"
61     "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJE"
62     "qg"
63     "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\\nyjSeg/"
64     "rWBQvS4hle4LfijkP3J5BG+"
65     "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\\nOnVF6N7dL3nTYZg+"
66     "uQrNsMTz9UxVAgMBAAECgYEAzbLewe1xe9vy+2GoSsfib+28\\nDZgSE6Bu/"
67     "zuFoPrRc6qL9p2SsnV7txrunTyJkkOnPLND9ABAXybRTlcVKP/sGgza\\n/"
68     "8HpCqFYM9V8f34SBWfD4fRFT+n/"
69     "73cfRUtGXdXpseva2lh8RilIQfPhNZAncenU\\ngqXjDvpkypEusgXAykECQQD+";
70 static const char test_json_key_str_part2[] =
71     "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\\nCslxoHQM8s+"
72     "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\\nEkoy2L/"
73     "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDA"
74     "G"
75     "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6Hz"
76     "A"
77     "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\\n6z8RJm0+"
78     "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/"
79     "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZ"
80     "Y"
81     "Ap6LI9W\\nIqv4vr6y38N79TTC\\n-----END PRIVATE KEY-----\\n\", ";
82 static const char test_json_key_str_part3[] =
83     "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
84     "\"client_email\": "
85     "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
86     "com\", \"client_id\": "
87     "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
88     "com\", \"type\": \"service_account\" }";
89
90 /* Test refresh token. */
91 static const char test_refresh_token_str[] =
92     "{ \"client_id\": \"32555999999.apps.googleusercontent.com\","
93     "  \"client_secret\": \"EmssLNjJy1332hD4KFsecret\","
94     "  \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\","
95     "  \"type\": \"authorized_user\"}";
96
97 static const char valid_oauth2_json_response[] =
98     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
99     " \"expires_in\":3599, "
100     " \"token_type\":\"Bearer\"}";
101
102 static const char test_scope[] = "perm1 perm2";
103
104 static const char test_signed_jwt[] =
105     "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImY0OTRkN2M1YWU2MGRmOTcyNmM4YW"
106     "U0MDcyZTViYTdmZDkwODg2YzcifQ";
107
108 static const char test_service_url[] = "https://foo.com/foo.v1";
109 static const char other_test_service_url[] = "https://bar.com/bar.v1";
110
111 static const char test_method[] = "ThisIsNotAMethod";
112
113 /*  -- Global state flags. -- */
114
115 static bool g_test_is_on_gce = false;
116
117 static bool g_test_gce_tenancy_checker_called = false;
118
119 /* -- Utils. -- */
120
121 static char* test_json_key_str(void) {
122   size_t result_len = strlen(test_json_key_str_part1) +
123                       strlen(test_json_key_str_part2) +
124                       strlen(test_json_key_str_part3);
125   char* result = static_cast<char*>(gpr_malloc(result_len + 1));
126   char* current = result;
127   strcpy(result, test_json_key_str_part1);
128   current += strlen(test_json_key_str_part1);
129   strcpy(current, test_json_key_str_part2);
130   current += strlen(test_json_key_str_part2);
131   strcpy(current, test_json_key_str_part3);
132   return result;
133 }
134
135 static grpc_httpcli_response http_response(int status, const char* body) {
136   grpc_httpcli_response response;
137   memset(&response, 0, sizeof(grpc_httpcli_response));
138   response.status = status;
139   response.body = gpr_strdup(const_cast<char*>(body));
140   response.body_length = strlen(body);
141   return response;
142 }
143
144 /* -- Tests. -- */
145
146 static void test_empty_md_array(void) {
147   grpc_core::ExecCtx exec_ctx;
148   grpc_credentials_mdelem_array md_array;
149   memset(&md_array, 0, sizeof(md_array));
150   GPR_ASSERT(md_array.md == nullptr);
151   GPR_ASSERT(md_array.size == 0);
152   grpc_credentials_mdelem_array_destroy(&md_array);
153 }
154
155 static void test_add_to_empty_md_array(void) {
156   grpc_core::ExecCtx exec_ctx;
157   grpc_credentials_mdelem_array md_array;
158   memset(&md_array, 0, sizeof(md_array));
159   const char* key = "hello";
160   const char* value = "there blah blah blah blah blah blah blah";
161   grpc_mdelem md = grpc_mdelem_from_slices(
162       grpc_slice_from_copied_string(key), grpc_slice_from_copied_string(value));
163   grpc_credentials_mdelem_array_add(&md_array, md);
164   GPR_ASSERT(md_array.size == 1);
165   GPR_ASSERT(grpc_mdelem_eq(md, md_array.md[0]));
166   GRPC_MDELEM_UNREF(md);
167   grpc_credentials_mdelem_array_destroy(&md_array);
168 }
169
170 static void test_add_abunch_to_md_array(void) {
171   grpc_core::ExecCtx exec_ctx;
172   grpc_credentials_mdelem_array md_array;
173   memset(&md_array, 0, sizeof(md_array));
174   const char* key = "hello";
175   const char* value = "there blah blah blah blah blah blah blah";
176   grpc_mdelem md = grpc_mdelem_from_slices(
177       grpc_slice_from_copied_string(key), grpc_slice_from_copied_string(value));
178   size_t num_entries = 1000;
179   for (size_t i = 0; i < num_entries; ++i) {
180     grpc_credentials_mdelem_array_add(&md_array, md);
181   }
182   for (size_t i = 0; i < num_entries; ++i) {
183     GPR_ASSERT(grpc_mdelem_eq(md_array.md[i], md));
184   }
185   GRPC_MDELEM_UNREF(md);
186   grpc_credentials_mdelem_array_destroy(&md_array);
187 }
188
189 static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
190   grpc_core::ExecCtx exec_ctx;
191   grpc_mdelem token_md = GRPC_MDNULL;
192   grpc_millis token_lifetime;
193   grpc_httpcli_response response =
194       http_response(200, valid_oauth2_json_response);
195   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
196                  &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_OK);
197   GPR_ASSERT(token_lifetime == 3599 * GPR_MS_PER_SEC);
198   GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDKEY(token_md), "authorization") == 0);
199   GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDVALUE(token_md),
200                                 "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
201              0);
202   GRPC_MDELEM_UNREF(token_md);
203   grpc_http_response_destroy(&response);
204 }
205
206 static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
207   grpc_core::ExecCtx exec_ctx;
208   grpc_mdelem token_md = GRPC_MDNULL;
209   grpc_millis token_lifetime;
210   grpc_httpcli_response response =
211       http_response(401, valid_oauth2_json_response);
212   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
213                  &response, &token_md, &token_lifetime) ==
214              GRPC_CREDENTIALS_ERROR);
215   grpc_http_response_destroy(&response);
216 }
217
218 static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
219   grpc_core::ExecCtx exec_ctx;
220   grpc_mdelem token_md = GRPC_MDNULL;
221   grpc_millis token_lifetime;
222   grpc_httpcli_response response = http_response(200, "");
223   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
224                  &response, &token_md, &token_lifetime) ==
225              GRPC_CREDENTIALS_ERROR);
226   grpc_http_response_destroy(&response);
227 }
228
229 static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
230   grpc_core::ExecCtx exec_ctx;
231   grpc_mdelem token_md = GRPC_MDNULL;
232   grpc_millis token_lifetime;
233   grpc_httpcli_response response =
234       http_response(200,
235                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
236                     " \"expires_in\":3599, "
237                     " \"token_type\":\"Bearer\"");
238   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
239                  &response, &token_md, &token_lifetime) ==
240              GRPC_CREDENTIALS_ERROR);
241   grpc_http_response_destroy(&response);
242 }
243
244 static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
245   grpc_core::ExecCtx exec_ctx;
246   grpc_mdelem token_md = GRPC_MDNULL;
247   grpc_millis token_lifetime;
248   grpc_httpcli_response response = http_response(200,
249                                                  "{"
250                                                  " \"expires_in\":3599, "
251                                                  " \"token_type\":\"Bearer\"}");
252   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
253                  &response, &token_md, &token_lifetime) ==
254              GRPC_CREDENTIALS_ERROR);
255   grpc_http_response_destroy(&response);
256 }
257
258 static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
259   grpc_core::ExecCtx exec_ctx;
260   grpc_mdelem token_md = GRPC_MDNULL;
261   grpc_millis token_lifetime;
262   grpc_httpcli_response response =
263       http_response(200,
264                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
265                     " \"expires_in\":3599, "
266                     "}");
267   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
268                  &response, &token_md, &token_lifetime) ==
269              GRPC_CREDENTIALS_ERROR);
270   grpc_http_response_destroy(&response);
271 }
272
273 static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
274     void) {
275   grpc_core::ExecCtx exec_ctx;
276   grpc_mdelem token_md = GRPC_MDNULL;
277   grpc_millis token_lifetime;
278   grpc_httpcli_response response =
279       http_response(200,
280                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
281                     " \"token_type\":\"Bearer\"}");
282   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
283                  &response, &token_md, &token_lifetime) ==
284              GRPC_CREDENTIALS_ERROR);
285   grpc_http_response_destroy(&response);
286 }
287
288 typedef struct {
289   const char* key;
290   const char* value;
291 } expected_md;
292
293 typedef struct {
294   grpc_error* expected_error;
295   const expected_md* expected;
296   size_t expected_size;
297   grpc_credentials_mdelem_array md_array;
298   grpc_closure on_request_metadata;
299   grpc_call_credentials* creds;
300   grpc_polling_entity pollent;
301 } request_metadata_state;
302
303 static void check_metadata(const expected_md* expected,
304                            grpc_credentials_mdelem_array* md_array) {
305   for (size_t i = 0; i < md_array->size; ++i) {
306     size_t j;
307     for (j = 0; j < md_array->size; ++j) {
308       if (0 ==
309           grpc_slice_str_cmp(GRPC_MDKEY(md_array->md[j]), expected[i].key)) {
310         GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDVALUE(md_array->md[j]),
311                                       expected[i].value) == 0);
312         break;
313       }
314     }
315     if (j == md_array->size) {
316       gpr_log(GPR_ERROR, "key %s not found", expected[i].key);
317       GPR_ASSERT(0);
318     }
319   }
320 }
321
322 static void check_request_metadata(void* arg, grpc_error* error) {
323   request_metadata_state* state = static_cast<request_metadata_state*>(arg);
324   gpr_log(GPR_INFO, "expected_error: %s",
325           grpc_error_string(state->expected_error));
326   gpr_log(GPR_INFO, "actual_error: %s", grpc_error_string(error));
327   if (state->expected_error == GRPC_ERROR_NONE) {
328     GPR_ASSERT(error == GRPC_ERROR_NONE);
329   } else {
330     grpc_slice expected_error;
331     GPR_ASSERT(grpc_error_get_str(state->expected_error,
332                                   GRPC_ERROR_STR_DESCRIPTION, &expected_error));
333     grpc_slice actual_error;
334     GPR_ASSERT(
335         grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION, &actual_error));
336     GPR_ASSERT(grpc_slice_cmp(expected_error, actual_error) == 0);
337     GRPC_ERROR_UNREF(state->expected_error);
338   }
339   gpr_log(GPR_INFO, "expected_size=%" PRIdPTR " actual_size=%" PRIdPTR,
340           state->expected_size, state->md_array.size);
341   GPR_ASSERT(state->md_array.size == state->expected_size);
342   check_metadata(state->expected, &state->md_array);
343   grpc_credentials_mdelem_array_destroy(&state->md_array);
344   grpc_pollset_set_destroy(grpc_polling_entity_pollset_set(&state->pollent));
345   gpr_free(state);
346 }
347
348 static request_metadata_state* make_request_metadata_state(
349     grpc_error* expected_error, const expected_md* expected,
350     size_t expected_size) {
351   request_metadata_state* state =
352       static_cast<request_metadata_state*>(gpr_zalloc(sizeof(*state)));
353   state->expected_error = expected_error;
354   state->expected = expected;
355   state->expected_size = expected_size;
356   state->pollent =
357       grpc_polling_entity_create_from_pollset_set(grpc_pollset_set_create());
358   GRPC_CLOSURE_INIT(&state->on_request_metadata, check_request_metadata, state,
359                     grpc_schedule_on_exec_ctx);
360   return state;
361 }
362
363 static void run_request_metadata_test(grpc_call_credentials* creds,
364                                       grpc_auth_metadata_context auth_md_ctx,
365                                       request_metadata_state* state) {
366   grpc_error* error = GRPC_ERROR_NONE;
367   if (creds->get_request_metadata(&state->pollent, auth_md_ctx,
368                                   &state->md_array, &state->on_request_metadata,
369                                   &error)) {
370     // Synchronous result.  Invoke the callback directly.
371     check_request_metadata(state, error);
372     GRPC_ERROR_UNREF(error);
373   }
374 }
375
376 static void test_google_iam_creds(void) {
377   grpc_core::ExecCtx exec_ctx;
378   expected_md emd[] = {{GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
379                         test_google_iam_authorization_token},
380                        {GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
381                         test_google_iam_authority_selector}};
382   request_metadata_state* state =
383       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
384   grpc_call_credentials* creds = grpc_google_iam_credentials_create(
385       test_google_iam_authorization_token, test_google_iam_authority_selector,
386       nullptr);
387   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
388                                             nullptr, nullptr};
389   run_request_metadata_test(creds, auth_md_ctx, state);
390   creds->Unref();
391 }
392
393 static void test_access_token_creds(void) {
394   grpc_core::ExecCtx exec_ctx;
395   expected_md emd[] = {{GRPC_AUTHORIZATION_METADATA_KEY, "Bearer blah"}};
396   request_metadata_state* state =
397       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
398   grpc_call_credentials* creds =
399       grpc_access_token_credentials_create("blah", nullptr);
400   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
401                                             nullptr, nullptr};
402   GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
403   run_request_metadata_test(creds, auth_md_ctx, state);
404   creds->Unref();
405 }
406
407 namespace {
408 class check_channel_oauth2 final : public grpc_channel_credentials {
409  public:
410   check_channel_oauth2() : grpc_channel_credentials("mock") {}
411   ~check_channel_oauth2() override = default;
412
413   grpc_core::RefCountedPtr<grpc_channel_security_connector>
414   create_security_connector(
415       grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
416       const char* target, const grpc_channel_args* args,
417       grpc_channel_args** new_args) override {
418     GPR_ASSERT(strcmp(type(), "mock") == 0);
419     GPR_ASSERT(call_creds != nullptr);
420     GPR_ASSERT(strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) ==
421                0);
422     return nullptr;
423   }
424 };
425 }  // namespace
426
427 static void test_channel_oauth2_composite_creds(void) {
428   grpc_core::ExecCtx exec_ctx;
429   grpc_channel_args* new_args;
430   grpc_channel_credentials* channel_creds =
431       grpc_core::New<check_channel_oauth2>();
432   grpc_call_credentials* oauth2_creds =
433       grpc_access_token_credentials_create("blah", nullptr);
434   grpc_channel_credentials* channel_oauth2_creds =
435       grpc_composite_channel_credentials_create(channel_creds, oauth2_creds,
436                                                 nullptr);
437   grpc_channel_credentials_release(channel_creds);
438   grpc_call_credentials_release(oauth2_creds);
439   channel_oauth2_creds->create_security_connector(nullptr, nullptr, nullptr,
440                                                   &new_args);
441   grpc_channel_credentials_release(channel_oauth2_creds);
442 }
443
444 static void test_oauth2_google_iam_composite_creds(void) {
445   grpc_core::ExecCtx exec_ctx;
446   expected_md emd[] = {
447       {GRPC_AUTHORIZATION_METADATA_KEY, test_oauth2_bearer_token},
448       {GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
449        test_google_iam_authorization_token},
450       {GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
451        test_google_iam_authority_selector}};
452   request_metadata_state* state =
453       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
454   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
455                                             nullptr, nullptr};
456   grpc_call_credentials* oauth2_creds = grpc_md_only_test_credentials_create(
457       "authorization", test_oauth2_bearer_token, 0);
458   grpc_call_credentials* google_iam_creds = grpc_google_iam_credentials_create(
459       test_google_iam_authorization_token, test_google_iam_authority_selector,
460       nullptr);
461   grpc_call_credentials* composite_creds =
462       grpc_composite_call_credentials_create(oauth2_creds, google_iam_creds,
463                                              nullptr);
464   oauth2_creds->Unref();
465   google_iam_creds->Unref();
466   GPR_ASSERT(strcmp(composite_creds->type(),
467                     GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
468   const grpc_composite_call_credentials::CallCredentialsList& creds_list =
469       static_cast<const grpc_composite_call_credentials*>(composite_creds)
470           ->inner();
471   GPR_ASSERT(creds_list.size() == 2);
472   GPR_ASSERT(strcmp(creds_list[0]->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) ==
473              0);
474   GPR_ASSERT(strcmp(creds_list[1]->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) ==
475              0);
476   run_request_metadata_test(composite_creds, auth_md_ctx, state);
477   composite_creds->Unref();
478 }
479
480 namespace {
481 class check_channel_oauth2_google_iam final : public grpc_channel_credentials {
482  public:
483   check_channel_oauth2_google_iam() : grpc_channel_credentials("mock") {}
484   ~check_channel_oauth2_google_iam() override = default;
485
486   grpc_core::RefCountedPtr<grpc_channel_security_connector>
487   create_security_connector(
488       grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
489       const char* target, const grpc_channel_args* args,
490       grpc_channel_args** new_args) override {
491     GPR_ASSERT(strcmp(type(), "mock") == 0);
492     GPR_ASSERT(call_creds != nullptr);
493     GPR_ASSERT(
494         strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
495     const grpc_composite_call_credentials::CallCredentialsList& creds_list =
496         static_cast<const grpc_composite_call_credentials*>(call_creds.get())
497             ->inner();
498     GPR_ASSERT(
499         strcmp(creds_list[0]->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
500     GPR_ASSERT(strcmp(creds_list[1]->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) ==
501                0);
502     return nullptr;
503   }
504 };
505 }  // namespace
506
507 static void test_channel_oauth2_google_iam_composite_creds(void) {
508   grpc_core::ExecCtx exec_ctx;
509   grpc_channel_args* new_args;
510   grpc_channel_credentials* channel_creds =
511       grpc_core::New<check_channel_oauth2_google_iam>();
512   grpc_call_credentials* oauth2_creds =
513       grpc_access_token_credentials_create("blah", nullptr);
514   grpc_channel_credentials* channel_oauth2_creds =
515       grpc_composite_channel_credentials_create(channel_creds, oauth2_creds,
516                                                 nullptr);
517   grpc_call_credentials* google_iam_creds = grpc_google_iam_credentials_create(
518       test_google_iam_authorization_token, test_google_iam_authority_selector,
519       nullptr);
520   grpc_channel_credentials* channel_oauth2_iam_creds =
521       grpc_composite_channel_credentials_create(channel_oauth2_creds,
522                                                 google_iam_creds, nullptr);
523   grpc_channel_credentials_release(channel_creds);
524   grpc_call_credentials_release(oauth2_creds);
525   grpc_channel_credentials_release(channel_oauth2_creds);
526   grpc_call_credentials_release(google_iam_creds);
527
528   channel_oauth2_iam_creds->create_security_connector(nullptr, nullptr, nullptr,
529                                                       &new_args);
530
531   grpc_channel_credentials_release(channel_oauth2_iam_creds);
532 }
533
534 static void validate_compute_engine_http_request(
535     const grpc_httpcli_request* request) {
536   GPR_ASSERT(request->handshaker != &grpc_httpcli_ssl);
537   GPR_ASSERT(strcmp(request->host, "metadata.google.internal.") == 0);
538   GPR_ASSERT(
539       strcmp(request->http.path,
540              "/computeMetadata/v1/instance/service-accounts/default/token") ==
541       0);
542   GPR_ASSERT(request->http.hdr_count == 1);
543   GPR_ASSERT(strcmp(request->http.hdrs[0].key, "Metadata-Flavor") == 0);
544   GPR_ASSERT(strcmp(request->http.hdrs[0].value, "Google") == 0);
545 }
546
547 static int compute_engine_httpcli_get_success_override(
548     const grpc_httpcli_request* request, grpc_millis deadline,
549     grpc_closure* on_done, grpc_httpcli_response* response) {
550   validate_compute_engine_http_request(request);
551   *response = http_response(200, valid_oauth2_json_response);
552   GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
553   return 1;
554 }
555
556 static int compute_engine_httpcli_get_failure_override(
557     const grpc_httpcli_request* request, grpc_millis deadline,
558     grpc_closure* on_done, grpc_httpcli_response* response) {
559   validate_compute_engine_http_request(request);
560   *response = http_response(403, "Not Authorized.");
561   GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
562   return 1;
563 }
564
565 static int httpcli_post_should_not_be_called(
566     const grpc_httpcli_request* request, const char* body_bytes,
567     size_t body_size, grpc_millis deadline, grpc_closure* on_done,
568     grpc_httpcli_response* response) {
569   GPR_ASSERT("HTTP POST should not be called" == nullptr);
570   return 1;
571 }
572
573 static int httpcli_get_should_not_be_called(const grpc_httpcli_request* request,
574                                             grpc_millis deadline,
575                                             grpc_closure* on_done,
576                                             grpc_httpcli_response* response) {
577   GPR_ASSERT("HTTP GET should not be called" == nullptr);
578   return 1;
579 }
580
581 static void test_compute_engine_creds_success() {
582   grpc_core::ExecCtx exec_ctx;
583   expected_md emd[] = {
584       {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}};
585   grpc_call_credentials* creds =
586       grpc_google_compute_engine_credentials_create(nullptr);
587   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
588                                             nullptr, nullptr};
589
590   /* First request: http get should be called. */
591   request_metadata_state* state =
592       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
593   grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
594                             httpcli_post_should_not_be_called);
595   run_request_metadata_test(creds, auth_md_ctx, state);
596   grpc_core::ExecCtx::Get()->Flush();
597
598   /* Second request: the cached token should be served directly. */
599   state =
600       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
601   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
602                             httpcli_post_should_not_be_called);
603   run_request_metadata_test(creds, auth_md_ctx, state);
604   grpc_core::ExecCtx::Get()->Flush();
605
606   creds->Unref();
607   grpc_httpcli_set_override(nullptr, nullptr);
608 }
609
610 static void test_compute_engine_creds_failure(void) {
611   grpc_core::ExecCtx exec_ctx;
612   request_metadata_state* state = make_request_metadata_state(
613       GRPC_ERROR_CREATE_FROM_STATIC_STRING(
614           "Error occurred when fetching oauth2 token."),
615       nullptr, 0);
616   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
617                                             nullptr, nullptr};
618   grpc_call_credentials* creds =
619       grpc_google_compute_engine_credentials_create(nullptr);
620   grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
621                             httpcli_post_should_not_be_called);
622   run_request_metadata_test(creds, auth_md_ctx, state);
623   creds->Unref();
624   grpc_httpcli_set_override(nullptr, nullptr);
625 }
626
627 static void validate_refresh_token_http_request(
628     const grpc_httpcli_request* request, const char* body, size_t body_size) {
629   /* The content of the assertion is tested extensively in json_token_test. */
630   char* expected_body = nullptr;
631   GPR_ASSERT(body != nullptr);
632   GPR_ASSERT(body_size != 0);
633   gpr_asprintf(&expected_body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
634                "32555999999.apps.googleusercontent.com",
635                "EmssLNjJy1332hD4KFsecret",
636                "1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42");
637   GPR_ASSERT(strlen(expected_body) == body_size);
638   GPR_ASSERT(memcmp(expected_body, body, body_size) == 0);
639   gpr_free(expected_body);
640   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
641   GPR_ASSERT(strcmp(request->host, GRPC_GOOGLE_OAUTH2_SERVICE_HOST) == 0);
642   GPR_ASSERT(
643       strcmp(request->http.path, GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH) == 0);
644   GPR_ASSERT(request->http.hdr_count == 1);
645   GPR_ASSERT(strcmp(request->http.hdrs[0].key, "Content-Type") == 0);
646   GPR_ASSERT(strcmp(request->http.hdrs[0].value,
647                     "application/x-www-form-urlencoded") == 0);
648 }
649
650 static int refresh_token_httpcli_post_success(
651     const grpc_httpcli_request* request, const char* body, size_t body_size,
652     grpc_millis deadline, grpc_closure* on_done,
653     grpc_httpcli_response* response) {
654   validate_refresh_token_http_request(request, body, body_size);
655   *response = http_response(200, valid_oauth2_json_response);
656   GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
657   return 1;
658 }
659
660 static int refresh_token_httpcli_post_failure(
661     const grpc_httpcli_request* request, const char* body, size_t body_size,
662     grpc_millis deadline, grpc_closure* on_done,
663     grpc_httpcli_response* response) {
664   validate_refresh_token_http_request(request, body, body_size);
665   *response = http_response(403, "Not Authorized.");
666   GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
667   return 1;
668 }
669
670 static void test_refresh_token_creds_success(void) {
671   grpc_core::ExecCtx exec_ctx;
672   expected_md emd[] = {
673       {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}};
674   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
675                                             nullptr, nullptr};
676   grpc_call_credentials* creds = grpc_google_refresh_token_credentials_create(
677       test_refresh_token_str, nullptr);
678
679   /* First request: http get should be called. */
680   request_metadata_state* state =
681       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
682   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
683                             refresh_token_httpcli_post_success);
684   run_request_metadata_test(creds, auth_md_ctx, state);
685   grpc_core::ExecCtx::Get()->Flush();
686
687   /* Second request: the cached token should be served directly. */
688   state =
689       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
690   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
691                             httpcli_post_should_not_be_called);
692   run_request_metadata_test(creds, auth_md_ctx, state);
693   grpc_core::ExecCtx::Get()->Flush();
694
695   creds->Unref();
696   grpc_httpcli_set_override(nullptr, nullptr);
697 }
698
699 static void test_refresh_token_creds_failure(void) {
700   grpc_core::ExecCtx exec_ctx;
701   request_metadata_state* state = make_request_metadata_state(
702       GRPC_ERROR_CREATE_FROM_STATIC_STRING(
703           "Error occurred when fetching oauth2 token."),
704       nullptr, 0);
705   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
706                                             nullptr, nullptr};
707   grpc_call_credentials* creds = grpc_google_refresh_token_credentials_create(
708       test_refresh_token_str, nullptr);
709   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
710                             refresh_token_httpcli_post_failure);
711   run_request_metadata_test(creds, auth_md_ctx, state);
712   creds->Unref();
713   grpc_httpcli_set_override(nullptr, nullptr);
714 }
715
716 static void validate_jwt_encode_and_sign_params(
717     const grpc_auth_json_key* json_key, const char* scope,
718     gpr_timespec token_lifetime) {
719   GPR_ASSERT(grpc_auth_json_key_is_valid(json_key));
720   GPR_ASSERT(json_key->private_key != nullptr);
721   GPR_ASSERT(RSA_check_key(json_key->private_key));
722   GPR_ASSERT(json_key->type != nullptr &&
723              strcmp(json_key->type, "service_account") == 0);
724   GPR_ASSERT(json_key->private_key_id != nullptr &&
725              strcmp(json_key->private_key_id,
726                     "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
727   GPR_ASSERT(json_key->client_id != nullptr &&
728              strcmp(json_key->client_id,
729                     "777-abaslkan11hlb6nmim3bpspl31ud.apps."
730                     "googleusercontent.com") == 0);
731   GPR_ASSERT(json_key->client_email != nullptr &&
732              strcmp(json_key->client_email,
733                     "777-abaslkan11hlb6nmim3bpspl31ud@developer."
734                     "gserviceaccount.com") == 0);
735   if (scope != nullptr) GPR_ASSERT(strcmp(scope, test_scope) == 0);
736   GPR_ASSERT(!gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime()));
737 }
738
739 static char* encode_and_sign_jwt_success(const grpc_auth_json_key* json_key,
740                                          const char* audience,
741                                          gpr_timespec token_lifetime,
742                                          const char* scope) {
743   validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
744   return gpr_strdup(test_signed_jwt);
745 }
746
747 static char* encode_and_sign_jwt_failure(const grpc_auth_json_key* json_key,
748                                          const char* audience,
749                                          gpr_timespec token_lifetime,
750                                          const char* scope) {
751   validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
752   return nullptr;
753 }
754
755 static char* encode_and_sign_jwt_should_not_be_called(
756     const grpc_auth_json_key* json_key, const char* audience,
757     gpr_timespec token_lifetime, const char* scope) {
758   GPR_ASSERT("grpc_jwt_encode_and_sign should not be called" == nullptr);
759   return nullptr;
760 }
761
762 static grpc_service_account_jwt_access_credentials* creds_as_jwt(
763     grpc_call_credentials* creds) {
764   GPR_ASSERT(creds != nullptr);
765   GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0);
766   return reinterpret_cast<grpc_service_account_jwt_access_credentials*>(creds);
767 }
768
769 static void test_jwt_creds_lifetime(void) {
770   char* json_key_string = test_json_key_str();
771
772   // Max lifetime.
773   grpc_call_credentials* jwt_creds =
774       grpc_service_account_jwt_access_credentials_create(
775           json_key_string, grpc_max_auth_token_lifetime(), nullptr);
776   GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(),
777                           grpc_max_auth_token_lifetime()) == 0);
778   grpc_call_credentials_release(jwt_creds);
779
780   // Shorter lifetime.
781   gpr_timespec token_lifetime = {10, 0, GPR_TIMESPAN};
782   GPR_ASSERT(gpr_time_cmp(grpc_max_auth_token_lifetime(), token_lifetime) > 0);
783   jwt_creds = grpc_service_account_jwt_access_credentials_create(
784       json_key_string, token_lifetime, nullptr);
785   GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(),
786                           token_lifetime) == 0);
787   grpc_call_credentials_release(jwt_creds);
788
789   // Cropped lifetime.
790   gpr_timespec add_to_max = {10, 0, GPR_TIMESPAN};
791   token_lifetime = gpr_time_add(grpc_max_auth_token_lifetime(), add_to_max);
792   jwt_creds = grpc_service_account_jwt_access_credentials_create(
793       json_key_string, token_lifetime, nullptr);
794   GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(),
795                           grpc_max_auth_token_lifetime()) == 0);
796   grpc_call_credentials_release(jwt_creds);
797
798   gpr_free(json_key_string);
799 }
800
801 static void test_jwt_creds_success(void) {
802   char* json_key_string = test_json_key_str();
803   grpc_core::ExecCtx exec_ctx;
804   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
805                                             nullptr, nullptr};
806   char* expected_md_value;
807   gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt);
808   expected_md emd[] = {{"authorization", expected_md_value}};
809   grpc_call_credentials* creds =
810       grpc_service_account_jwt_access_credentials_create(
811           json_key_string, grpc_max_auth_token_lifetime(), nullptr);
812
813   /* First request: jwt_encode_and_sign should be called. */
814   request_metadata_state* state =
815       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
816   grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
817   run_request_metadata_test(creds, auth_md_ctx, state);
818   grpc_core::ExecCtx::Get()->Flush();
819
820   /* Second request: the cached token should be served directly. */
821   state =
822       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
823   grpc_jwt_encode_and_sign_set_override(
824       encode_and_sign_jwt_should_not_be_called);
825   run_request_metadata_test(creds, auth_md_ctx, state);
826   grpc_core::ExecCtx::Get()->Flush();
827
828   /* Third request: Different service url so jwt_encode_and_sign should be
829      called again (no caching). */
830   state =
831       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
832   auth_md_ctx.service_url = other_test_service_url;
833   grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
834   run_request_metadata_test(creds, auth_md_ctx, state);
835   grpc_core::ExecCtx::Get()->Flush();
836
837   creds->Unref();
838   gpr_free(json_key_string);
839   gpr_free(expected_md_value);
840   grpc_jwt_encode_and_sign_set_override(nullptr);
841 }
842
843 static void test_jwt_creds_signing_failure(void) {
844   char* json_key_string = test_json_key_str();
845   grpc_core::ExecCtx exec_ctx;
846   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
847                                             nullptr, nullptr};
848   request_metadata_state* state = make_request_metadata_state(
849       GRPC_ERROR_CREATE_FROM_STATIC_STRING("Could not generate JWT."), nullptr,
850       0);
851   grpc_call_credentials* creds =
852       grpc_service_account_jwt_access_credentials_create(
853           json_key_string, grpc_max_auth_token_lifetime(), nullptr);
854
855   grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure);
856   run_request_metadata_test(creds, auth_md_ctx, state);
857
858   gpr_free(json_key_string);
859   creds->Unref();
860   grpc_jwt_encode_and_sign_set_override(nullptr);
861 }
862
863 static void set_google_default_creds_env_var_with_file_contents(
864     const char* file_prefix, const char* contents) {
865   size_t contents_len = strlen(contents);
866   char* creds_file_name;
867   FILE* creds_file = gpr_tmpfile(file_prefix, &creds_file_name);
868   GPR_ASSERT(creds_file_name != nullptr);
869   GPR_ASSERT(creds_file != nullptr);
870   GPR_ASSERT(fwrite(contents, 1, contents_len, creds_file) == contents_len);
871   fclose(creds_file);
872   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, creds_file_name);
873   gpr_free(creds_file_name);
874 }
875
876 static void test_google_default_creds_auth_key(void) {
877   grpc_core::ExecCtx exec_ctx;
878   grpc_composite_channel_credentials* creds;
879   char* json_key = test_json_key_str();
880   grpc_flush_cached_google_default_credentials();
881   set_google_default_creds_env_var_with_file_contents(
882       "json_key_google_default_creds", json_key);
883   gpr_free(json_key);
884   creds = reinterpret_cast<grpc_composite_channel_credentials*>(
885       grpc_google_default_credentials_create());
886   auto* default_creds =
887       reinterpret_cast<const grpc_google_default_channel_credentials*>(
888           creds->inner_creds());
889   GPR_ASSERT(default_creds->ssl_creds() != nullptr);
890   auto* jwt =
891       reinterpret_cast<const grpc_service_account_jwt_access_credentials*>(
892           creds->call_creds());
893   GPR_ASSERT(
894       strcmp(jwt->key().client_id,
895              "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") ==
896       0);
897   creds->Unref();
898   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
899 }
900
901 static void test_google_default_creds_refresh_token(void) {
902   grpc_core::ExecCtx exec_ctx;
903   grpc_composite_channel_credentials* creds;
904   grpc_flush_cached_google_default_credentials();
905   set_google_default_creds_env_var_with_file_contents(
906       "refresh_token_google_default_creds", test_refresh_token_str);
907   creds = reinterpret_cast<grpc_composite_channel_credentials*>(
908       grpc_google_default_credentials_create());
909   auto* default_creds =
910       reinterpret_cast<const grpc_google_default_channel_credentials*>(
911           creds->inner_creds());
912   GPR_ASSERT(default_creds->ssl_creds() != nullptr);
913   auto* refresh =
914       reinterpret_cast<const grpc_google_refresh_token_credentials*>(
915           creds->call_creds());
916   GPR_ASSERT(strcmp(refresh->refresh_token().client_id,
917                     "32555999999.apps.googleusercontent.com") == 0);
918   creds->Unref();
919   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
920 }
921
922 static int default_creds_metadata_server_detection_httpcli_get_success_override(
923     const grpc_httpcli_request* request, grpc_millis deadline,
924     grpc_closure* on_done, grpc_httpcli_response* response) {
925   *response = http_response(200, "");
926   grpc_http_header* headers =
927       static_cast<grpc_http_header*>(gpr_malloc(sizeof(*headers) * 1));
928   headers[0].key = gpr_strdup("Metadata-Flavor");
929   headers[0].value = gpr_strdup("Google");
930   response->hdr_count = 1;
931   response->hdrs = headers;
932   GPR_ASSERT(strcmp(request->http.path, "/") == 0);
933   GPR_ASSERT(strcmp(request->host, "metadata.google.internal.") == 0);
934   GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
935   return 1;
936 }
937
938 static char* null_well_known_creds_path_getter(void) { return nullptr; }
939
940 static bool test_gce_tenancy_checker(void) {
941   g_test_gce_tenancy_checker_called = true;
942   return g_test_is_on_gce;
943 }
944
945 static void test_google_default_creds_gce(void) {
946   grpc_core::ExecCtx exec_ctx;
947   expected_md emd[] = {
948       {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}};
949   request_metadata_state* state =
950       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
951   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
952                                             nullptr, nullptr};
953   grpc_flush_cached_google_default_credentials();
954   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
955   grpc_override_well_known_credentials_path_getter(
956       null_well_known_creds_path_getter);
957   set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
958   g_test_gce_tenancy_checker_called = false;
959   g_test_is_on_gce = true;
960
961   /* Simulate a successful detection of GCE. */
962   grpc_composite_channel_credentials* creds =
963       reinterpret_cast<grpc_composite_channel_credentials*>(
964           grpc_google_default_credentials_create());
965
966   /* Verify that the default creds actually embeds a GCE creds. */
967   GPR_ASSERT(creds != nullptr);
968   GPR_ASSERT(creds->call_creds() != nullptr);
969   grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
970                             httpcli_post_should_not_be_called);
971   run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state);
972   grpc_core::ExecCtx::Get()->Flush();
973
974   GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
975
976   /* Cleanup. */
977   creds->Unref();
978   grpc_httpcli_set_override(nullptr, nullptr);
979   grpc_override_well_known_credentials_path_getter(nullptr);
980 }
981
982 static void test_google_default_creds_non_gce(void) {
983   grpc_core::ExecCtx exec_ctx;
984   expected_md emd[] = {
985       {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}};
986   request_metadata_state* state =
987       make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
988   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
989                                             nullptr, nullptr};
990   grpc_flush_cached_google_default_credentials();
991   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
992   grpc_override_well_known_credentials_path_getter(
993       null_well_known_creds_path_getter);
994   set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
995   g_test_gce_tenancy_checker_called = false;
996   g_test_is_on_gce = false;
997   /* Simulate a successful detection of metadata server. */
998   grpc_httpcli_set_override(
999       default_creds_metadata_server_detection_httpcli_get_success_override,
1000       httpcli_post_should_not_be_called);
1001   grpc_composite_channel_credentials* creds =
1002       reinterpret_cast<grpc_composite_channel_credentials*>(
1003           grpc_google_default_credentials_create());
1004   /* Verify that the default creds actually embeds a GCE creds. */
1005   GPR_ASSERT(creds != nullptr);
1006   GPR_ASSERT(creds->call_creds() != nullptr);
1007   grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
1008                             httpcli_post_should_not_be_called);
1009   run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state);
1010   grpc_core::ExecCtx::Get()->Flush();
1011   GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
1012   /* Cleanup. */
1013   creds->Unref();
1014   grpc_httpcli_set_override(nullptr, nullptr);
1015   grpc_override_well_known_credentials_path_getter(nullptr);
1016 }
1017
1018 static int default_creds_gce_detection_httpcli_get_failure_override(
1019     const grpc_httpcli_request* request, grpc_millis deadline,
1020     grpc_closure* on_done, grpc_httpcli_response* response) {
1021   /* No magic header. */
1022   GPR_ASSERT(strcmp(request->http.path, "/") == 0);
1023   GPR_ASSERT(strcmp(request->host, "metadata.google.internal.") == 0);
1024   *response = http_response(200, "");
1025   GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
1026   return 1;
1027 }
1028
1029 static void test_no_google_default_creds(void) {
1030   grpc_flush_cached_google_default_credentials();
1031   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
1032   grpc_override_well_known_credentials_path_getter(
1033       null_well_known_creds_path_getter);
1034   set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
1035   g_test_gce_tenancy_checker_called = false;
1036   g_test_is_on_gce = false;
1037   grpc_httpcli_set_override(
1038       default_creds_gce_detection_httpcli_get_failure_override,
1039       httpcli_post_should_not_be_called);
1040   /* Simulate a successful detection of GCE. */
1041   GPR_ASSERT(grpc_google_default_credentials_create() == nullptr);
1042   /* Try a second one. GCE detection should occur again. */
1043   g_test_gce_tenancy_checker_called = false;
1044   GPR_ASSERT(grpc_google_default_credentials_create() == nullptr);
1045   GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
1046   /* Cleanup. */
1047   grpc_override_well_known_credentials_path_getter(nullptr);
1048   grpc_httpcli_set_override(nullptr, nullptr);
1049 }
1050
1051 typedef enum {
1052   PLUGIN_INITIAL_STATE,
1053   PLUGIN_GET_METADATA_CALLED_STATE,
1054   PLUGIN_DESTROY_CALLED_STATE
1055 } plugin_state;
1056
1057 static const expected_md plugin_md[] = {{"foo", "bar"}, {"hi", "there"}};
1058
1059 static int plugin_get_metadata_success(
1060     void* state, grpc_auth_metadata_context context,
1061     grpc_credentials_plugin_metadata_cb cb, void* user_data,
1062     grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX],
1063     size_t* num_creds_md, grpc_status_code* status,
1064     const char** error_details) {
1065   GPR_ASSERT(strcmp(context.service_url, test_service_url) == 0);
1066   GPR_ASSERT(strcmp(context.method_name, test_method) == 0);
1067   GPR_ASSERT(context.channel_auth_context == nullptr);
1068   GPR_ASSERT(context.reserved == nullptr);
1069   GPR_ASSERT(GPR_ARRAY_SIZE(plugin_md) <
1070              GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX);
1071   plugin_state* s = static_cast<plugin_state*>(state);
1072   *s = PLUGIN_GET_METADATA_CALLED_STATE;
1073   for (size_t i = 0; i < GPR_ARRAY_SIZE(plugin_md); ++i) {
1074     memset(&creds_md[i], 0, sizeof(grpc_metadata));
1075     creds_md[i].key = grpc_slice_from_copied_string(plugin_md[i].key);
1076     creds_md[i].value = grpc_slice_from_copied_string(plugin_md[i].value);
1077   }
1078   *num_creds_md = GPR_ARRAY_SIZE(plugin_md);
1079   return true;  // Synchronous return.
1080 }
1081
1082 static const char* plugin_error_details = "Could not get metadata for plugin.";
1083
1084 static int plugin_get_metadata_failure(
1085     void* state, grpc_auth_metadata_context context,
1086     grpc_credentials_plugin_metadata_cb cb, void* user_data,
1087     grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX],
1088     size_t* num_creds_md, grpc_status_code* status,
1089     const char** error_details) {
1090   GPR_ASSERT(strcmp(context.service_url, test_service_url) == 0);
1091   GPR_ASSERT(strcmp(context.method_name, test_method) == 0);
1092   GPR_ASSERT(context.channel_auth_context == nullptr);
1093   GPR_ASSERT(context.reserved == nullptr);
1094   plugin_state* s = static_cast<plugin_state*>(state);
1095   *s = PLUGIN_GET_METADATA_CALLED_STATE;
1096   *status = GRPC_STATUS_UNAUTHENTICATED;
1097   *error_details = gpr_strdup(plugin_error_details);
1098   return true;  // Synchronous return.
1099 }
1100
1101 static void plugin_destroy(void* state) {
1102   plugin_state* s = static_cast<plugin_state*>(state);
1103   *s = PLUGIN_DESTROY_CALLED_STATE;
1104 }
1105
1106 static void test_metadata_plugin_success(void) {
1107   plugin_state state = PLUGIN_INITIAL_STATE;
1108   grpc_metadata_credentials_plugin plugin;
1109   grpc_core::ExecCtx exec_ctx;
1110   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
1111                                             nullptr, nullptr};
1112   request_metadata_state* md_state = make_request_metadata_state(
1113       GRPC_ERROR_NONE, plugin_md, GPR_ARRAY_SIZE(plugin_md));
1114
1115   plugin.state = &state;
1116   plugin.get_metadata = plugin_get_metadata_success;
1117   plugin.destroy = plugin_destroy;
1118
1119   grpc_call_credentials* creds =
1120       grpc_metadata_credentials_create_from_plugin(plugin, nullptr);
1121   GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
1122   run_request_metadata_test(creds, auth_md_ctx, md_state);
1123   GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
1124   creds->Unref();
1125
1126   GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
1127 }
1128
1129 static void test_metadata_plugin_failure(void) {
1130   plugin_state state = PLUGIN_INITIAL_STATE;
1131   grpc_metadata_credentials_plugin plugin;
1132   grpc_core::ExecCtx exec_ctx;
1133   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
1134                                             nullptr, nullptr};
1135   char* expected_error;
1136   gpr_asprintf(&expected_error,
1137                "Getting metadata from plugin failed with error: %s",
1138                plugin_error_details);
1139   request_metadata_state* md_state = make_request_metadata_state(
1140       GRPC_ERROR_CREATE_FROM_COPIED_STRING(expected_error), nullptr, 0);
1141   gpr_free(expected_error);
1142
1143   plugin.state = &state;
1144   plugin.get_metadata = plugin_get_metadata_failure;
1145   plugin.destroy = plugin_destroy;
1146
1147   grpc_call_credentials* creds =
1148       grpc_metadata_credentials_create_from_plugin(plugin, nullptr);
1149   GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
1150   run_request_metadata_test(creds, auth_md_ctx, md_state);
1151   GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
1152   creds->Unref();
1153
1154   GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
1155 }
1156
1157 static void test_get_well_known_google_credentials_file_path(void) {
1158   char* path;
1159   char* home = gpr_getenv("HOME");
1160   path = grpc_get_well_known_google_credentials_file_path();
1161   GPR_ASSERT(path != nullptr);
1162   gpr_free(path);
1163 #if defined(GPR_POSIX_ENV) || defined(GPR_LINUX_ENV)
1164   gpr_unsetenv("HOME");
1165   path = grpc_get_well_known_google_credentials_file_path();
1166   GPR_ASSERT(path == nullptr);
1167   gpr_setenv("HOME", home);
1168   gpr_free(path);
1169 #endif /* GPR_POSIX_ENV || GPR_LINUX_ENV */
1170   gpr_free(home);
1171 }
1172
1173 static void test_channel_creds_duplicate_without_call_creds(void) {
1174   grpc_core::ExecCtx exec_ctx;
1175
1176   grpc_channel_credentials* channel_creds =
1177       grpc_fake_transport_security_credentials_create();
1178
1179   grpc_core::RefCountedPtr<grpc_channel_credentials> dup =
1180       channel_creds->duplicate_without_call_credentials();
1181   GPR_ASSERT(dup == channel_creds);
1182   dup.reset();
1183
1184   grpc_call_credentials* call_creds =
1185       grpc_access_token_credentials_create("blah", nullptr);
1186   grpc_channel_credentials* composite_creds =
1187       grpc_composite_channel_credentials_create(channel_creds, call_creds,
1188                                                 nullptr);
1189   call_creds->Unref();
1190   dup = composite_creds->duplicate_without_call_credentials();
1191   GPR_ASSERT(dup == channel_creds);
1192   dup.reset();
1193
1194   channel_creds->Unref();
1195   composite_creds->Unref();
1196 }
1197
1198 typedef struct {
1199   const char* url_scheme;
1200   const char* call_host;
1201   const char* call_method;
1202   const char* desired_service_url;
1203   const char* desired_method_name;
1204 } auth_metadata_context_test_case;
1205
1206 static void test_auth_metadata_context(void) {
1207   auth_metadata_context_test_case test_cases[] = {
1208       // No service nor method.
1209       {"https", "www.foo.com", "", "https://www.foo.com", ""},
1210       // No method.
1211       {"https", "www.foo.com", "/Service", "https://www.foo.com/Service", ""},
1212       // Empty service and method.
1213       {"https", "www.foo.com", "//", "https://www.foo.com/", ""},
1214       // Empty method.
1215       {"https", "www.foo.com", "/Service/", "https://www.foo.com/Service", ""},
1216       // Malformed url.
1217       {"https", "www.foo.com:", "/Service/", "https://www.foo.com:/Service",
1218        ""},
1219       // https, default explicit port.
1220       {"https", "www.foo.com:443", "/Service/FooMethod",
1221        "https://www.foo.com/Service", "FooMethod"},
1222       // https, default implicit port.
1223       {"https", "www.foo.com", "/Service/FooMethod",
1224        "https://www.foo.com/Service", "FooMethod"},
1225       // https with ipv6 literal, default explicit port.
1226       {"https", "[1080:0:0:0:8:800:200C:417A]:443", "/Service/FooMethod",
1227        "https://[1080:0:0:0:8:800:200C:417A]/Service", "FooMethod"},
1228       // https with ipv6 literal, default implicit port.
1229       {"https", "[1080:0:0:0:8:800:200C:443]", "/Service/FooMethod",
1230        "https://[1080:0:0:0:8:800:200C:443]/Service", "FooMethod"},
1231       // https, custom port.
1232       {"https", "www.foo.com:8888", "/Service/FooMethod",
1233        "https://www.foo.com:8888/Service", "FooMethod"},
1234       // https with ipv6 literal, custom port.
1235       {"https", "[1080:0:0:0:8:800:200C:417A]:8888", "/Service/FooMethod",
1236        "https://[1080:0:0:0:8:800:200C:417A]:8888/Service", "FooMethod"},
1237       // custom url scheme, https default port.
1238       {"blah", "www.foo.com:443", "/Service/FooMethod",
1239        "blah://www.foo.com:443/Service", "FooMethod"}};
1240   for (uint32_t i = 0; i < GPR_ARRAY_SIZE(test_cases); i++) {
1241     const char* url_scheme = test_cases[i].url_scheme;
1242     grpc_slice call_host =
1243         grpc_slice_from_copied_string(test_cases[i].call_host);
1244     grpc_slice call_method =
1245         grpc_slice_from_copied_string(test_cases[i].call_method);
1246     grpc_auth_metadata_context auth_md_context;
1247     memset(&auth_md_context, 0, sizeof(auth_md_context));
1248     grpc_auth_metadata_context_build(url_scheme, call_host, call_method,
1249                                      nullptr, &auth_md_context);
1250     if (strcmp(auth_md_context.service_url,
1251                test_cases[i].desired_service_url) != 0) {
1252       gpr_log(GPR_ERROR, "Invalid service url, want: %s, got %s.",
1253               test_cases[i].desired_service_url, auth_md_context.service_url);
1254       GPR_ASSERT(false);
1255     }
1256     if (strcmp(auth_md_context.method_name,
1257                test_cases[i].desired_method_name) != 0) {
1258       gpr_log(GPR_ERROR, "Invalid method name, want: %s, got %s.",
1259               test_cases[i].desired_method_name, auth_md_context.method_name);
1260       GPR_ASSERT(false);
1261     }
1262     GPR_ASSERT(auth_md_context.channel_auth_context == nullptr);
1263     grpc_slice_unref(call_host);
1264     grpc_slice_unref(call_method);
1265     grpc_auth_metadata_context_reset(&auth_md_context);
1266   }
1267 }
1268
1269 int main(int argc, char** argv) {
1270   grpc::testing::TestEnvironment env(argc, argv);
1271   grpc_init();
1272   test_empty_md_array();
1273   test_add_to_empty_md_array();
1274   test_add_abunch_to_md_array();
1275   test_oauth2_token_fetcher_creds_parsing_ok();
1276   test_oauth2_token_fetcher_creds_parsing_bad_http_status();
1277   test_oauth2_token_fetcher_creds_parsing_empty_http_body();
1278   test_oauth2_token_fetcher_creds_parsing_invalid_json();
1279   test_oauth2_token_fetcher_creds_parsing_missing_token();
1280   test_oauth2_token_fetcher_creds_parsing_missing_token_type();
1281   test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime();
1282   test_google_iam_creds();
1283   test_access_token_creds();
1284   test_channel_oauth2_composite_creds();
1285   test_oauth2_google_iam_composite_creds();
1286   test_channel_oauth2_google_iam_composite_creds();
1287   test_compute_engine_creds_success();
1288   test_compute_engine_creds_failure();
1289   test_refresh_token_creds_success();
1290   test_refresh_token_creds_failure();
1291   test_jwt_creds_lifetime();
1292   test_jwt_creds_success();
1293   test_jwt_creds_signing_failure();
1294   test_google_default_creds_auth_key();
1295   test_google_default_creds_refresh_token();
1296   test_google_default_creds_gce();
1297   test_google_default_creds_non_gce();
1298   test_no_google_default_creds();
1299   test_metadata_plugin_success();
1300   test_metadata_plugin_failure();
1301   test_get_well_known_google_credentials_file_path();
1302   test_channel_creds_duplicate_without_call_creds();
1303   test_auth_metadata_context();
1304   grpc_shutdown();
1305   return 0;
1306 }