LCOV - code coverage report
Current view: top level - test/core/security - credentials_test.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 517 533 97.0 %
Date: 2015-10-10 Functions: 55 59 93.2 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, Google Inc.
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are
       8             :  * met:
       9             :  *
      10             :  *     * Redistributions of source code must retain the above copyright
      11             :  * notice, this list of conditions and the following disclaimer.
      12             :  *     * Redistributions in binary form must reproduce the above
      13             :  * copyright notice, this list of conditions and the following disclaimer
      14             :  * in the documentation and/or other materials provided with the
      15             :  * distribution.
      16             :  *     * Neither the name of Google Inc. nor the names of its
      17             :  * contributors may be used to endorse or promote products derived from
      18             :  * this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :  *
      32             :  */
      33             : 
      34             : #include "src/core/security/credentials.h"
      35             : 
      36             : #include <string.h>
      37             : 
      38             : #include "src/core/httpcli/httpcli.h"
      39             : #include "src/core/security/json_token.h"
      40             : #include "src/core/support/env.h"
      41             : #include "src/core/support/file.h"
      42             : #include "src/core/support/string.h"
      43             : 
      44             : #include "test/core/util/test_config.h"
      45             : 
      46             : #include <grpc/support/alloc.h>
      47             : #include <grpc/support/log.h>
      48             : #include <grpc/support/string_util.h>
      49             : #include <grpc/support/time.h>
      50             : 
      51             : #include <openssl/rsa.h>
      52             : 
      53             : static const char test_google_iam_authorization_token[] = "blahblahblhahb";
      54             : static const char test_google_iam_authority_selector[] = "respectmyauthoritah";
      55             : static const char test_oauth2_bearer_token[] =
      56             :     "Bearer blaaslkdjfaslkdfasdsfasf";
      57             : static const char test_root_cert[] = "I am the root!";
      58             : 
      59             : /* This JSON key was generated with the GCE console and revoked immediately.
      60             :    The identifiers have been changed as well.
      61             :    Maximum size for a string literal is 509 chars in C89, yay!  */
      62             : static const char test_json_key_str_part1[] =
      63             :     "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----"
      64             :     "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJE"
      65             :     "qg"
      66             :     "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\\nyjSeg/"
      67             :     "rWBQvS4hle4LfijkP3J5BG+"
      68             :     "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\\nOnVF6N7dL3nTYZg+"
      69             :     "uQrNsMTz9UxVAgMBAAECgYEAzbLewe1xe9vy+2GoSsfib+28\\nDZgSE6Bu/"
      70             :     "zuFoPrRc6qL9p2SsnV7txrunTyJkkOnPLND9ABAXybRTlcVKP/sGgza\\n/"
      71             :     "8HpCqFYM9V8f34SBWfD4fRFT+n/"
      72             :     "73cfRUtGXdXpseva2lh8RilIQfPhNZAncenU\\ngqXjDvpkypEusgXAykECQQD+";
      73             : static const char test_json_key_str_part2[] =
      74             :     "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\\nCslxoHQM8s+"
      75             :     "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\\nEkoy2L/"
      76             :     "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDA"
      77             :     "G"
      78             :     "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6Hz"
      79             :     "A"
      80             :     "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\\n6z8RJm0+"
      81             :     "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/"
      82             :     "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZ"
      83             :     "Y"
      84             :     "Ap6LI9W\\nIqv4vr6y38N79TTC\\n-----END PRIVATE KEY-----\\n\", ";
      85             : static const char test_json_key_str_part3[] =
      86             :     "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
      87             :     "\"client_email\": "
      88             :     "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
      89             :     "com\", \"client_id\": "
      90             :     "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
      91             :     "com\", \"type\": \"service_account\" }";
      92             : 
      93             : /* Test refresh token. */
      94             : static const char test_refresh_token_str[] =
      95             :     "{ \"client_id\": \"32555999999.apps.googleusercontent.com\","
      96             :     "  \"client_secret\": \"EmssLNjJy1332hD4KFsecret\","
      97             :     "  \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\","
      98             :     "  \"type\": \"authorized_user\"}";
      99             : 
     100             : static const char valid_oauth2_json_response[] =
     101             :     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
     102             :     " \"expires_in\":3599, "
     103             :     " \"token_type\":\"Bearer\"}";
     104             : 
     105             : static const char test_user_data[] = "user data";
     106             : 
     107             : static const char test_scope[] = "perm1 perm2";
     108             : 
     109             : static const char test_signed_jwt[] =
     110             :     "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImY0OTRkN2M1YWU2MGRmOTcyNmM4YW"
     111             :     "U0MDcyZTViYTdmZDkwODg2YzcifQ";
     112             : 
     113             : static const char test_service_url[] = "https://foo.com/foo.v1";
     114             : static const char other_test_service_url[] = "https://bar.com/bar.v1";
     115             : 
     116           3 : static char *test_json_key_str(void) {
     117           3 :   size_t result_len = strlen(test_json_key_str_part1) +
     118             :                       strlen(test_json_key_str_part2) +
     119             :                       strlen(test_json_key_str_part3);
     120           3 :   char *result = gpr_malloc(result_len + 1);
     121           3 :   char *current = result;
     122           3 :   strcpy(result, test_json_key_str_part1);
     123           3 :   current += strlen(test_json_key_str_part1);
     124           3 :   strcpy(current, test_json_key_str_part2);
     125           3 :   current += strlen(test_json_key_str_part2);
     126           3 :   strcpy(current, test_json_key_str_part3);
     127           3 :   return result;
     128             : }
     129             : 
     130             : typedef struct {
     131             :   const char *key;
     132             :   const char *value;
     133             : } expected_md;
     134             : 
     135          11 : static grpc_httpcli_response http_response(int status, const char *body) {
     136             :   grpc_httpcli_response response;
     137          11 :   memset(&response, 0, sizeof(grpc_httpcli_response));
     138          11 :   response.status = status;
     139          11 :   response.body = (char *)body;
     140          11 :   response.body_length = strlen(body);
     141          11 :   return response;
     142             : }
     143             : 
     144           1 : static void test_empty_md_store(void) {
     145           1 :   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
     146           1 :   GPR_ASSERT(store->num_entries == 0);
     147           1 :   GPR_ASSERT(store->allocated == 0);
     148           1 :   grpc_credentials_md_store_unref(store);
     149           1 : }
     150             : 
     151           1 : static void test_ref_unref_empty_md_store(void) {
     152           1 :   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
     153           1 :   grpc_credentials_md_store_ref(store);
     154           1 :   grpc_credentials_md_store_ref(store);
     155           1 :   GPR_ASSERT(store->num_entries == 0);
     156           1 :   GPR_ASSERT(store->allocated == 0);
     157           1 :   grpc_credentials_md_store_unref(store);
     158           1 :   grpc_credentials_md_store_unref(store);
     159           1 :   grpc_credentials_md_store_unref(store);
     160           1 : }
     161             : 
     162           1 : static void test_add_to_empty_md_store(void) {
     163           1 :   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
     164           1 :   const char *key_str = "hello";
     165           1 :   const char *value_str = "there blah blah blah blah blah blah blah";
     166           1 :   gpr_slice key = gpr_slice_from_copied_string(key_str);
     167           1 :   gpr_slice value = gpr_slice_from_copied_string(value_str);
     168           1 :   grpc_credentials_md_store_add(store, key, value);
     169           1 :   GPR_ASSERT(store->num_entries == 1);
     170           1 :   GPR_ASSERT(gpr_slice_cmp(key, store->entries[0].key) == 0);
     171           1 :   GPR_ASSERT(gpr_slice_cmp(value, store->entries[0].value) == 0);
     172           1 :   gpr_slice_unref(key);
     173           1 :   gpr_slice_unref(value);
     174           1 :   grpc_credentials_md_store_unref(store);
     175           1 : }
     176             : 
     177           1 : static void test_add_cstrings_to_empty_md_store(void) {
     178           1 :   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
     179           1 :   const char *key_str = "hello";
     180           1 :   const char *value_str = "there blah blah blah blah blah blah blah";
     181           1 :   grpc_credentials_md_store_add_cstrings(store, key_str, value_str);
     182           1 :   GPR_ASSERT(store->num_entries == 1);
     183           1 :   GPR_ASSERT(gpr_slice_str_cmp(store->entries[0].key, key_str) == 0);
     184           1 :   GPR_ASSERT(gpr_slice_str_cmp(store->entries[0].value, value_str) == 0);
     185           1 :   grpc_credentials_md_store_unref(store);
     186           1 : }
     187             : 
     188           1 : static void test_empty_preallocated_md_store(void) {
     189           1 :   grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
     190           1 :   GPR_ASSERT(store->num_entries == 0);
     191           1 :   GPR_ASSERT(store->allocated == 4);
     192           1 :   GPR_ASSERT(store->entries != NULL);
     193           1 :   grpc_credentials_md_store_unref(store);
     194           1 : }
     195             : 
     196           1 : static void test_add_abunch_to_md_store(void) {
     197           1 :   grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
     198           1 :   size_t num_entries = 1000;
     199           1 :   const char *key_str = "hello";
     200           1 :   const char *value_str = "there blah blah blah blah blah blah blah";
     201             :   size_t i;
     202        1001 :   for (i = 0; i < num_entries; i++) {
     203        1000 :     grpc_credentials_md_store_add_cstrings(store, key_str, value_str);
     204             :   }
     205        1001 :   for (i = 0; i < num_entries; i++) {
     206        1000 :     GPR_ASSERT(gpr_slice_str_cmp(store->entries[i].key, key_str) == 0);
     207        1000 :     GPR_ASSERT(gpr_slice_str_cmp(store->entries[i].value, value_str) == 0);
     208             :   }
     209           1 :   grpc_credentials_md_store_unref(store);
     210           1 : }
     211             : 
     212           1 : static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
     213           1 :   grpc_credentials_md_store *token_md = NULL;
     214             :   gpr_timespec token_lifetime;
     215           1 :   grpc_httpcli_response response =
     216             :       http_response(200, valid_oauth2_json_response);
     217           1 :   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
     218             :                  &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_OK);
     219           1 :   GPR_ASSERT(token_lifetime.tv_sec == 3599);
     220           1 :   GPR_ASSERT(token_lifetime.tv_nsec == 0);
     221           1 :   GPR_ASSERT(token_md->num_entries == 1);
     222           1 :   GPR_ASSERT(gpr_slice_str_cmp(token_md->entries[0].key, "Authorization") == 0);
     223           1 :   GPR_ASSERT(gpr_slice_str_cmp(token_md->entries[0].value,
     224             :                                "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
     225             :              0);
     226           1 :   grpc_credentials_md_store_unref(token_md);
     227           1 : }
     228             : 
     229           1 : static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
     230           1 :   grpc_credentials_md_store *token_md = NULL;
     231             :   gpr_timespec token_lifetime;
     232           1 :   grpc_httpcli_response response =
     233             :       http_response(401, valid_oauth2_json_response);
     234           1 :   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
     235             :                  &response, &token_md, &token_lifetime) ==
     236             :              GRPC_CREDENTIALS_ERROR);
     237           1 : }
     238             : 
     239           1 : static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
     240           1 :   grpc_credentials_md_store *token_md = NULL;
     241             :   gpr_timespec token_lifetime;
     242           1 :   grpc_httpcli_response response = http_response(200, "");
     243           1 :   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
     244             :                  &response, &token_md, &token_lifetime) ==
     245             :              GRPC_CREDENTIALS_ERROR);
     246           1 : }
     247             : 
     248           1 : static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
     249           1 :   grpc_credentials_md_store *token_md = NULL;
     250             :   gpr_timespec token_lifetime;
     251           1 :   grpc_httpcli_response response =
     252             :       http_response(200,
     253             :                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
     254             :                     " \"expires_in\":3599, "
     255             :                     " \"token_type\":\"Bearer\"");
     256           1 :   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
     257             :                  &response, &token_md, &token_lifetime) ==
     258             :              GRPC_CREDENTIALS_ERROR);
     259           1 : }
     260             : 
     261           1 : static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
     262           1 :   grpc_credentials_md_store *token_md = NULL;
     263             :   gpr_timespec token_lifetime;
     264           1 :   grpc_httpcli_response response = http_response(200,
     265             :                                                  "{"
     266             :                                                  " \"expires_in\":3599, "
     267             :                                                  " \"token_type\":\"Bearer\"}");
     268           1 :   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
     269             :                  &response, &token_md, &token_lifetime) ==
     270             :              GRPC_CREDENTIALS_ERROR);
     271           1 : }
     272             : 
     273           1 : static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
     274           1 :   grpc_credentials_md_store *token_md = NULL;
     275             :   gpr_timespec token_lifetime;
     276           1 :   grpc_httpcli_response response =
     277             :       http_response(200,
     278             :                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
     279             :                     " \"expires_in\":3599, "
     280             :                     "}");
     281           1 :   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
     282             :                  &response, &token_md, &token_lifetime) ==
     283             :              GRPC_CREDENTIALS_ERROR);
     284           1 : }
     285             : 
     286           1 : static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
     287             :     void) {
     288           1 :   grpc_credentials_md_store *token_md = NULL;
     289             :   gpr_timespec token_lifetime;
     290           1 :   grpc_httpcli_response response =
     291             :       http_response(200,
     292             :                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
     293             :                     " \"token_type\":\"Bearer\"}");
     294           1 :   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
     295             :                  &response, &token_md, &token_lifetime) ==
     296             :              GRPC_CREDENTIALS_ERROR);
     297           1 : }
     298             : 
     299           4 : static void check_metadata(expected_md *expected, grpc_credentials_md *md_elems,
     300             :                            size_t num_md) {
     301             :   size_t i;
     302          11 :   for (i = 0; i < num_md; i++) {
     303             :     size_t j;
     304          11 :     for (j = 0; j < num_md; j++) {
     305          11 :       if (0 == gpr_slice_str_cmp(md_elems[j].key, expected[i].key)) {
     306           7 :         GPR_ASSERT(gpr_slice_str_cmp(md_elems[j].value, expected[i].value) ==
     307             :                    0);
     308           7 :         break;
     309             :       }
     310             :     }
     311           7 :     if (j == num_md) {
     312           0 :       gpr_log(GPR_ERROR, "key %s not found", expected[i].key);
     313           0 :       GPR_ASSERT(0);
     314             :     }
     315             :   }
     316           4 : }
     317             : 
     318           1 : static void check_google_iam_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
     319             :                                       grpc_credentials_md *md_elems,
     320             :                                       size_t num_md,
     321             :                                       grpc_credentials_status status) {
     322           1 :   grpc_credentials *c = (grpc_credentials *)user_data;
     323           1 :   expected_md emd[] = {{GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
     324             :                         test_google_iam_authorization_token},
     325             :                        {GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
     326             :                         test_google_iam_authority_selector}};
     327           1 :   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
     328           1 :   GPR_ASSERT(num_md == 2);
     329           1 :   check_metadata(emd, md_elems, num_md);
     330           1 :   grpc_credentials_unref(c);
     331           1 : }
     332             : 
     333           1 : static void test_google_iam_creds(void) {
     334           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     335           1 :   grpc_credentials *creds = grpc_google_iam_credentials_create(
     336             :       test_google_iam_authorization_token, test_google_iam_authority_selector,
     337             :       NULL);
     338           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(creds));
     339           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata_only(creds));
     340           1 :   grpc_credentials_get_request_metadata(&exec_ctx, creds, NULL,
     341             :                                         test_service_url,
     342             :                                         check_google_iam_metadata, creds);
     343           1 :   grpc_exec_ctx_finish(&exec_ctx);
     344           1 : }
     345             : 
     346           1 : static void check_access_token_metadata(grpc_exec_ctx *exec_ctx,
     347             :                                         void *user_data,
     348             :                                         grpc_credentials_md *md_elems,
     349             :                                         size_t num_md,
     350             :                                         grpc_credentials_status status) {
     351           1 :   grpc_credentials *c = (grpc_credentials *)user_data;
     352           1 :   expected_md emd[] = {{GRPC_AUTHORIZATION_METADATA_KEY, "Bearer blah"}};
     353           1 :   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
     354           1 :   GPR_ASSERT(num_md == 1);
     355           1 :   check_metadata(emd, md_elems, num_md);
     356           1 :   grpc_credentials_unref(c);
     357           1 : }
     358             : 
     359           1 : static void test_access_token_creds(void) {
     360           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     361           1 :   grpc_credentials *creds = grpc_access_token_credentials_create("blah", NULL);
     362           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(creds));
     363           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata_only(creds));
     364           1 :   GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
     365           1 :   grpc_credentials_get_request_metadata(&exec_ctx, creds, NULL,
     366             :                                         test_service_url,
     367             :                                         check_access_token_metadata, creds);
     368           1 :   grpc_exec_ctx_finish(&exec_ctx);
     369           1 : }
     370             : 
     371           1 : static void check_ssl_oauth2_composite_metadata(
     372             :     grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
     373             :     size_t num_md, grpc_credentials_status status) {
     374           1 :   grpc_credentials *c = (grpc_credentials *)user_data;
     375           1 :   expected_md emd[] = {
     376             :       {GRPC_AUTHORIZATION_METADATA_KEY, test_oauth2_bearer_token}};
     377           1 :   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
     378           1 :   GPR_ASSERT(num_md == 1);
     379           1 :   check_metadata(emd, md_elems, num_md);
     380           1 :   grpc_credentials_unref(c);
     381           1 : }
     382             : 
     383           1 : static void test_ssl_oauth2_composite_creds(void) {
     384           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     385           1 :   grpc_credentials *ssl_creds =
     386             :       grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
     387             :   const grpc_credentials_array *creds_array;
     388           1 :   grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
     389             :       "Authorization", test_oauth2_bearer_token, 0);
     390           1 :   grpc_credentials *composite_creds =
     391             :       grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
     392           1 :   grpc_credentials_unref(ssl_creds);
     393           1 :   grpc_credentials_unref(oauth2_creds);
     394           1 :   GPR_ASSERT(strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) ==
     395             :              0);
     396           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
     397           1 :   GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
     398           1 :   creds_array = grpc_composite_credentials_get_credentials(composite_creds);
     399           1 :   GPR_ASSERT(creds_array->num_creds == 2);
     400           1 :   GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
     401             :                     GRPC_CREDENTIALS_TYPE_SSL) == 0);
     402           1 :   GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
     403             :                     GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
     404           1 :   grpc_credentials_get_request_metadata(
     405             :       &exec_ctx, composite_creds, NULL, test_service_url,
     406             :       check_ssl_oauth2_composite_metadata, composite_creds);
     407           1 :   grpc_exec_ctx_finish(&exec_ctx);
     408           1 : }
     409             : 
     410           0 : void test_ssl_fake_transport_security_composite_creds_failure(void) {
     411           0 :   grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
     412           0 :   grpc_credentials *fake_transport_security_creds =
     413             :       grpc_fake_transport_security_credentials_create();
     414             : 
     415             :   /* 2 connector credentials: should not work. */
     416           0 :   GPR_ASSERT(grpc_composite_credentials_create(
     417             :                  ssl_creds, fake_transport_security_creds, NULL) == NULL);
     418           0 :   grpc_credentials_unref(ssl_creds);
     419           0 :   grpc_credentials_unref(fake_transport_security_creds);
     420           0 : }
     421             : 
     422           1 : static void check_ssl_oauth2_google_iam_composite_metadata(
     423             :     grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
     424             :     size_t num_md, grpc_credentials_status status) {
     425           1 :   grpc_credentials *c = (grpc_credentials *)user_data;
     426           1 :   expected_md emd[] = {
     427             :       {GRPC_AUTHORIZATION_METADATA_KEY, test_oauth2_bearer_token},
     428             :       {GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
     429             :        test_google_iam_authorization_token},
     430             :       {GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
     431             :        test_google_iam_authority_selector}};
     432           1 :   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
     433           1 :   GPR_ASSERT(num_md == 3);
     434           1 :   check_metadata(emd, md_elems, num_md);
     435           1 :   grpc_credentials_unref(c);
     436           1 : }
     437             : 
     438           1 : static void test_ssl_oauth2_google_iam_composite_creds(void) {
     439           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     440           1 :   grpc_credentials *ssl_creds =
     441             :       grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
     442             :   const grpc_credentials_array *creds_array;
     443           1 :   grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
     444             :       "Authorization", test_oauth2_bearer_token, 0);
     445           1 :   grpc_credentials *aux_creds =
     446             :       grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
     447           1 :   grpc_credentials *google_iam_creds = grpc_google_iam_credentials_create(
     448             :       test_google_iam_authorization_token, test_google_iam_authority_selector,
     449             :       NULL);
     450           1 :   grpc_credentials *composite_creds =
     451             :       grpc_composite_credentials_create(aux_creds, google_iam_creds, NULL);
     452           1 :   grpc_credentials_unref(ssl_creds);
     453           1 :   grpc_credentials_unref(oauth2_creds);
     454           1 :   grpc_credentials_unref(aux_creds);
     455           1 :   grpc_credentials_unref(google_iam_creds);
     456           1 :   GPR_ASSERT(strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) ==
     457             :              0);
     458           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
     459           1 :   GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
     460           1 :   creds_array = grpc_composite_credentials_get_credentials(composite_creds);
     461           1 :   GPR_ASSERT(creds_array->num_creds == 3);
     462           1 :   GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
     463             :                     GRPC_CREDENTIALS_TYPE_SSL) == 0);
     464           1 :   GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
     465             :                     GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
     466           1 :   GPR_ASSERT(strcmp(creds_array->creds_array[2]->type,
     467             :                     GRPC_CREDENTIALS_TYPE_IAM) == 0);
     468           1 :   grpc_credentials_get_request_metadata(
     469             :       &exec_ctx, composite_creds, NULL, test_service_url,
     470             :       check_ssl_oauth2_google_iam_composite_metadata, composite_creds);
     471           1 :   grpc_exec_ctx_finish(&exec_ctx);
     472           1 : }
     473             : 
     474           4 : static void on_oauth2_creds_get_metadata_success(
     475             :     grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
     476             :     size_t num_md, grpc_credentials_status status) {
     477           4 :   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
     478           4 :   GPR_ASSERT(num_md == 1);
     479           4 :   GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "Authorization") == 0);
     480           4 :   GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].value,
     481             :                                "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
     482             :              0);
     483           4 :   GPR_ASSERT(user_data != NULL);
     484           4 :   GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
     485           4 : }
     486             : 
     487           2 : static void on_oauth2_creds_get_metadata_failure(
     488             :     grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
     489             :     size_t num_md, grpc_credentials_status status) {
     490           2 :   GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
     491           2 :   GPR_ASSERT(num_md == 0);
     492           2 :   GPR_ASSERT(user_data != NULL);
     493           2 :   GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
     494           2 : }
     495             : 
     496           2 : static void validate_compute_engine_http_request(
     497             :     const grpc_httpcli_request *request) {
     498           2 :   GPR_ASSERT(request->handshaker != &grpc_httpcli_ssl);
     499           2 :   GPR_ASSERT(strcmp(request->host, "metadata") == 0);
     500           2 :   GPR_ASSERT(
     501             :       strcmp(request->path,
     502             :              "/computeMetadata/v1/instance/service-accounts/default/token") ==
     503             :       0);
     504           2 :   GPR_ASSERT(request->hdr_count == 1);
     505           2 :   GPR_ASSERT(strcmp(request->hdrs[0].key, "Metadata-Flavor") == 0);
     506           2 :   GPR_ASSERT(strcmp(request->hdrs[0].value, "Google") == 0);
     507           2 : }
     508             : 
     509           1 : static int compute_engine_httpcli_get_success_override(
     510             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     511             :     gpr_timespec deadline, grpc_httpcli_response_cb on_response,
     512             :     void *user_data) {
     513           1 :   grpc_httpcli_response response =
     514             :       http_response(200, valid_oauth2_json_response);
     515           1 :   validate_compute_engine_http_request(request);
     516           1 :   on_response(exec_ctx, user_data, &response);
     517           1 :   return 1;
     518             : }
     519             : 
     520           1 : static int compute_engine_httpcli_get_failure_override(
     521             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     522             :     gpr_timespec deadline, grpc_httpcli_response_cb on_response,
     523             :     void *user_data) {
     524           1 :   grpc_httpcli_response response = http_response(403, "Not Authorized.");
     525           1 :   validate_compute_engine_http_request(request);
     526           1 :   on_response(exec_ctx, user_data, &response);
     527           1 :   return 1;
     528             : }
     529             : 
     530           0 : static int httpcli_post_should_not_be_called(
     531             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     532             :     const char *body_bytes, size_t body_size, gpr_timespec deadline,
     533             :     grpc_httpcli_response_cb on_response, void *user_data) {
     534           0 :   GPR_ASSERT("HTTP POST should not be called" == NULL);
     535             :   return 1;
     536             : }
     537             : 
     538           0 : static int httpcli_get_should_not_be_called(
     539             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     540             :     gpr_timespec deadline, grpc_httpcli_response_cb on_response,
     541             :     void *user_data) {
     542           0 :   GPR_ASSERT("HTTP GET should not be called" == NULL);
     543             :   return 1;
     544             : }
     545             : 
     546           1 : static void test_compute_engine_creds_success(void) {
     547           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     548           1 :   grpc_credentials *compute_engine_creds =
     549             :       grpc_google_compute_engine_credentials_create(NULL);
     550           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
     551           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
     552             : 
     553             :   /* First request: http get should be called. */
     554           1 :   grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
     555             :                             httpcli_post_should_not_be_called);
     556           1 :   grpc_credentials_get_request_metadata(
     557             :       &exec_ctx, compute_engine_creds, NULL, test_service_url,
     558             :       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
     559           1 :   grpc_exec_ctx_flush(&exec_ctx);
     560             : 
     561             :   /* Second request: the cached token should be served directly. */
     562           1 :   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
     563             :                             httpcli_post_should_not_be_called);
     564           1 :   grpc_credentials_get_request_metadata(
     565             :       &exec_ctx, compute_engine_creds, NULL, test_service_url,
     566             :       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
     567           1 :   grpc_exec_ctx_finish(&exec_ctx);
     568             : 
     569           1 :   grpc_credentials_unref(compute_engine_creds);
     570           1 :   grpc_httpcli_set_override(NULL, NULL);
     571           1 : }
     572             : 
     573           1 : static void test_compute_engine_creds_failure(void) {
     574           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     575           1 :   grpc_credentials *compute_engine_creds =
     576             :       grpc_google_compute_engine_credentials_create(NULL);
     577           1 :   grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
     578             :                             httpcli_post_should_not_be_called);
     579           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
     580           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
     581           1 :   grpc_credentials_get_request_metadata(
     582             :       &exec_ctx, compute_engine_creds, NULL, test_service_url,
     583             :       on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
     584           1 :   grpc_credentials_unref(compute_engine_creds);
     585           1 :   grpc_httpcli_set_override(NULL, NULL);
     586           1 :   grpc_exec_ctx_finish(&exec_ctx);
     587           1 : }
     588             : 
     589           2 : static void validate_refresh_token_http_request(
     590             :     const grpc_httpcli_request *request, const char *body, size_t body_size) {
     591             :   /* The content of the assertion is tested extensively in json_token_test. */
     592           2 :   char *expected_body = NULL;
     593           2 :   GPR_ASSERT(body != NULL);
     594           2 :   GPR_ASSERT(body_size != 0);
     595           2 :   gpr_asprintf(&expected_body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
     596             :                "32555999999.apps.googleusercontent.com",
     597             :                "EmssLNjJy1332hD4KFsecret",
     598             :                "1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42");
     599           2 :   GPR_ASSERT(strlen(expected_body) == body_size);
     600           2 :   GPR_ASSERT(memcmp(expected_body, body, body_size) == 0);
     601           2 :   gpr_free(expected_body);
     602           2 :   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
     603           2 :   GPR_ASSERT(strcmp(request->host, GRPC_GOOGLE_OAUTH2_SERVICE_HOST) == 0);
     604           2 :   GPR_ASSERT(strcmp(request->path, GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH) == 0);
     605           2 :   GPR_ASSERT(request->hdr_count == 1);
     606           2 :   GPR_ASSERT(strcmp(request->hdrs[0].key, "Content-Type") == 0);
     607           2 :   GPR_ASSERT(
     608             :       strcmp(request->hdrs[0].value, "application/x-www-form-urlencoded") == 0);
     609           2 : }
     610             : 
     611           1 : static int refresh_token_httpcli_post_success(
     612             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     613             :     const char *body, size_t body_size, gpr_timespec deadline,
     614             :     grpc_httpcli_response_cb on_response, void *user_data) {
     615           1 :   grpc_httpcli_response response =
     616             :       http_response(200, valid_oauth2_json_response);
     617           1 :   validate_refresh_token_http_request(request, body, body_size);
     618           1 :   on_response(exec_ctx, user_data, &response);
     619           1 :   return 1;
     620             : }
     621             : 
     622           1 : static int refresh_token_httpcli_post_failure(
     623             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     624             :     const char *body, size_t body_size, gpr_timespec deadline,
     625             :     grpc_httpcli_response_cb on_response, void *user_data) {
     626           1 :   grpc_httpcli_response response = http_response(403, "Not Authorized.");
     627           1 :   validate_refresh_token_http_request(request, body, body_size);
     628           1 :   on_response(exec_ctx, user_data, &response);
     629           1 :   return 1;
     630             : }
     631             : 
     632           1 : static void test_refresh_token_creds_success(void) {
     633           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     634           1 :   grpc_credentials *refresh_token_creds =
     635             :       grpc_google_refresh_token_credentials_create(test_refresh_token_str,
     636             :                                                    NULL);
     637           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
     638           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata_only(refresh_token_creds));
     639             : 
     640             :   /* First request: http get should be called. */
     641           1 :   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
     642             :                             refresh_token_httpcli_post_success);
     643           1 :   grpc_credentials_get_request_metadata(
     644             :       &exec_ctx, refresh_token_creds, NULL, test_service_url,
     645             :       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
     646           1 :   grpc_exec_ctx_flush(&exec_ctx);
     647             : 
     648             :   /* Second request: the cached token should be served directly. */
     649           1 :   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
     650             :                             httpcli_post_should_not_be_called);
     651           1 :   grpc_credentials_get_request_metadata(
     652             :       &exec_ctx, refresh_token_creds, NULL, test_service_url,
     653             :       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
     654           1 :   grpc_exec_ctx_flush(&exec_ctx);
     655             : 
     656           1 :   grpc_credentials_unref(refresh_token_creds);
     657           1 :   grpc_httpcli_set_override(NULL, NULL);
     658           1 :   grpc_exec_ctx_finish(&exec_ctx);
     659           1 : }
     660             : 
     661           1 : static void test_refresh_token_creds_failure(void) {
     662           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     663           1 :   grpc_credentials *refresh_token_creds =
     664             :       grpc_google_refresh_token_credentials_create(test_refresh_token_str,
     665             :                                                    NULL);
     666           1 :   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
     667             :                             refresh_token_httpcli_post_failure);
     668           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
     669           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata_only(refresh_token_creds));
     670           1 :   grpc_credentials_get_request_metadata(
     671             :       &exec_ctx, refresh_token_creds, NULL, test_service_url,
     672             :       on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
     673           1 :   grpc_credentials_unref(refresh_token_creds);
     674           1 :   grpc_httpcli_set_override(NULL, NULL);
     675           1 :   grpc_exec_ctx_finish(&exec_ctx);
     676           1 : }
     677             : 
     678           3 : static void validate_jwt_encode_and_sign_params(
     679             :     const grpc_auth_json_key *json_key, const char *scope,
     680             :     gpr_timespec token_lifetime) {
     681           3 :   GPR_ASSERT(grpc_auth_json_key_is_valid(json_key));
     682           3 :   GPR_ASSERT(json_key->private_key != NULL);
     683           3 :   GPR_ASSERT(RSA_check_key(json_key->private_key));
     684           3 :   GPR_ASSERT(json_key->type != NULL &&
     685             :              strcmp(json_key->type, "service_account") == 0);
     686           3 :   GPR_ASSERT(json_key->private_key_id != NULL &&
     687             :              strcmp(json_key->private_key_id,
     688             :                     "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
     689           3 :   GPR_ASSERT(json_key->client_id != NULL &&
     690             :              strcmp(json_key->client_id,
     691             :                     "777-abaslkan11hlb6nmim3bpspl31ud.apps."
     692             :                     "googleusercontent.com") == 0);
     693           3 :   GPR_ASSERT(json_key->client_email != NULL &&
     694             :              strcmp(json_key->client_email,
     695             :                     "777-abaslkan11hlb6nmim3bpspl31ud@developer."
     696             :                     "gserviceaccount.com") == 0);
     697           3 :   if (scope != NULL) GPR_ASSERT(strcmp(scope, test_scope) == 0);
     698           3 :   GPR_ASSERT(!gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime));
     699           3 : }
     700             : 
     701           2 : static char *encode_and_sign_jwt_success(const grpc_auth_json_key *json_key,
     702             :                                          const char *audience,
     703             :                                          gpr_timespec token_lifetime,
     704             :                                          const char *scope) {
     705           2 :   validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
     706           2 :   return gpr_strdup(test_signed_jwt);
     707             : }
     708             : 
     709           1 : static char *encode_and_sign_jwt_failure(const grpc_auth_json_key *json_key,
     710             :                                          const char *audience,
     711             :                                          gpr_timespec token_lifetime,
     712             :                                          const char *scope) {
     713           1 :   validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
     714           1 :   return NULL;
     715             : }
     716             : 
     717           0 : static char *encode_and_sign_jwt_should_not_be_called(
     718             :     const grpc_auth_json_key *json_key, const char *audience,
     719             :     gpr_timespec token_lifetime, const char *scope) {
     720           0 :   GPR_ASSERT("grpc_jwt_encode_and_sign should not be called" == NULL);
     721             :   return NULL;
     722             : }
     723             : 
     724           3 : static void on_jwt_creds_get_metadata_success(grpc_exec_ctx *exec_ctx,
     725             :                                               void *user_data,
     726             :                                               grpc_credentials_md *md_elems,
     727             :                                               size_t num_md,
     728             :                                               grpc_credentials_status status) {
     729             :   char *expected_md_value;
     730           3 :   gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt);
     731           3 :   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
     732           3 :   GPR_ASSERT(num_md == 1);
     733           3 :   GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "Authorization") == 0);
     734           3 :   GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].value, expected_md_value) == 0);
     735           3 :   GPR_ASSERT(user_data != NULL);
     736           3 :   GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
     737           3 :   gpr_free(expected_md_value);
     738           3 : }
     739             : 
     740           1 : static void on_jwt_creds_get_metadata_failure(grpc_exec_ctx *exec_ctx,
     741             :                                               void *user_data,
     742             :                                               grpc_credentials_md *md_elems,
     743             :                                               size_t num_md,
     744             :                                               grpc_credentials_status status) {
     745           1 :   GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
     746           1 :   GPR_ASSERT(num_md == 0);
     747           1 :   GPR_ASSERT(user_data != NULL);
     748           1 :   GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
     749           1 : }
     750             : 
     751           1 : static void test_jwt_creds_success(void) {
     752           1 :   char *json_key_string = test_json_key_str();
     753           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     754           1 :   grpc_credentials *jwt_creds =
     755             :       grpc_service_account_jwt_access_credentials_create(
     756             :           json_key_string, grpc_max_auth_token_lifetime, NULL);
     757           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
     758           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
     759             : 
     760             :   /* First request: jwt_encode_and_sign should be called. */
     761           1 :   grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
     762           1 :   grpc_credentials_get_request_metadata(
     763             :       &exec_ctx, jwt_creds, NULL, test_service_url,
     764             :       on_jwt_creds_get_metadata_success, (void *)test_user_data);
     765           1 :   grpc_exec_ctx_flush(&exec_ctx);
     766             : 
     767             :   /* Second request: the cached token should be served directly. */
     768           1 :   grpc_jwt_encode_and_sign_set_override(
     769             :       encode_and_sign_jwt_should_not_be_called);
     770           1 :   grpc_credentials_get_request_metadata(
     771             :       &exec_ctx, jwt_creds, NULL, test_service_url,
     772             :       on_jwt_creds_get_metadata_success, (void *)test_user_data);
     773           1 :   grpc_exec_ctx_flush(&exec_ctx);
     774             : 
     775             :   /* Third request: Different service url so jwt_encode_and_sign should be
     776             :      called again (no caching). */
     777           1 :   grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
     778           1 :   grpc_credentials_get_request_metadata(
     779             :       &exec_ctx, jwt_creds, NULL, other_test_service_url,
     780             :       on_jwt_creds_get_metadata_success, (void *)test_user_data);
     781           1 :   grpc_exec_ctx_flush(&exec_ctx);
     782             : 
     783           1 :   gpr_free(json_key_string);
     784           1 :   grpc_credentials_unref(jwt_creds);
     785           1 :   grpc_jwt_encode_and_sign_set_override(NULL);
     786           1 : }
     787             : 
     788           1 : static void test_jwt_creds_signing_failure(void) {
     789           1 :   char *json_key_string = test_json_key_str();
     790           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     791           1 :   grpc_credentials *jwt_creds =
     792             :       grpc_service_account_jwt_access_credentials_create(
     793             :           json_key_string, grpc_max_auth_token_lifetime, NULL);
     794           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
     795           1 :   GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
     796             : 
     797           1 :   grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure);
     798           1 :   grpc_credentials_get_request_metadata(
     799             :       &exec_ctx, jwt_creds, NULL, test_service_url,
     800             :       on_jwt_creds_get_metadata_failure, (void *)test_user_data);
     801             : 
     802           1 :   gpr_free(json_key_string);
     803           1 :   grpc_credentials_unref(jwt_creds);
     804           1 :   grpc_jwt_encode_and_sign_set_override(NULL);
     805           1 :   grpc_exec_ctx_finish(&exec_ctx);
     806           1 : }
     807             : 
     808           2 : static void set_google_default_creds_env_var_with_file_contents(
     809             :     const char *file_prefix, const char *contents) {
     810           2 :   size_t contents_len = strlen(contents);
     811             :   char *creds_file_name;
     812           2 :   FILE *creds_file = gpr_tmpfile(file_prefix, &creds_file_name);
     813           2 :   GPR_ASSERT(creds_file_name != NULL);
     814           2 :   GPR_ASSERT(creds_file != NULL);
     815           2 :   GPR_ASSERT(fwrite(contents, 1, contents_len, creds_file) == contents_len);
     816           2 :   fclose(creds_file);
     817           2 :   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, creds_file_name);
     818           2 :   gpr_free(creds_file_name);
     819           2 : }
     820             : 
     821           2 : static grpc_credentials *composite_inner_creds(grpc_credentials *creds,
     822             :                                                const char *inner_creds_type) {
     823             :   size_t i;
     824             :   grpc_composite_credentials *composite;
     825           2 :   GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
     826           2 :   composite = (grpc_composite_credentials *)creds;
     827           4 :   for (i = 0; i < composite->inner.num_creds; i++) {
     828           4 :     grpc_credentials *c = composite->inner.creds_array[i];
     829           6 :     if (strcmp(c->type, inner_creds_type) == 0) return c;
     830             :   }
     831           0 :   GPR_ASSERT(0); /* Not found. */
     832             : }
     833             : 
     834           1 : static void test_google_default_creds_auth_key(void) {
     835             :   grpc_service_account_jwt_access_credentials *jwt;
     836             :   grpc_credentials *creds;
     837           1 :   char *json_key = test_json_key_str();
     838           1 :   grpc_flush_cached_google_default_credentials();
     839           1 :   set_google_default_creds_env_var_with_file_contents(
     840             :       "json_key_google_default_creds", json_key);
     841           1 :   gpr_free(json_key);
     842           1 :   creds = grpc_google_default_credentials_create();
     843           1 :   GPR_ASSERT(creds != NULL);
     844           1 :   jwt = (grpc_service_account_jwt_access_credentials *)composite_inner_creds(
     845             :       creds, GRPC_CREDENTIALS_TYPE_JWT);
     846           1 :   GPR_ASSERT(
     847             :       strcmp(jwt->key.client_id,
     848             :              "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") ==
     849             :       0);
     850           1 :   grpc_credentials_unref(creds);
     851           1 :   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
     852           1 : }
     853             : 
     854           1 : static void test_google_default_creds_access_token(void) {
     855             :   grpc_google_refresh_token_credentials *refresh;
     856             :   grpc_credentials *creds;
     857           1 :   grpc_flush_cached_google_default_credentials();
     858           1 :   set_google_default_creds_env_var_with_file_contents(
     859             :       "refresh_token_google_default_creds", test_refresh_token_str);
     860           1 :   creds = grpc_google_default_credentials_create();
     861           1 :   GPR_ASSERT(creds != NULL);
     862           1 :   refresh = (grpc_google_refresh_token_credentials *)composite_inner_creds(
     863             :       creds, GRPC_CREDENTIALS_TYPE_OAUTH2);
     864           1 :   GPR_ASSERT(strcmp(refresh->refresh_token.client_id,
     865             :                     "32555999999.apps.googleusercontent.com") == 0);
     866           1 :   grpc_credentials_unref(creds);
     867           1 :   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
     868           1 : }
     869             : 
     870             : typedef enum {
     871             :   PLUGIN_INITIAL_STATE,
     872             :   PLUGIN_GET_METADATA_CALLED_STATE,
     873             :   PLUGIN_DESTROY_CALLED_STATE
     874             : } plugin_state;
     875             : 
     876             : typedef struct {
     877             :   const char *key;
     878             :   const char *value;
     879             : } plugin_metadata;
     880             : 
     881             : static const plugin_metadata plugin_md[] = {{"foo", "bar"}, {"hi", "there"}};
     882             : 
     883           1 : static void plugin_get_metadata_success(void *state, const char *service_url,
     884             :                                         grpc_credentials_plugin_metadata_cb cb,
     885             :                                         void *user_data) {
     886             :   size_t i;
     887             :   grpc_metadata md[GPR_ARRAY_SIZE(plugin_md)];
     888           1 :   plugin_state *s = (plugin_state *)state;
     889           1 :   GPR_ASSERT(strcmp(service_url, test_service_url) == 0);
     890           1 :   *s = PLUGIN_GET_METADATA_CALLED_STATE;
     891           3 :   for (i = 0; i < GPR_ARRAY_SIZE(plugin_md); i++) {
     892           2 :     memset(&md[i], 0, sizeof(grpc_metadata));
     893           2 :     md[i].key = plugin_md[i].key;
     894           2 :     md[i].value = plugin_md[i].value;
     895           2 :     md[i].value_length = strlen(plugin_md[i].value);
     896             :   }
     897           1 :   cb(user_data, md, GPR_ARRAY_SIZE(md), GRPC_STATUS_OK, NULL);
     898           1 : }
     899             : 
     900           1 : static void plugin_get_metadata_failure(void *state, const char *service_url,
     901             :                                         grpc_credentials_plugin_metadata_cb cb,
     902             :                                         void *user_data) {
     903           1 :   plugin_state *s = (plugin_state *)state;
     904           1 :   GPR_ASSERT(strcmp(service_url, test_service_url) == 0);
     905           1 :   *s = PLUGIN_GET_METADATA_CALLED_STATE;
     906           1 :   cb(user_data, NULL, 0, GRPC_STATUS_UNAUTHENTICATED,
     907             :      "Could not get metadata for plugin.");
     908           1 : }
     909             : 
     910           1 : static void on_plugin_metadata_received_success(
     911             :     grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
     912             :     size_t num_md, grpc_credentials_status status) {
     913           1 :   size_t i = 0;
     914           1 :   GPR_ASSERT(user_data == NULL);
     915           1 :   GPR_ASSERT(md_elems != NULL);
     916           1 :   GPR_ASSERT(num_md == GPR_ARRAY_SIZE(plugin_md));
     917           3 :   for (i = 0; i < num_md; i++) {
     918           2 :     GPR_ASSERT(gpr_slice_str_cmp(md_elems[i].key, plugin_md[i].key) == 0);
     919           2 :     GPR_ASSERT(gpr_slice_str_cmp(md_elems[i].value, plugin_md[i].value) == 0);
     920             :   }
     921           1 : }
     922             : 
     923           1 : static void on_plugin_metadata_received_failure(
     924             :     grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
     925             :     size_t num_md, grpc_credentials_status status) {
     926           1 :   GPR_ASSERT(user_data == NULL);
     927           1 :   GPR_ASSERT(md_elems == NULL);
     928           1 :   GPR_ASSERT(num_md == 0);
     929           1 :   GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
     930           1 : }
     931             : 
     932           2 : static void plugin_destroy(void *state) {
     933           2 :   plugin_state *s = (plugin_state *)state;
     934           2 :   *s = PLUGIN_DESTROY_CALLED_STATE;
     935           2 : }
     936             : 
     937           1 : static void test_metadata_plugin_success(void) {
     938             :   grpc_credentials *creds;
     939           1 :   plugin_state state = PLUGIN_INITIAL_STATE;
     940             :   grpc_metadata_credentials_plugin plugin;
     941           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     942             : 
     943           1 :   plugin.state = &state;
     944           1 :   plugin.get_metadata = plugin_get_metadata_success;
     945           1 :   plugin.destroy = plugin_destroy;
     946             : 
     947           1 :   creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
     948           1 :   GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
     949           1 :   grpc_credentials_get_request_metadata(
     950             :       &exec_ctx, creds, NULL, test_service_url,
     951             :       on_plugin_metadata_received_success, NULL);
     952           1 :   GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
     953           1 :   grpc_credentials_release(creds);
     954           1 :   GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
     955           1 :   grpc_exec_ctx_finish(&exec_ctx);
     956           1 : }
     957             : 
     958           1 : static void test_metadata_plugin_failure(void) {
     959             :   grpc_credentials *creds;
     960           1 :   plugin_state state = PLUGIN_INITIAL_STATE;
     961             :   grpc_metadata_credentials_plugin plugin;
     962           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     963             : 
     964           1 :   plugin.state = &state;
     965           1 :   plugin.get_metadata = plugin_get_metadata_failure;
     966           1 :   plugin.destroy = plugin_destroy;
     967             : 
     968           1 :   creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
     969           1 :   GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
     970           1 :   grpc_credentials_get_request_metadata(
     971             :       &exec_ctx, creds, NULL, test_service_url,
     972             :       on_plugin_metadata_received_failure, NULL);
     973           1 :   GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
     974           1 :   grpc_credentials_release(creds);
     975           1 :   GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
     976           1 :   grpc_exec_ctx_finish(&exec_ctx);
     977           1 : }
     978             : 
     979           1 : int main(int argc, char **argv) {
     980           1 :   grpc_test_init(argc, argv);
     981           1 :   test_empty_md_store();
     982           1 :   test_ref_unref_empty_md_store();
     983           1 :   test_add_to_empty_md_store();
     984           1 :   test_add_cstrings_to_empty_md_store();
     985           1 :   test_empty_preallocated_md_store();
     986           1 :   test_add_abunch_to_md_store();
     987           1 :   test_oauth2_token_fetcher_creds_parsing_ok();
     988           1 :   test_oauth2_token_fetcher_creds_parsing_bad_http_status();
     989           1 :   test_oauth2_token_fetcher_creds_parsing_empty_http_body();
     990           1 :   test_oauth2_token_fetcher_creds_parsing_invalid_json();
     991           1 :   test_oauth2_token_fetcher_creds_parsing_missing_token();
     992           1 :   test_oauth2_token_fetcher_creds_parsing_missing_token_type();
     993           1 :   test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime();
     994           1 :   test_google_iam_creds();
     995           1 :   test_access_token_creds();
     996           1 :   test_ssl_oauth2_composite_creds();
     997           1 :   test_ssl_oauth2_google_iam_composite_creds();
     998           1 :   test_compute_engine_creds_success();
     999           1 :   test_compute_engine_creds_failure();
    1000           1 :   test_refresh_token_creds_success();
    1001           1 :   test_refresh_token_creds_failure();
    1002           1 :   test_jwt_creds_success();
    1003           1 :   test_jwt_creds_signing_failure();
    1004           1 :   test_google_default_creds_auth_key();
    1005           1 :   test_google_default_creds_access_token();
    1006           1 :   test_metadata_plugin_success();
    1007           1 :   test_metadata_plugin_failure();
    1008           1 :   return 0;
    1009             : }

Generated by: LCOV version 1.10