LCOV - code coverage report
Current view: top level - test/core/security - jwt_verifier_test.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 285 289 98.6 %
Date: 2015-10-10 Functions: 25 27 92.6 %

          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/jwt_verifier.h"
      35             : 
      36             : #include <string.h>
      37             : 
      38             : #include "src/core/httpcli/httpcli.h"
      39             : #include "src/core/security/base64.h"
      40             : #include "src/core/security/json_token.h"
      41             : #include "test/core/util/test_config.h"
      42             : 
      43             : #include <grpc/support/alloc.h>
      44             : #include <grpc/support/log.h>
      45             : #include <grpc/support/slice.h>
      46             : #include <grpc/support/string_util.h>
      47             : 
      48             : /* This JSON key was generated with the GCE console and revoked immediately.
      49             :    The identifiers have been changed as well.
      50             :    Maximum size for a string literal is 509 chars in C89, yay!  */
      51             : static const char json_key_str_part1[] =
      52             :     "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----"
      53             :     "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJE"
      54             :     "qg"
      55             :     "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\\nyjSeg/"
      56             :     "rWBQvS4hle4LfijkP3J5BG+"
      57             :     "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\\nOnVF6N7dL3nTYZg+"
      58             :     "uQrNsMTz9UxVAgMBAAECgYEAzbLewe1xe9vy+2GoSsfib+28\\nDZgSE6Bu/"
      59             :     "zuFoPrRc6qL9p2SsnV7txrunTyJkkOnPLND9ABAXybRTlcVKP/sGgza\\n/"
      60             :     "8HpCqFYM9V8f34SBWfD4fRFT+n/"
      61             :     "73cfRUtGXdXpseva2lh8RilIQfPhNZAncenU\\ngqXjDvpkypEusgXAykECQQD+";
      62             : static const char json_key_str_part2[] =
      63             :     "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\\nCslxoHQM8s+"
      64             :     "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\\nEkoy2L/"
      65             :     "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDA"
      66             :     "G"
      67             :     "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6Hz"
      68             :     "A"
      69             :     "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\\n6z8RJm0+"
      70             :     "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/"
      71             :     "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZ"
      72             :     "Y"
      73             :     "Ap6LI9W\\nIqv4vr6y38N79TTC\\n-----END PRIVATE KEY-----\\n\", ";
      74             : static const char json_key_str_part3_for_google_email_issuer[] =
      75             :     "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
      76             :     "\"client_email\": "
      77             :     "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
      78             :     "com\", \"client_id\": "
      79             :     "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
      80             :     "com\", \"type\": \"service_account\" }";
      81             : /* Trick our JWT library into issuing a JWT with iss=accounts.google.com. */
      82             : static const char json_key_str_part3_for_url_issuer[] =
      83             :     "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
      84             :     "\"client_email\": \"accounts.google.com\", "
      85             :     "\"client_id\": "
      86             :     "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
      87             :     "com\", \"type\": \"service_account\" }";
      88             : static const char json_key_str_part3_for_custom_email_issuer[] =
      89             :     "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
      90             :     "\"client_email\": "
      91             :     "\"foo@bar.com\", \"client_id\": "
      92             :     "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
      93             :     "com\", \"type\": \"service_account\" }";
      94             : 
      95             : static grpc_jwt_verifier_email_domain_key_url_mapping custom_mapping = {
      96             :     "bar.com", "keys.bar.com/jwk"};
      97             : 
      98             : static const char expected_user_data[] = "user data";
      99             : 
     100             : static const char good_jwk_set[] =
     101             :     "{"
     102             :     " \"keys\": ["
     103             :     "  {"
     104             :     "   \"kty\": \"RSA\","
     105             :     "   \"alg\": \"RS256\","
     106             :     "   \"use\": \"sig\","
     107             :     "   \"kid\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\","
     108             :     "   \"n\": "
     109             :     "\"4S8myegefIeRdynuYkSqBYaOLDvU19cHKC56RIqGjrkXFoZuydIz1IxACpWTtDasb4jQ6mxP"
     110             :     "QutZC1nKNJ6D-tYFC9LiGV7gt-KOQ_cnkEb4hcMw_xF_OI1FCx6cBcM0-"
     111             :     "RjiQkK8q7HbF0M6dUXo3t0vedNhmD65Cs2wxPP1TFU=\","
     112             :     "   \"e\": \"AQAB\""
     113             :     "  }"
     114             :     " ]"
     115             :     "}";
     116             : 
     117             : static gpr_timespec expected_lifetime = {3600, 0, GPR_TIMESPAN};
     118             : 
     119             : static const char good_google_email_keys_part1[] =
     120             :     "{\"e6b5137873db8d2ef81e06a47289e6434ec8a165\": \"-----BEGIN "
     121             :     "CERTIFICATE-----"
     122             :     "\\nMIICATCCAWoCCQDEywLhxvHjnDANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB\\nVTET"
     123             :     "MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0\\ncyBQdHkgTHR"
     124             :     "kMB4XDTE1MDYyOTA4Mzk1MFoXDTI1MDYyNjA4Mzk1MFowRTELMAkG\\nA1UEBhMCQVUxEzARBg"
     125             :     "NVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0\\nIFdpZGdpdHMgUHR5IEx0ZDCBn"
     126             :     "zANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4S8m\\nyegefIeRdynuYkSqBYaOLDvU19cHKC56"
     127             :     "RIqGjrkXFoZuydIz1IxACpWTtDasb4jQ\\n6mxPQutZC1nKNJ6D+tYFC9LiGV7gt+KOQ/";
     128             : 
     129             : static const char good_google_email_keys_part2[] =
     130             :     "cnkEb4hcMw/xF/OI1FCx6cBcM0+"
     131             :     "Rji\\nQkK8q7HbF0M6dUXo3t0vedNhmD65Cs2wxPP1TFUCAwEAATANBgkqhkiG9w0BAQsF\\nA"
     132             :     "AOBgQBfu69FkPmBknbKNFgurPz78kbs3VNN+k/"
     133             :     "PUgO5DHKskJmgK2TbtvX2VMpx\\nkftmHGzgzMzUlOtigCaGMgHWjfqjpP9uuDbahXrZBJzB8c"
     134             :     "Oq7MrQF8r17qVvo3Ue\\nPjTKQMAsU8uxTEMmeuz9L6yExs0rfd6bPOrQkAoVfFfiYB3/"
     135             :     "pA==\\n-----END CERTIFICATE-----\\n\"}";
     136             : 
     137             : static const char expected_audience[] = "https://foo.com";
     138             : 
     139             : static const char good_openid_config[] =
     140             :     "{"
     141             :     " \"issuer\": \"https://accounts.google.com\","
     142             :     " \"authorization_endpoint\": "
     143             :     "\"https://accounts.google.com/o/oauth2/v2/auth\","
     144             :     " \"token_endpoint\": \"https://www.googleapis.com/oauth2/v4/token\","
     145             :     " \"userinfo_endpoint\": \"https://www.googleapis.com/oauth2/v3/userinfo\","
     146             :     " \"revocation_endpoint\": \"https://accounts.google.com/o/oauth2/revoke\","
     147             :     " \"jwks_uri\": \"https://www.googleapis.com/oauth2/v3/certs\""
     148             :     "}";
     149             : 
     150             : static const char expired_claims[] =
     151             :     "{ \"aud\": \"https://foo.com\","
     152             :     "  \"iss\": \"blah.foo.com\","
     153             :     "  \"sub\": \"juju@blah.foo.com\","
     154             :     "  \"jti\": \"jwtuniqueid\","
     155             :     "  \"iat\": 100," /* Way back in the past... */
     156             :     "  \"exp\": 120,"
     157             :     "  \"nbf\": 60,"
     158             :     "  \"foo\": \"bar\"}";
     159             : 
     160             : static const char claims_without_time_constraint[] =
     161             :     "{ \"aud\": \"https://foo.com\","
     162             :     "  \"iss\": \"blah.foo.com\","
     163             :     "  \"sub\": \"juju@blah.foo.com\","
     164             :     "  \"jti\": \"jwtuniqueid\","
     165             :     "  \"foo\": \"bar\"}";
     166             : 
     167             : static const char invalid_claims[] =
     168             :     "{ \"aud\": \"https://foo.com\","
     169             :     "  \"iss\": 46," /* Issuer cannot be a number. */
     170             :     "  \"sub\": \"juju@blah.foo.com\","
     171             :     "  \"jti\": \"jwtuniqueid\","
     172             :     "  \"foo\": \"bar\"}";
     173             : 
     174             : typedef struct {
     175             :   grpc_jwt_verifier_status expected_status;
     176             :   const char *expected_issuer;
     177             :   const char *expected_subject;
     178             : } verifier_test_config;
     179             : 
     180           1 : static void test_claims_success(void) {
     181             :   grpc_jwt_claims *claims;
     182           1 :   gpr_slice s = gpr_slice_from_copied_string(claims_without_time_constraint);
     183           2 :   grpc_json *json = grpc_json_parse_string_with_len(
     184           2 :       (char *)GPR_SLICE_START_PTR(s), GPR_SLICE_LENGTH(s));
     185           1 :   GPR_ASSERT(json != NULL);
     186           1 :   claims = grpc_jwt_claims_from_json(json, s);
     187           1 :   GPR_ASSERT(claims != NULL);
     188           1 :   GPR_ASSERT(grpc_jwt_claims_json(claims) == json);
     189           1 :   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), "https://foo.com") == 0);
     190           1 :   GPR_ASSERT(strcmp(grpc_jwt_claims_issuer(claims), "blah.foo.com") == 0);
     191           1 :   GPR_ASSERT(strcmp(grpc_jwt_claims_subject(claims), "juju@blah.foo.com") == 0);
     192           1 :   GPR_ASSERT(strcmp(grpc_jwt_claims_id(claims), "jwtuniqueid") == 0);
     193           1 :   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
     194             :              GRPC_JWT_VERIFIER_OK);
     195           1 :   grpc_jwt_claims_destroy(claims);
     196           1 : }
     197             : 
     198           1 : static void test_expired_claims_failure(void) {
     199             :   grpc_jwt_claims *claims;
     200           1 :   gpr_slice s = gpr_slice_from_copied_string(expired_claims);
     201           2 :   grpc_json *json = grpc_json_parse_string_with_len(
     202           2 :       (char *)GPR_SLICE_START_PTR(s), GPR_SLICE_LENGTH(s));
     203           1 :   gpr_timespec exp_iat = {100, 0, GPR_CLOCK_REALTIME};
     204           1 :   gpr_timespec exp_exp = {120, 0, GPR_CLOCK_REALTIME};
     205           1 :   gpr_timespec exp_nbf = {60, 0, GPR_CLOCK_REALTIME};
     206           1 :   GPR_ASSERT(json != NULL);
     207           1 :   claims = grpc_jwt_claims_from_json(json, s);
     208           1 :   GPR_ASSERT(claims != NULL);
     209           1 :   GPR_ASSERT(grpc_jwt_claims_json(claims) == json);
     210           1 :   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), "https://foo.com") == 0);
     211           1 :   GPR_ASSERT(strcmp(grpc_jwt_claims_issuer(claims), "blah.foo.com") == 0);
     212           1 :   GPR_ASSERT(strcmp(grpc_jwt_claims_subject(claims), "juju@blah.foo.com") == 0);
     213           1 :   GPR_ASSERT(strcmp(grpc_jwt_claims_id(claims), "jwtuniqueid") == 0);
     214           1 :   GPR_ASSERT(gpr_time_cmp(grpc_jwt_claims_issued_at(claims), exp_iat) == 0);
     215           1 :   GPR_ASSERT(gpr_time_cmp(grpc_jwt_claims_expires_at(claims), exp_exp) == 0);
     216           1 :   GPR_ASSERT(gpr_time_cmp(grpc_jwt_claims_not_before(claims), exp_nbf) == 0);
     217             : 
     218           1 :   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
     219             :              GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE);
     220           1 :   grpc_jwt_claims_destroy(claims);
     221           1 : }
     222             : 
     223           1 : static void test_invalid_claims_failure(void) {
     224           1 :   gpr_slice s = gpr_slice_from_copied_string(invalid_claims);
     225           2 :   grpc_json *json = grpc_json_parse_string_with_len(
     226           2 :       (char *)GPR_SLICE_START_PTR(s), GPR_SLICE_LENGTH(s));
     227           1 :   GPR_ASSERT(grpc_jwt_claims_from_json(json, s) == NULL);
     228           1 : }
     229             : 
     230           1 : static void test_bad_audience_claims_failure(void) {
     231             :   grpc_jwt_claims *claims;
     232           1 :   gpr_slice s = gpr_slice_from_copied_string(claims_without_time_constraint);
     233           2 :   grpc_json *json = grpc_json_parse_string_with_len(
     234           2 :       (char *)GPR_SLICE_START_PTR(s), GPR_SLICE_LENGTH(s));
     235           1 :   GPR_ASSERT(json != NULL);
     236           1 :   claims = grpc_jwt_claims_from_json(json, s);
     237           1 :   GPR_ASSERT(claims != NULL);
     238           1 :   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://bar.com") ==
     239             :              GRPC_JWT_VERIFIER_BAD_AUDIENCE);
     240           1 :   grpc_jwt_claims_destroy(claims);
     241           1 : }
     242             : 
     243           6 : static char *json_key_str(const char *last_part) {
     244           6 :   size_t result_len = strlen(json_key_str_part1) + strlen(json_key_str_part2) +
     245           6 :                       strlen(last_part);
     246           6 :   char *result = gpr_malloc(result_len + 1);
     247           6 :   char *current = result;
     248           6 :   strcpy(result, json_key_str_part1);
     249           6 :   current += strlen(json_key_str_part1);
     250           6 :   strcpy(current, json_key_str_part2);
     251           6 :   current += strlen(json_key_str_part2);
     252           6 :   strcpy(current, last_part);
     253           6 :   return result;
     254             : }
     255             : 
     256           1 : static char *good_google_email_keys(void) {
     257           1 :   size_t result_len = strlen(good_google_email_keys_part1) +
     258             :                       strlen(good_google_email_keys_part2);
     259           1 :   char *result = gpr_malloc(result_len + 1);
     260           1 :   char *current = result;
     261           1 :   strcpy(result, good_google_email_keys_part1);
     262           1 :   current += strlen(good_google_email_keys_part1);
     263           1 :   strcpy(current, good_google_email_keys_part2);
     264           1 :   return result;
     265             : }
     266             : 
     267           8 : static grpc_httpcli_response http_response(int status, char *body) {
     268             :   grpc_httpcli_response response;
     269           8 :   memset(&response, 0, sizeof(grpc_httpcli_response));
     270           8 :   response.status = status;
     271           8 :   response.body = body;
     272           8 :   response.body_length = strlen(body);
     273           8 :   return response;
     274             : }
     275             : 
     276           0 : static int httpcli_post_should_not_be_called(
     277             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     278             :     const char *body_bytes, size_t body_size, gpr_timespec deadline,
     279             :     grpc_httpcli_response_cb on_response, void *user_data) {
     280           0 :   GPR_ASSERT("HTTP POST should not be called" == NULL);
     281             :   return 1;
     282             : }
     283             : 
     284           1 : static int httpcli_get_google_keys_for_email(
     285             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     286             :     gpr_timespec deadline, grpc_httpcli_response_cb on_response,
     287             :     void *user_data) {
     288           1 :   grpc_httpcli_response response = http_response(200, good_google_email_keys());
     289           1 :   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
     290           1 :   GPR_ASSERT(strcmp(request->host, "www.googleapis.com") == 0);
     291           1 :   GPR_ASSERT(strcmp(request->path,
     292             :                     "/robot/v1/metadata/x509/"
     293             :                     "777-abaslkan11hlb6nmim3bpspl31ud@developer."
     294             :                     "gserviceaccount.com") == 0);
     295           1 :   on_response(exec_ctx, user_data, &response);
     296           1 :   gpr_free(response.body);
     297           1 :   return 1;
     298             : }
     299             : 
     300           3 : static void on_verification_success(void *user_data,
     301             :                                     grpc_jwt_verifier_status status,
     302             :                                     grpc_jwt_claims *claims) {
     303           3 :   GPR_ASSERT(status == GRPC_JWT_VERIFIER_OK);
     304           3 :   GPR_ASSERT(claims != NULL);
     305           3 :   GPR_ASSERT(user_data == (void *)expected_user_data);
     306           3 :   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), expected_audience) == 0);
     307           3 :   grpc_jwt_claims_destroy(claims);
     308           3 : }
     309             : 
     310           1 : static void test_jwt_verifier_google_email_issuer_success(void) {
     311           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     312           1 :   grpc_jwt_verifier *verifier = grpc_jwt_verifier_create(NULL, 0);
     313           1 :   char *jwt = NULL;
     314           1 :   char *key_str = json_key_str(json_key_str_part3_for_google_email_issuer);
     315           1 :   grpc_auth_json_key key = grpc_auth_json_key_create_from_string(key_str);
     316           1 :   gpr_free(key_str);
     317           1 :   GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
     318           1 :   grpc_httpcli_set_override(httpcli_get_google_keys_for_email,
     319             :                             httpcli_post_should_not_be_called);
     320           1 :   jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
     321             :                                  NULL);
     322           1 :   grpc_auth_json_key_destruct(&key);
     323           1 :   GPR_ASSERT(jwt != NULL);
     324           1 :   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
     325             :                            on_verification_success, (void *)expected_user_data);
     326           1 :   gpr_free(jwt);
     327           1 :   grpc_jwt_verifier_destroy(verifier);
     328           1 :   grpc_httpcli_set_override(NULL, NULL);
     329           1 :   grpc_exec_ctx_finish(&exec_ctx);
     330           1 : }
     331             : 
     332           1 : static int httpcli_get_custom_keys_for_email(
     333             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     334             :     gpr_timespec deadline, grpc_httpcli_response_cb on_response,
     335             :     void *user_data) {
     336           1 :   grpc_httpcli_response response = http_response(200, gpr_strdup(good_jwk_set));
     337           1 :   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
     338           1 :   GPR_ASSERT(strcmp(request->host, "keys.bar.com") == 0);
     339           1 :   GPR_ASSERT(strcmp(request->path, "/jwk/foo@bar.com") == 0);
     340           1 :   on_response(exec_ctx, user_data, &response);
     341           1 :   gpr_free(response.body);
     342           1 :   return 1;
     343             : }
     344             : 
     345           1 : static void test_jwt_verifier_custom_email_issuer_success(void) {
     346           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     347           1 :   grpc_jwt_verifier *verifier = grpc_jwt_verifier_create(&custom_mapping, 1);
     348           1 :   char *jwt = NULL;
     349           1 :   char *key_str = json_key_str(json_key_str_part3_for_custom_email_issuer);
     350           1 :   grpc_auth_json_key key = grpc_auth_json_key_create_from_string(key_str);
     351           1 :   gpr_free(key_str);
     352           1 :   GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
     353           1 :   grpc_httpcli_set_override(httpcli_get_custom_keys_for_email,
     354             :                             httpcli_post_should_not_be_called);
     355           1 :   jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
     356             :                                  NULL);
     357           1 :   grpc_auth_json_key_destruct(&key);
     358           1 :   GPR_ASSERT(jwt != NULL);
     359           1 :   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
     360             :                            on_verification_success, (void *)expected_user_data);
     361           1 :   gpr_free(jwt);
     362           1 :   grpc_jwt_verifier_destroy(verifier);
     363           1 :   grpc_httpcli_set_override(NULL, NULL);
     364           1 :   grpc_exec_ctx_finish(&exec_ctx);
     365           1 : }
     366             : 
     367           2 : static int httpcli_get_jwk_set(grpc_exec_ctx *exec_ctx,
     368             :                                const grpc_httpcli_request *request,
     369             :                                gpr_timespec deadline,
     370             :                                grpc_httpcli_response_cb on_response,
     371             :                                void *user_data) {
     372           2 :   grpc_httpcli_response response = http_response(200, gpr_strdup(good_jwk_set));
     373           2 :   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
     374           2 :   GPR_ASSERT(strcmp(request->host, "www.googleapis.com") == 0);
     375           2 :   GPR_ASSERT(strcmp(request->path, "/oauth2/v3/certs") == 0);
     376           2 :   on_response(exec_ctx, user_data, &response);
     377           2 :   gpr_free(response.body);
     378           2 :   return 1;
     379             : }
     380             : 
     381           2 : static int httpcli_get_openid_config(grpc_exec_ctx *exec_ctx,
     382             :                                      const grpc_httpcli_request *request,
     383             :                                      gpr_timespec deadline,
     384             :                                      grpc_httpcli_response_cb on_response,
     385             :                                      void *user_data) {
     386           2 :   grpc_httpcli_response response =
     387           2 :       http_response(200, gpr_strdup(good_openid_config));
     388           2 :   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
     389           2 :   GPR_ASSERT(strcmp(request->host, "accounts.google.com") == 0);
     390           2 :   GPR_ASSERT(strcmp(request->path, GRPC_OPENID_CONFIG_URL_SUFFIX) == 0);
     391           2 :   grpc_httpcli_set_override(httpcli_get_jwk_set,
     392             :                             httpcli_post_should_not_be_called);
     393           2 :   on_response(exec_ctx, user_data, &response);
     394           2 :   gpr_free(response.body);
     395           2 :   return 1;
     396             : }
     397             : 
     398           1 : static void test_jwt_verifier_url_issuer_success(void) {
     399           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     400           1 :   grpc_jwt_verifier *verifier = grpc_jwt_verifier_create(NULL, 0);
     401           1 :   char *jwt = NULL;
     402           1 :   char *key_str = json_key_str(json_key_str_part3_for_url_issuer);
     403           1 :   grpc_auth_json_key key = grpc_auth_json_key_create_from_string(key_str);
     404           1 :   gpr_free(key_str);
     405           1 :   GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
     406           1 :   grpc_httpcli_set_override(httpcli_get_openid_config,
     407             :                             httpcli_post_should_not_be_called);
     408           1 :   jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
     409             :                                  NULL);
     410           1 :   grpc_auth_json_key_destruct(&key);
     411           1 :   GPR_ASSERT(jwt != NULL);
     412           1 :   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
     413             :                            on_verification_success, (void *)expected_user_data);
     414           1 :   gpr_free(jwt);
     415           1 :   grpc_jwt_verifier_destroy(verifier);
     416           1 :   grpc_httpcli_set_override(NULL, NULL);
     417           1 :   grpc_exec_ctx_finish(&exec_ctx);
     418           1 : }
     419             : 
     420           2 : static void on_verification_key_retrieval_error(void *user_data,
     421             :                                                 grpc_jwt_verifier_status status,
     422             :                                                 grpc_jwt_claims *claims) {
     423           2 :   GPR_ASSERT(status == GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR);
     424           2 :   GPR_ASSERT(claims == NULL);
     425           2 :   GPR_ASSERT(user_data == (void *)expected_user_data);
     426           2 : }
     427             : 
     428           2 : static int httpcli_get_bad_json(grpc_exec_ctx *exec_ctx,
     429             :                                 const grpc_httpcli_request *request,
     430             :                                 gpr_timespec deadline,
     431             :                                 grpc_httpcli_response_cb on_response,
     432             :                                 void *user_data) {
     433           2 :   grpc_httpcli_response response =
     434           2 :       http_response(200, gpr_strdup("{\"bad\": \"stuff\"}"));
     435           2 :   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
     436           2 :   on_response(exec_ctx, user_data, &response);
     437           2 :   gpr_free(response.body);
     438           2 :   return 1;
     439             : }
     440             : 
     441           1 : static void test_jwt_verifier_url_issuer_bad_config(void) {
     442           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     443           1 :   grpc_jwt_verifier *verifier = grpc_jwt_verifier_create(NULL, 0);
     444           1 :   char *jwt = NULL;
     445           1 :   char *key_str = json_key_str(json_key_str_part3_for_url_issuer);
     446           1 :   grpc_auth_json_key key = grpc_auth_json_key_create_from_string(key_str);
     447           1 :   gpr_free(key_str);
     448           1 :   GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
     449           1 :   grpc_httpcli_set_override(httpcli_get_bad_json,
     450             :                             httpcli_post_should_not_be_called);
     451           1 :   jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
     452             :                                  NULL);
     453           1 :   grpc_auth_json_key_destruct(&key);
     454           1 :   GPR_ASSERT(jwt != NULL);
     455           1 :   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
     456             :                            on_verification_key_retrieval_error,
     457             :                            (void *)expected_user_data);
     458           1 :   gpr_free(jwt);
     459           1 :   grpc_jwt_verifier_destroy(verifier);
     460           1 :   grpc_httpcli_set_override(NULL, NULL);
     461           1 :   grpc_exec_ctx_finish(&exec_ctx);
     462           1 : }
     463             : 
     464           1 : static void test_jwt_verifier_bad_json_key(void) {
     465           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     466           1 :   grpc_jwt_verifier *verifier = grpc_jwt_verifier_create(NULL, 0);
     467           1 :   char *jwt = NULL;
     468           1 :   char *key_str = json_key_str(json_key_str_part3_for_google_email_issuer);
     469           1 :   grpc_auth_json_key key = grpc_auth_json_key_create_from_string(key_str);
     470           1 :   gpr_free(key_str);
     471           1 :   GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
     472           1 :   grpc_httpcli_set_override(httpcli_get_bad_json,
     473             :                             httpcli_post_should_not_be_called);
     474           1 :   jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
     475             :                                  NULL);
     476           1 :   grpc_auth_json_key_destruct(&key);
     477           1 :   GPR_ASSERT(jwt != NULL);
     478           1 :   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
     479             :                            on_verification_key_retrieval_error,
     480             :                            (void *)expected_user_data);
     481           1 :   gpr_free(jwt);
     482           1 :   grpc_jwt_verifier_destroy(verifier);
     483           1 :   grpc_httpcli_set_override(NULL, NULL);
     484           1 :   grpc_exec_ctx_finish(&exec_ctx);
     485           1 : }
     486             : 
     487           1 : static void corrupt_jwt_sig(char *jwt) {
     488             :   gpr_slice sig;
     489             :   char *bad_b64_sig;
     490             :   gpr_uint8 *sig_bytes;
     491           1 :   char *last_dot = strrchr(jwt, '.');
     492           1 :   GPR_ASSERT(last_dot != NULL);
     493           1 :   sig = grpc_base64_decode(last_dot + 1, 1);
     494           1 :   GPR_ASSERT(!GPR_SLICE_IS_EMPTY(sig));
     495           1 :   sig_bytes = GPR_SLICE_START_PTR(sig);
     496           1 :   (*sig_bytes)++; /* Corrupt first byte. */
     497           1 :   bad_b64_sig =
     498           1 :       grpc_base64_encode(GPR_SLICE_START_PTR(sig), GPR_SLICE_LENGTH(sig), 1, 0);
     499           1 :   memcpy(last_dot + 1, bad_b64_sig, strlen(bad_b64_sig));
     500           1 :   gpr_free(bad_b64_sig);
     501           1 :   gpr_slice_unref(sig);
     502           1 : }
     503             : 
     504           1 : static void on_verification_bad_signature(void *user_data,
     505             :                                           grpc_jwt_verifier_status status,
     506             :                                           grpc_jwt_claims *claims) {
     507           1 :   GPR_ASSERT(status == GRPC_JWT_VERIFIER_BAD_SIGNATURE);
     508           1 :   GPR_ASSERT(claims == NULL);
     509           1 :   GPR_ASSERT(user_data == (void *)expected_user_data);
     510           1 : }
     511             : 
     512           1 : static void test_jwt_verifier_bad_signature(void) {
     513           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     514           1 :   grpc_jwt_verifier *verifier = grpc_jwt_verifier_create(NULL, 0);
     515           1 :   char *jwt = NULL;
     516           1 :   char *key_str = json_key_str(json_key_str_part3_for_url_issuer);
     517           1 :   grpc_auth_json_key key = grpc_auth_json_key_create_from_string(key_str);
     518           1 :   gpr_free(key_str);
     519           1 :   GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
     520           1 :   grpc_httpcli_set_override(httpcli_get_openid_config,
     521             :                             httpcli_post_should_not_be_called);
     522           1 :   jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
     523             :                                  NULL);
     524           1 :   grpc_auth_json_key_destruct(&key);
     525           1 :   corrupt_jwt_sig(jwt);
     526           1 :   GPR_ASSERT(jwt != NULL);
     527           1 :   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
     528             :                            on_verification_bad_signature,
     529             :                            (void *)expected_user_data);
     530           1 :   gpr_free(jwt);
     531           1 :   grpc_jwt_verifier_destroy(verifier);
     532           1 :   grpc_httpcli_set_override(NULL, NULL);
     533           1 :   grpc_exec_ctx_finish(&exec_ctx);
     534           1 : }
     535             : 
     536           0 : static int httpcli_get_should_not_be_called(
     537             :     grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
     538             :     gpr_timespec deadline, grpc_httpcli_response_cb on_response,
     539             :     void *user_data) {
     540           0 :   GPR_ASSERT(0);
     541             :   return 1;
     542             : }
     543             : 
     544           1 : static void on_verification_bad_format(void *user_data,
     545             :                                        grpc_jwt_verifier_status status,
     546             :                                        grpc_jwt_claims *claims) {
     547           1 :   GPR_ASSERT(status == GRPC_JWT_VERIFIER_BAD_FORMAT);
     548           1 :   GPR_ASSERT(claims == NULL);
     549           1 :   GPR_ASSERT(user_data == (void *)expected_user_data);
     550           1 : }
     551             : 
     552           1 : static void test_jwt_verifier_bad_format(void) {
     553           1 :   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     554           1 :   grpc_jwt_verifier *verifier = grpc_jwt_verifier_create(NULL, 0);
     555           1 :   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
     556             :                             httpcli_post_should_not_be_called);
     557           1 :   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, "bad jwt",
     558             :                            expected_audience, on_verification_bad_format,
     559             :                            (void *)expected_user_data);
     560           1 :   grpc_jwt_verifier_destroy(verifier);
     561           1 :   grpc_httpcli_set_override(NULL, NULL);
     562           1 :   grpc_exec_ctx_finish(&exec_ctx);
     563           1 : }
     564             : 
     565             : /* find verification key: bad jks, cannot find key in jks */
     566             : /* bad signature custom provided email*/
     567             : /* bad key */
     568             : 
     569           1 : int main(int argc, char **argv) {
     570           1 :   grpc_test_init(argc, argv);
     571           1 :   test_claims_success();
     572           1 :   test_expired_claims_failure();
     573           1 :   test_invalid_claims_failure();
     574           1 :   test_bad_audience_claims_failure();
     575           1 :   test_jwt_verifier_google_email_issuer_success();
     576           1 :   test_jwt_verifier_custom_email_issuer_success();
     577           1 :   test_jwt_verifier_url_issuer_success();
     578           1 :   test_jwt_verifier_url_issuer_bad_config();
     579           1 :   test_jwt_verifier_bad_json_key();
     580           1 :   test_jwt_verifier_bad_signature();
     581           1 :   test_jwt_verifier_bad_format();
     582           1 :   return 0;
     583             : }

Generated by: LCOV version 1.10