• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
test_json_key_str(const char * bad_part3)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 
test_parse_json_key_success(void)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 
test_parse_json_key_failure_bad_json(void)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@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 
test_parse_json_key_failure_no_type(void)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@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 
test_parse_json_key_failure_no_client_id(void)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@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 
test_parse_json_key_failure_no_client_email(void)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 
test_parse_json_key_failure_no_private_key_id(void)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@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 
test_parse_json_key_failure_no_private_key(void)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@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 
parse_json_part_from_jwt(const char * str,size_t len,char ** scratchpad)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 
check_jwt_header(grpc_json * header)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 
check_jwt_claim(grpc_json * claim,const char * expected_audience,const char * expected_scope)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@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 
check_jwt_signature(const char * b64_signature,RSA * rsa_key,const char * signed_data,size_t signed_data_size)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 
service_account_creds_jwt_encode_and_sign(const grpc_auth_json_key * key)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 
jwt_creds_jwt_encode_and_sign(const grpc_auth_json_key * key)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 
service_account_creds_check_jwt_claim(grpc_json * claim)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 
jwt_creds_check_jwt_claim(grpc_json * claim)370 static void jwt_creds_check_jwt_claim(grpc_json* claim) {
371   check_jwt_claim(claim, test_service_url, nullptr);
372 }
373 
test_jwt_encode_and_sign(char * (* jwt_encode_and_sign_func)(const grpc_auth_json_key *),void (* check_jwt_claim_func)(grpc_json *))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 
test_service_account_creds_jwt_encode_and_sign(void)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 
test_jwt_creds_jwt_encode_and_sign(void)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 
test_parse_refresh_token_success(void)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 
test_parse_refresh_token_failure_no_type(void)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 
test_parse_refresh_token_failure_no_client_id(void)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 
test_parse_refresh_token_failure_no_client_secret(void)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 
test_parse_refresh_token_failure_no_refresh_token(void)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 
main(int argc,char ** argv)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