1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #include "src/core/lib/security/credentials/jwt/json_token.h" 20 21 #include <openssl/evp.h> 22 #include <string.h> 23 24 #include <grpc/grpc_security.h> 25 #include <grpc/slice.h> 26 #include <grpc/support/alloc.h> 27 #include <grpc/support/log.h> 28 29 #include "src/core/lib/json/json.h" 30 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h" 31 #include "src/core/lib/slice/b64.h" 32 #include "src/core/lib/slice/slice_internal.h" 33 #include "test/core/util/test_config.h" 34 35 /* This JSON key was generated with the GCE console and revoked immediately. 36 The identifiers have been changed as well. 37 Maximum size for a string literal is 509 chars in C89, yay! */ 38 static const char test_json_key_str_part1[] = 39 "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----" 40 "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJE" 41 "qg" 42 "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\\nyjSeg/" 43 "rWBQvS4hle4LfijkP3J5BG+" 44 "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\\nOnVF6N7dL3nTYZg+" 45 "uQrNsMTz9UxVAgMBAAECgYEAzbLewe1xe9vy+2GoSsfib+28\\nDZgSE6Bu/" 46 "zuFoPrRc6qL9p2SsnV7txrunTyJkkOnPLND9ABAXybRTlcVKP/sGgza\\n/" 47 "8HpCqFYM9V8f34SBWfD4fRFT+n/" 48 "73cfRUtGXdXpseva2lh8RilIQfPhNZAncenU\\ngqXjDvpkypEusgXAykECQQD+"; 49 static const char test_json_key_str_part2[] = 50 "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\\nCslxoHQM8s+" 51 "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\\nEkoy2L/" 52 "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDA" 53 "G" 54 "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6Hz" 55 "A" 56 "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\\n6z8RJm0+" 57 "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/" 58 "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZ" 59 "Y" 60 "Ap6LI9W\\nIqv4vr6y38N79TTC\\n-----END PRIVATE KEY-----\\n\", "; 61 static const char test_json_key_str_part3[] = 62 "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", " 63 "\"client_email\": " 64 "\"777-abaslkan11hlb6nmim3bpspl31ud (at) developer.gserviceaccount." 65 "com\", \"client_id\": " 66 "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent." 67 "com\", \"type\": \"service_account\" }"; 68 69 /* Test refresh token. */ 70 static const char test_refresh_token_str[] = 71 "{ \"client_id\": \"32555999999.apps.googleusercontent.com\"," 72 " \"client_secret\": \"EmssLNjJy1332hD4KFsecret\"," 73 " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\"," 74 " \"type\": \"authorized_user\"}"; 75 76 static const char test_scope[] = "myperm1 myperm2"; 77 78 static const char test_service_url[] = "https://foo.com/foo.v1"; 79 80 static char* test_json_key_str(const char* bad_part3) { 81 const char* part3 = 82 bad_part3 != nullptr ? bad_part3 : test_json_key_str_part3; 83 size_t result_len = strlen(test_json_key_str_part1) + 84 strlen(test_json_key_str_part2) + strlen(part3); 85 char* result = static_cast<char*>(gpr_malloc(result_len + 1)); 86 char* current = result; 87 strcpy(result, test_json_key_str_part1); 88 current += strlen(test_json_key_str_part1); 89 strcpy(current, test_json_key_str_part2); 90 current += strlen(test_json_key_str_part2); 91 strcpy(current, part3); 92 return result; 93 } 94 95 static void test_parse_json_key_success(void) { 96 char* json_string = test_json_key_str(nullptr); 97 grpc_auth_json_key json_key = 98 grpc_auth_json_key_create_from_string(json_string); 99 GPR_ASSERT(grpc_auth_json_key_is_valid(&json_key)); 100 GPR_ASSERT(json_key.type != nullptr && 101 strcmp(json_key.type, "service_account") == 0); 102 GPR_ASSERT(json_key.private_key_id != nullptr && 103 strcmp(json_key.private_key_id, 104 "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0); 105 GPR_ASSERT(json_key.client_id != nullptr && 106 strcmp(json_key.client_id, 107 "777-abaslkan11hlb6nmim3bpspl31ud.apps." 108 "googleusercontent.com") == 0); 109 GPR_ASSERT(json_key.client_email != nullptr && 110 strcmp(json_key.client_email, 111 "777-abaslkan11hlb6nmim3bpspl31ud@developer." 112 "gserviceaccount.com") == 0); 113 GPR_ASSERT(json_key.private_key != nullptr); 114 gpr_free(json_string); 115 grpc_auth_json_key_destruct(&json_key); 116 } 117 118 static void test_parse_json_key_failure_bad_json(void) { 119 const char non_closing_part3[] = 120 "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", " 121 "\"client_email\": " 122 "\"777-abaslkan11hlb6nmim3bpspl31ud (at) developer.gserviceaccount." 123 "com\", \"client_id\": " 124 "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent." 125 "com\", \"type\": \"service_account\" "; 126 char* json_string = test_json_key_str(non_closing_part3); 127 grpc_auth_json_key json_key = 128 grpc_auth_json_key_create_from_string(json_string); 129 GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key)); 130 gpr_free(json_string); 131 grpc_auth_json_key_destruct(&json_key); 132 } 133 134 static void test_parse_json_key_failure_no_type(void) { 135 const char no_type_part3[] = 136 "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", " 137 "\"client_email\": " 138 "\"777-abaslkan11hlb6nmim3bpspl31ud (at) developer.gserviceaccount." 139 "com\", \"client_id\": " 140 "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent." 141 "com\" }"; 142 char* json_string = test_json_key_str(no_type_part3); 143 grpc_auth_json_key json_key = 144 grpc_auth_json_key_create_from_string(json_string); 145 GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key)); 146 gpr_free(json_string); 147 grpc_auth_json_key_destruct(&json_key); 148 } 149 150 static void test_parse_json_key_failure_no_client_id(void) { 151 const char no_client_id_part3[] = 152 "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", " 153 "\"client_email\": " 154 "\"777-abaslkan11hlb6nmim3bpspl31ud (at) developer.gserviceaccount." 155 "com\", " 156 "\"type\": \"service_account\" }"; 157 char* json_string = test_json_key_str(no_client_id_part3); 158 grpc_auth_json_key json_key = 159 grpc_auth_json_key_create_from_string(json_string); 160 GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key)); 161 gpr_free(json_string); 162 grpc_auth_json_key_destruct(&json_key); 163 } 164 165 static void test_parse_json_key_failure_no_client_email(void) { 166 const char no_client_email_part3[] = 167 "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", " 168 "\"client_id\": " 169 "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent." 170 "com\", \"type\": \"service_account\" }"; 171 char* json_string = test_json_key_str(no_client_email_part3); 172 grpc_auth_json_key json_key = 173 grpc_auth_json_key_create_from_string(json_string); 174 GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key)); 175 gpr_free(json_string); 176 grpc_auth_json_key_destruct(&json_key); 177 } 178 179 static void test_parse_json_key_failure_no_private_key_id(void) { 180 const char no_private_key_id_part3[] = 181 "\"client_email\": " 182 "\"777-abaslkan11hlb6nmim3bpspl31ud (at) developer.gserviceaccount." 183 "com\", \"client_id\": " 184 "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent." 185 "com\", \"type\": \"service_account\" }"; 186 char* json_string = test_json_key_str(no_private_key_id_part3); 187 grpc_auth_json_key json_key = 188 grpc_auth_json_key_create_from_string(json_string); 189 GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key)); 190 gpr_free(json_string); 191 grpc_auth_json_key_destruct(&json_key); 192 } 193 194 static void test_parse_json_key_failure_no_private_key(void) { 195 const char no_private_key_json_string[] = 196 "{ \"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", " 197 "\"client_email\": " 198 "\"777-abaslkan11hlb6nmim3bpspl31ud (at) developer.gserviceaccount." 199 "com\", \"client_id\": " 200 "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent." 201 "com\", \"type\": \"service_account\" }"; 202 grpc_auth_json_key json_key = 203 grpc_auth_json_key_create_from_string(no_private_key_json_string); 204 GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key)); 205 grpc_auth_json_key_destruct(&json_key); 206 } 207 208 static grpc_json* parse_json_part_from_jwt(const char* str, size_t len, 209 char** scratchpad) { 210 grpc_core::ExecCtx exec_ctx; 211 char* b64; 212 char* decoded; 213 grpc_json* json; 214 grpc_slice slice; 215 b64 = static_cast<char*>(gpr_malloc(len + 1)); 216 strncpy(b64, str, len); 217 b64[len] = '\0'; 218 slice = grpc_base64_decode(b64, 1); 219 GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(slice)); 220 decoded = static_cast<char*>(gpr_malloc(GRPC_SLICE_LENGTH(slice) + 1)); 221 strncpy(decoded, reinterpret_cast<const char*> GRPC_SLICE_START_PTR(slice), 222 GRPC_SLICE_LENGTH(slice)); 223 decoded[GRPC_SLICE_LENGTH(slice)] = '\0'; 224 json = grpc_json_parse_string(decoded); 225 gpr_free(b64); 226 *scratchpad = decoded; 227 grpc_slice_unref(slice); 228 229 return json; 230 } 231 232 static void check_jwt_header(grpc_json* header) { 233 grpc_json* ptr; 234 grpc_json* alg = nullptr; 235 grpc_json* typ = nullptr; 236 grpc_json* kid = nullptr; 237 238 for (ptr = header->child; ptr; ptr = ptr->next) { 239 if (strcmp(ptr->key, "alg") == 0) { 240 alg = ptr; 241 } else if (strcmp(ptr->key, "typ") == 0) { 242 typ = ptr; 243 } else if (strcmp(ptr->key, "kid") == 0) { 244 kid = ptr; 245 } 246 } 247 GPR_ASSERT(alg != nullptr); 248 GPR_ASSERT(alg->type == GRPC_JSON_STRING); 249 GPR_ASSERT(strcmp(alg->value, "RS256") == 0); 250 251 GPR_ASSERT(typ != nullptr); 252 GPR_ASSERT(typ->type == GRPC_JSON_STRING); 253 GPR_ASSERT(strcmp(typ->value, "JWT") == 0); 254 255 GPR_ASSERT(kid != nullptr); 256 GPR_ASSERT(kid->type == GRPC_JSON_STRING); 257 GPR_ASSERT(strcmp(kid->value, "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 258 0); 259 } 260 261 static void check_jwt_claim(grpc_json* claim, const char* expected_audience, 262 const char* expected_scope) { 263 gpr_timespec expiration = gpr_time_0(GPR_CLOCK_REALTIME); 264 gpr_timespec issue_time = gpr_time_0(GPR_CLOCK_REALTIME); 265 gpr_timespec parsed_lifetime; 266 grpc_json* iss = nullptr; 267 grpc_json* scope = nullptr; 268 grpc_json* aud = nullptr; 269 grpc_json* exp = nullptr; 270 grpc_json* iat = nullptr; 271 grpc_json* sub = nullptr; 272 grpc_json* ptr; 273 274 for (ptr = claim->child; ptr; ptr = ptr->next) { 275 if (strcmp(ptr->key, "iss") == 0) { 276 iss = ptr; 277 } else if (strcmp(ptr->key, "sub") == 0) { 278 sub = ptr; 279 } else if (strcmp(ptr->key, "scope") == 0) { 280 scope = ptr; 281 } else if (strcmp(ptr->key, "aud") == 0) { 282 aud = ptr; 283 } else if (strcmp(ptr->key, "exp") == 0) { 284 exp = ptr; 285 } else if (strcmp(ptr->key, "iat") == 0) { 286 iat = ptr; 287 } 288 } 289 290 GPR_ASSERT(iss != nullptr); 291 GPR_ASSERT(iss->type == GRPC_JSON_STRING); 292 GPR_ASSERT( 293 strcmp( 294 iss->value, 295 "777-abaslkan11hlb6nmim3bpspl31ud (at) developer.gserviceaccount.com") == 296 0); 297 298 if (expected_scope != nullptr) { 299 GPR_ASSERT(scope != nullptr); 300 GPR_ASSERT(sub == nullptr); 301 GPR_ASSERT(scope->type == GRPC_JSON_STRING); 302 GPR_ASSERT(strcmp(scope->value, expected_scope) == 0); 303 } else { 304 /* Claims without scope must have a sub. */ 305 GPR_ASSERT(scope == nullptr); 306 GPR_ASSERT(sub != nullptr); 307 GPR_ASSERT(sub->type == GRPC_JSON_STRING); 308 GPR_ASSERT(strcmp(iss->value, sub->value) == 0); 309 } 310 311 GPR_ASSERT(aud != nullptr); 312 GPR_ASSERT(aud->type == GRPC_JSON_STRING); 313 GPR_ASSERT(strcmp(aud->value, expected_audience) == 0); 314 315 GPR_ASSERT(exp != nullptr); 316 GPR_ASSERT(exp->type == GRPC_JSON_NUMBER); 317 expiration.tv_sec = strtol(exp->value, nullptr, 10); 318 319 GPR_ASSERT(iat != nullptr); 320 GPR_ASSERT(iat->type == GRPC_JSON_NUMBER); 321 issue_time.tv_sec = strtol(iat->value, nullptr, 10); 322 323 parsed_lifetime = gpr_time_sub(expiration, issue_time); 324 GPR_ASSERT(parsed_lifetime.tv_sec == grpc_max_auth_token_lifetime().tv_sec); 325 } 326 327 static void check_jwt_signature(const char* b64_signature, RSA* rsa_key, 328 const char* signed_data, 329 size_t signed_data_size) { 330 grpc_core::ExecCtx exec_ctx; 331 332 EVP_MD_CTX* md_ctx = EVP_MD_CTX_create(); 333 EVP_PKEY* key = EVP_PKEY_new(); 334 335 grpc_slice sig = grpc_base64_decode(b64_signature, 1); 336 GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(sig)); 337 GPR_ASSERT(GRPC_SLICE_LENGTH(sig) == 128); 338 339 GPR_ASSERT(md_ctx != nullptr); 340 GPR_ASSERT(key != nullptr); 341 EVP_PKEY_set1_RSA(key, rsa_key); 342 343 GPR_ASSERT( 344 EVP_DigestVerifyInit(md_ctx, nullptr, EVP_sha256(), nullptr, key) == 1); 345 GPR_ASSERT(EVP_DigestVerifyUpdate(md_ctx, signed_data, signed_data_size) == 346 1); 347 GPR_ASSERT(EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(sig), 348 GRPC_SLICE_LENGTH(sig)) == 1); 349 350 grpc_slice_unref_internal(sig); 351 if (key != nullptr) EVP_PKEY_free(key); 352 if (md_ctx != nullptr) EVP_MD_CTX_destroy(md_ctx); 353 } 354 355 static char* service_account_creds_jwt_encode_and_sign( 356 const grpc_auth_json_key* key) { 357 return grpc_jwt_encode_and_sign(key, GRPC_JWT_OAUTH2_AUDIENCE, 358 grpc_max_auth_token_lifetime(), test_scope); 359 } 360 361 static char* jwt_creds_jwt_encode_and_sign(const grpc_auth_json_key* key) { 362 return grpc_jwt_encode_and_sign(key, test_service_url, 363 grpc_max_auth_token_lifetime(), nullptr); 364 } 365 366 static void service_account_creds_check_jwt_claim(grpc_json* claim) { 367 check_jwt_claim(claim, GRPC_JWT_OAUTH2_AUDIENCE, test_scope); 368 } 369 370 static void jwt_creds_check_jwt_claim(grpc_json* claim) { 371 check_jwt_claim(claim, test_service_url, nullptr); 372 } 373 374 static void test_jwt_encode_and_sign( 375 char* (*jwt_encode_and_sign_func)(const grpc_auth_json_key*), 376 void (*check_jwt_claim_func)(grpc_json*)) { 377 char* json_string = test_json_key_str(nullptr); 378 grpc_json* parsed_header = nullptr; 379 grpc_json* parsed_claim = nullptr; 380 char* scratchpad; 381 grpc_auth_json_key json_key = 382 grpc_auth_json_key_create_from_string(json_string); 383 const char* b64_signature; 384 size_t offset = 0; 385 char* jwt = jwt_encode_and_sign_func(&json_key); 386 const char* dot = strchr(jwt, '.'); 387 GPR_ASSERT(dot != nullptr); 388 parsed_header = parse_json_part_from_jwt(jwt, static_cast<size_t>(dot - jwt), 389 &scratchpad); 390 GPR_ASSERT(parsed_header != nullptr); 391 check_jwt_header(parsed_header); 392 offset = static_cast<size_t>(dot - jwt) + 1; 393 grpc_json_destroy(parsed_header); 394 gpr_free(scratchpad); 395 396 dot = strchr(jwt + offset, '.'); 397 GPR_ASSERT(dot != nullptr); 398 parsed_claim = parse_json_part_from_jwt( 399 jwt + offset, static_cast<size_t>(dot - (jwt + offset)), &scratchpad); 400 GPR_ASSERT(parsed_claim != nullptr); 401 check_jwt_claim_func(parsed_claim); 402 offset = static_cast<size_t>(dot - jwt) + 1; 403 grpc_json_destroy(parsed_claim); 404 gpr_free(scratchpad); 405 406 dot = strchr(jwt + offset, '.'); 407 GPR_ASSERT(dot == nullptr); /* no more part. */ 408 b64_signature = jwt + offset; 409 check_jwt_signature(b64_signature, json_key.private_key, jwt, offset - 1); 410 411 gpr_free(json_string); 412 grpc_auth_json_key_destruct(&json_key); 413 gpr_free(jwt); 414 } 415 416 static void test_service_account_creds_jwt_encode_and_sign(void) { 417 test_jwt_encode_and_sign(service_account_creds_jwt_encode_and_sign, 418 service_account_creds_check_jwt_claim); 419 } 420 421 static void test_jwt_creds_jwt_encode_and_sign(void) { 422 test_jwt_encode_and_sign(jwt_creds_jwt_encode_and_sign, 423 jwt_creds_check_jwt_claim); 424 } 425 426 static void test_parse_refresh_token_success(void) { 427 grpc_auth_refresh_token refresh_token = 428 grpc_auth_refresh_token_create_from_string(test_refresh_token_str); 429 GPR_ASSERT(grpc_auth_refresh_token_is_valid(&refresh_token)); 430 GPR_ASSERT(refresh_token.type != nullptr && 431 (strcmp(refresh_token.type, "authorized_user") == 0)); 432 GPR_ASSERT(refresh_token.client_id != nullptr && 433 (strcmp(refresh_token.client_id, 434 "32555999999.apps.googleusercontent.com") == 0)); 435 GPR_ASSERT( 436 refresh_token.client_secret != nullptr && 437 (strcmp(refresh_token.client_secret, "EmssLNjJy1332hD4KFsecret") == 0)); 438 GPR_ASSERT(refresh_token.refresh_token != nullptr && 439 (strcmp(refresh_token.refresh_token, 440 "1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42") == 0)); 441 grpc_auth_refresh_token_destruct(&refresh_token); 442 } 443 444 static void test_parse_refresh_token_failure_no_type(void) { 445 const char refresh_token_str[] = 446 "{ \"client_id\": \"32555999999.apps.googleusercontent.com\"," 447 " \"client_secret\": \"EmssLNjJy1332hD4KFsecret\"," 448 " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\"}"; 449 grpc_auth_refresh_token refresh_token = 450 grpc_auth_refresh_token_create_from_string(refresh_token_str); 451 GPR_ASSERT(!grpc_auth_refresh_token_is_valid(&refresh_token)); 452 } 453 454 static void test_parse_refresh_token_failure_no_client_id(void) { 455 const char refresh_token_str[] = 456 "{ \"client_secret\": \"EmssLNjJy1332hD4KFsecret\"," 457 " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\"," 458 " \"type\": \"authorized_user\"}"; 459 grpc_auth_refresh_token refresh_token = 460 grpc_auth_refresh_token_create_from_string(refresh_token_str); 461 GPR_ASSERT(!grpc_auth_refresh_token_is_valid(&refresh_token)); 462 } 463 464 static void test_parse_refresh_token_failure_no_client_secret(void) { 465 const char refresh_token_str[] = 466 "{ \"client_id\": \"32555999999.apps.googleusercontent.com\"," 467 " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\"," 468 " \"type\": \"authorized_user\"}"; 469 grpc_auth_refresh_token refresh_token = 470 grpc_auth_refresh_token_create_from_string(refresh_token_str); 471 GPR_ASSERT(!grpc_auth_refresh_token_is_valid(&refresh_token)); 472 } 473 474 static void test_parse_refresh_token_failure_no_refresh_token(void) { 475 const char refresh_token_str[] = 476 "{ \"client_id\": \"32555999999.apps.googleusercontent.com\"," 477 " \"client_secret\": \"EmssLNjJy1332hD4KFsecret\"," 478 " \"type\": \"authorized_user\"}"; 479 grpc_auth_refresh_token refresh_token = 480 grpc_auth_refresh_token_create_from_string(refresh_token_str); 481 GPR_ASSERT(!grpc_auth_refresh_token_is_valid(&refresh_token)); 482 } 483 484 int main(int argc, char** argv) { 485 grpc_test_init(argc, argv); 486 grpc_init(); 487 test_parse_json_key_success(); 488 test_parse_json_key_failure_bad_json(); 489 test_parse_json_key_failure_no_type(); 490 test_parse_json_key_failure_no_client_id(); 491 test_parse_json_key_failure_no_client_email(); 492 test_parse_json_key_failure_no_private_key_id(); 493 test_parse_json_key_failure_no_private_key(); 494 test_service_account_creds_jwt_encode_and_sign(); 495 test_jwt_creds_jwt_encode_and_sign(); 496 test_parse_refresh_token_success(); 497 test_parse_refresh_token_failure_no_type(); 498 test_parse_refresh_token_failure_no_client_id(); 499 test_parse_refresh_token_failure_no_client_secret(); 500 test_parse_refresh_token_failure_no_refresh_token(); 501 grpc_shutdown(); 502 return 0; 503 } 504