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 <gmock/gmock.h>
20 #include <grpc/grpc.h>
21 #include <grpcpp/security/credentials.h>
22 #include <grpcpp/security/server_credentials.h>
23 #include <grpcpp/security/tls_credentials_options.h>
24 #include <grpcpp/server_builder.h>
25 #include <gtest/gtest.h>
26 
27 #include <memory>
28 
29 #include "src/core/lib/gpr/env.h"
30 #include "src/core/lib/gpr/tmpfile.h"
31 #include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
32 #include "src/cpp/client/secure_credentials.h"
33 #include "src/cpp/common/tls_credentials_options_util.h"
34 
35 namespace {
36 
37 typedef class ::grpc_impl::experimental::TlsKeyMaterialsConfig
38     TlsKeyMaterialsConfig;
39 typedef class ::grpc_impl::experimental::TlsCredentialReloadArg
40     TlsCredentialReloadArg;
41 typedef struct ::grpc_impl::experimental::TlsCredentialReloadInterface
42     TlsCredentialReloadInterface;
43 typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckArg
44     TlsServerAuthorizationCheckArg;
45 typedef struct ::grpc_impl::experimental::TlsServerAuthorizationCheckInterface
46     TlsServerAuthorizationCheckInterface;
47 
tls_credential_reload_callback(grpc_tls_credential_reload_arg * arg)48 static void tls_credential_reload_callback(
49     grpc_tls_credential_reload_arg* arg) {
50   GPR_ASSERT(arg != nullptr);
51   arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
52 }
53 
54 class TestTlsCredentialReload : public TlsCredentialReloadInterface {
Schedule(TlsCredentialReloadArg * arg)55   int Schedule(TlsCredentialReloadArg* arg) override {
56     GPR_ASSERT(arg != nullptr);
57     TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key3",
58                                                   "cert_chain3"};
59     arg->set_pem_root_certs("new_pem_root_certs");
60     arg->add_pem_key_cert_pair(pair);
61     arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
62     return 0;
63   }
64 
Cancel(TlsCredentialReloadArg * arg)65   void Cancel(TlsCredentialReloadArg* arg) override {
66     GPR_ASSERT(arg != nullptr);
67     arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
68     arg->set_error_details("cancelled");
69   }
70 };
71 
tls_server_authorization_check_callback(grpc_tls_server_authorization_check_arg * arg)72 static void tls_server_authorization_check_callback(
73     grpc_tls_server_authorization_check_arg* arg) {
74   GPR_ASSERT(arg != nullptr);
75   grpc::string cb_user_data = "cb_user_data";
76   arg->cb_user_data = static_cast<void*>(gpr_strdup(cb_user_data.c_str()));
77   arg->success = 1;
78   arg->target_name = gpr_strdup("callback_target_name");
79   arg->peer_cert = gpr_strdup("callback_peer_cert");
80   arg->status = GRPC_STATUS_OK;
81   arg->error_details->set_error_details("callback_error_details");
82 }
83 
84 class TestTlsServerAuthorizationCheck
85     : public TlsServerAuthorizationCheckInterface {
Schedule(TlsServerAuthorizationCheckArg * arg)86   int Schedule(TlsServerAuthorizationCheckArg* arg) override {
87     GPR_ASSERT(arg != nullptr);
88     grpc::string cb_user_data = "cb_user_data";
89     arg->set_cb_user_data(static_cast<void*>(gpr_strdup(cb_user_data.c_str())));
90     arg->set_success(1);
91     arg->set_target_name("sync_target_name");
92     arg->set_peer_cert("sync_peer_cert");
93     arg->set_status(GRPC_STATUS_OK);
94     arg->set_error_details("sync_error_details");
95     return 1;
96   }
97 
Cancel(TlsServerAuthorizationCheckArg * arg)98   void Cancel(TlsServerAuthorizationCheckArg* arg) override {
99     GPR_ASSERT(arg != nullptr);
100     arg->set_status(GRPC_STATUS_PERMISSION_DENIED);
101     arg->set_error_details("cancelled");
102   }
103 };
104 }  // namespace
105 
106 namespace grpc {
107 namespace testing {
108 
109 class CredentialsTest : public ::testing::Test {
110  protected:
111 };
112 
TEST_F(CredentialsTest,InvalidGoogleRefreshToken)113 TEST_F(CredentialsTest, InvalidGoogleRefreshToken) {
114   std::shared_ptr<CallCredentials> bad1 = GoogleRefreshTokenCredentials("");
115   EXPECT_EQ(static_cast<CallCredentials*>(nullptr), bad1.get());
116 }
117 
TEST_F(CredentialsTest,DefaultCredentials)118 TEST_F(CredentialsTest, DefaultCredentials) {
119   auto creds = GoogleDefaultCredentials();
120 }
121 
TEST_F(CredentialsTest,StsCredentialsOptionsCppToCore)122 TEST_F(CredentialsTest, StsCredentialsOptionsCppToCore) {
123   grpc::experimental::StsCredentialsOptions options;
124   options.token_exchange_service_uri = "https://foo.com/exchange";
125   options.resource = "resource";
126   options.audience = "audience";
127   options.scope = "scope";
128   // options.requested_token_type explicitly not set.
129   options.subject_token_path = "/foo/bar";
130   options.subject_token_type = "nice_token_type";
131   options.actor_token_path = "/foo/baz";
132   options.actor_token_type = "even_nicer_token_type";
133   grpc_sts_credentials_options core_opts =
134       grpc_impl::experimental::StsCredentialsCppToCoreOptions(options);
135   EXPECT_EQ(options.token_exchange_service_uri,
136             core_opts.token_exchange_service_uri);
137   EXPECT_EQ(options.resource, core_opts.resource);
138   EXPECT_EQ(options.audience, core_opts.audience);
139   EXPECT_EQ(options.scope, core_opts.scope);
140   EXPECT_EQ(options.requested_token_type, core_opts.requested_token_type);
141   EXPECT_EQ(options.subject_token_path, core_opts.subject_token_path);
142   EXPECT_EQ(options.subject_token_type, core_opts.subject_token_type);
143   EXPECT_EQ(options.actor_token_path, core_opts.actor_token_path);
144   EXPECT_EQ(options.actor_token_type, core_opts.actor_token_type);
145 }
146 
TEST_F(CredentialsTest,StsCredentialsOptionsJson)147 TEST_F(CredentialsTest, StsCredentialsOptionsJson) {
148   const char valid_json[] = R"(
149   {
150     "token_exchange_service_uri": "https://foo/exchange",
151     "resource": "resource",
152     "audience": "audience",
153     "scope": "scope",
154     "requested_token_type": "requested_token_type",
155     "subject_token_path": "subject_token_path",
156     "subject_token_type": "subject_token_type",
157     "actor_token_path": "actor_token_path",
158     "actor_token_type": "actor_token_type"
159   })";
160   grpc::experimental::StsCredentialsOptions options;
161   EXPECT_TRUE(
162       grpc::experimental::StsCredentialsOptionsFromJson(valid_json, &options)
163           .ok());
164   EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange");
165   EXPECT_EQ(options.resource, "resource");
166   EXPECT_EQ(options.audience, "audience");
167   EXPECT_EQ(options.scope, "scope");
168   EXPECT_EQ(options.requested_token_type, "requested_token_type");
169   EXPECT_EQ(options.subject_token_path, "subject_token_path");
170   EXPECT_EQ(options.subject_token_type, "subject_token_type");
171   EXPECT_EQ(options.actor_token_path, "actor_token_path");
172   EXPECT_EQ(options.actor_token_type, "actor_token_type");
173 
174   const char minimum_valid_json[] = R"(
175   {
176     "token_exchange_service_uri": "https://foo/exchange",
177     "subject_token_path": "subject_token_path",
178     "subject_token_type": "subject_token_type"
179   })";
180   EXPECT_TRUE(grpc::experimental::StsCredentialsOptionsFromJson(
181                   minimum_valid_json, &options)
182                   .ok());
183   EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange");
184   EXPECT_EQ(options.resource, "");
185   EXPECT_EQ(options.audience, "");
186   EXPECT_EQ(options.scope, "");
187   EXPECT_EQ(options.requested_token_type, "");
188   EXPECT_EQ(options.subject_token_path, "subject_token_path");
189   EXPECT_EQ(options.subject_token_type, "subject_token_type");
190   EXPECT_EQ(options.actor_token_path, "");
191   EXPECT_EQ(options.actor_token_type, "");
192 
193   const char invalid_json[] = R"(
194   I'm not a valid JSON.
195   )";
196   EXPECT_EQ(
197       grpc::StatusCode::INVALID_ARGUMENT,
198       grpc::experimental::StsCredentialsOptionsFromJson(invalid_json, &options)
199           .error_code());
200 
201   const char invalid_json_missing_subject_token_type[] = R"(
202   {
203     "token_exchange_service_uri": "https://foo/exchange",
204     "subject_token_path": "subject_token_path"
205   })";
206   auto status = grpc::experimental::StsCredentialsOptionsFromJson(
207       invalid_json_missing_subject_token_type, &options);
208   EXPECT_EQ(grpc::StatusCode::INVALID_ARGUMENT, status.error_code());
209   EXPECT_THAT(status.error_message(),
210               ::testing::HasSubstr("subject_token_type"));
211 
212   const char invalid_json_missing_subject_token_path[] = R"(
213   {
214     "token_exchange_service_uri": "https://foo/exchange",
215     "subject_token_type": "subject_token_type"
216   })";
217   status = grpc::experimental::StsCredentialsOptionsFromJson(
218       invalid_json_missing_subject_token_path, &options);
219   EXPECT_EQ(grpc::StatusCode::INVALID_ARGUMENT, status.error_code());
220   EXPECT_THAT(status.error_message(),
221               ::testing::HasSubstr("subject_token_path"));
222 
223   const char invalid_json_missing_token_exchange_uri[] = R"(
224   {
225     "subject_token_path": "subject_token_path",
226     "subject_token_type": "subject_token_type"
227   })";
228   status = grpc::experimental::StsCredentialsOptionsFromJson(
229       invalid_json_missing_token_exchange_uri, &options);
230   EXPECT_EQ(grpc::StatusCode::INVALID_ARGUMENT, status.error_code());
231   EXPECT_THAT(status.error_message(),
232               ::testing::HasSubstr("token_exchange_service_uri"));
233 }
234 
TEST_F(CredentialsTest,StsCredentialsOptionsFromEnv)235 TEST_F(CredentialsTest, StsCredentialsOptionsFromEnv) {
236   // Unset env and check expected failure.
237   gpr_unsetenv("STS_CREDENTIALS");
238   grpc::experimental::StsCredentialsOptions options;
239   auto status = grpc::experimental::StsCredentialsOptionsFromEnv(&options);
240   EXPECT_EQ(grpc::StatusCode::NOT_FOUND, status.error_code());
241 
242   // Set env and check for success.
243   const char valid_json[] = R"(
244   {
245     "token_exchange_service_uri": "https://foo/exchange",
246     "subject_token_path": "subject_token_path",
247     "subject_token_type": "subject_token_type"
248   })";
249   char* creds_file_name;
250   FILE* creds_file = gpr_tmpfile("sts_creds_options", &creds_file_name);
251   ASSERT_NE(creds_file_name, nullptr);
252   ASSERT_NE(creds_file, nullptr);
253   ASSERT_EQ(sizeof(valid_json),
254             fwrite(valid_json, 1, sizeof(valid_json), creds_file));
255   fclose(creds_file);
256   gpr_setenv("STS_CREDENTIALS", creds_file_name);
257   gpr_free(creds_file_name);
258   status = grpc::experimental::StsCredentialsOptionsFromEnv(&options);
259   EXPECT_TRUE(status.ok());
260   EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange");
261   EXPECT_EQ(options.resource, "");
262   EXPECT_EQ(options.audience, "");
263   EXPECT_EQ(options.scope, "");
264   EXPECT_EQ(options.requested_token_type, "");
265   EXPECT_EQ(options.subject_token_path, "subject_token_path");
266   EXPECT_EQ(options.subject_token_type, "subject_token_type");
267   EXPECT_EQ(options.actor_token_path, "");
268   EXPECT_EQ(options.actor_token_type, "");
269 
270   // Cleanup.
271   gpr_unsetenv("STS_CREDENTIALS");
272 }
273 
274 typedef class ::grpc_impl::experimental::TlsKeyMaterialsConfig
275     TlsKeyMaterialsConfig;
276 
TEST_F(CredentialsTest,TlsKeyMaterialsConfigCppToC)277 TEST_F(CredentialsTest, TlsKeyMaterialsConfigCppToC) {
278   std::shared_ptr<TlsKeyMaterialsConfig> config(new TlsKeyMaterialsConfig());
279   struct TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key",
280                                                        "cert_chain"};
281   std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pair_list = {pair};
282   config->set_key_materials("pem_root_certs", pair_list);
283   grpc_tls_key_materials_config* c_config =
284       ConvertToCKeyMaterialsConfig(config);
285   EXPECT_STREQ("pem_root_certs", c_config->pem_root_certs());
286   EXPECT_EQ(1, static_cast<int>(c_config->pem_key_cert_pair_list().size()));
287   EXPECT_STREQ(pair.private_key.c_str(),
288                c_config->pem_key_cert_pair_list()[0].private_key());
289   EXPECT_STREQ(pair.cert_chain.c_str(),
290                c_config->pem_key_cert_pair_list()[0].cert_chain());
291   delete c_config;
292 }
293 
TEST_F(CredentialsTest,TlsKeyMaterialsModifiers)294 TEST_F(CredentialsTest, TlsKeyMaterialsModifiers) {
295   std::shared_ptr<TlsKeyMaterialsConfig> config(new TlsKeyMaterialsConfig());
296   TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key", "cert_chain"};
297   config->add_pem_key_cert_pair(pair);
298   config->set_pem_root_certs("pem_root_certs");
299   EXPECT_STREQ(config->pem_root_certs().c_str(), "pem_root_certs");
300   std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> list =
301       config->pem_key_cert_pair_list();
302   EXPECT_EQ(static_cast<int>(list.size()), 1);
303   EXPECT_STREQ(list[0].private_key.c_str(), "private_key");
304   EXPECT_STREQ(list[0].cert_chain.c_str(), "cert_chain");
305 }
306 
307 typedef class ::grpc_impl::experimental::TlsCredentialReloadArg
308     TlsCredentialReloadArg;
309 typedef class ::grpc_impl::experimental::TlsCredentialReloadConfig
310     TlsCredentialReloadConfig;
311 
TEST_F(CredentialsTest,TlsCredentialReloadArgCallback)312 TEST_F(CredentialsTest, TlsCredentialReloadArgCallback) {
313   grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg;
314   c_arg->key_materials_config = grpc_tls_key_materials_config_create();
315   c_arg->cb = tls_credential_reload_callback;
316   c_arg->context = nullptr;
317   TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg);
318   arg->set_pem_root_certs("pem_root_certs");
319   TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key", "cert_chain"};
320   arg->add_pem_key_cert_pair(pair);
321   arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
322   arg->OnCredentialReloadDoneCallback();
323   EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
324   EXPECT_STREQ(c_arg->key_materials_config->pem_root_certs(), "pem_root_certs");
325   EXPECT_EQ(c_arg->key_materials_config->pem_key_cert_pair_list().size(), 1);
326   EXPECT_STREQ(
327       c_arg->key_materials_config->pem_key_cert_pair_list()[0].private_key(),
328       "private_key");
329   EXPECT_STREQ(
330       c_arg->key_materials_config->pem_key_cert_pair_list()[0].cert_chain(),
331       "cert_chain");
332 
333   // Cleanup.
334   delete arg;
335   delete c_arg->key_materials_config;
336   delete c_arg;
337 }
338 
TEST_F(CredentialsTest,TlsCredentialReloadConfigSchedule)339 TEST_F(CredentialsTest, TlsCredentialReloadConfigSchedule) {
340   std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
341       new TestTlsCredentialReload());
342   std::shared_ptr<TlsCredentialReloadConfig> config(
343       new TlsCredentialReloadConfig(test_credential_reload));
344   grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg();
345   c_arg->error_details = new grpc_tls_error_details();
346   c_arg->context = nullptr;
347   TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg);
348   struct TlsKeyMaterialsConfig::PemKeyCertPair pair1 = {"private_key1",
349                                                         "cert_chain1"};
350   struct TlsKeyMaterialsConfig::PemKeyCertPair pair2 = {"private_key2",
351                                                         "cert_chain2"};
352   std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pair_list = {pair1, pair2};
353   arg->set_key_materials("pem_root_certs", pair_list);
354   arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
355   arg->set_error_details("error_details");
356 
357   int schedule_output = config->Schedule(arg);
358   EXPECT_EQ(schedule_output, 0);
359   EXPECT_STREQ(c_arg->key_materials_config->pem_root_certs(),
360                "new_pem_root_certs");
361   grpc_tls_key_materials_config::PemKeyCertPairList c_pair_list =
362       c_arg->key_materials_config->pem_key_cert_pair_list();
363   EXPECT_TRUE(!arg->is_pem_key_cert_pair_list_empty());
364   EXPECT_EQ(static_cast<int>(c_pair_list.size()), 3);
365   EXPECT_STREQ(c_pair_list[0].private_key(), "private_key1");
366   EXPECT_STREQ(c_pair_list[0].cert_chain(), "cert_chain1");
367   EXPECT_STREQ(c_pair_list[1].private_key(), "private_key2");
368   EXPECT_STREQ(c_pair_list[1].cert_chain(), "cert_chain2");
369   EXPECT_STREQ(c_pair_list[2].private_key(), "private_key3");
370   EXPECT_STREQ(c_pair_list[2].cert_chain(), "cert_chain3");
371   EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
372   EXPECT_STREQ(arg->error_details().c_str(), "error_details");
373 
374   // Cleanup.
375   delete c_arg->key_materials_config;
376   if (c_arg->destroy_context != nullptr) {
377     c_arg->destroy_context(c_arg->context);
378   }
379   delete c_arg->error_details;
380   delete c_arg;
381   delete config->c_config();
382 }
383 
TEST_F(CredentialsTest,TlsCredentialReloadConfigCppToC)384 TEST_F(CredentialsTest, TlsCredentialReloadConfigCppToC) {
385   std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
386       new TestTlsCredentialReload());
387   TlsCredentialReloadConfig config(test_credential_reload);
388   grpc_tls_credential_reload_arg c_arg;
389   c_arg.error_details = new grpc_tls_error_details();
390   c_arg.context = nullptr;
391   c_arg.cb_user_data = static_cast<void*>(nullptr);
392   grpc_tls_key_materials_config c_key_materials;
393   grpc::string test_private_key = "private_key";
394   grpc::string test_cert_chain = "cert_chain";
395   grpc_ssl_pem_key_cert_pair* ssl_pair =
396       (grpc_ssl_pem_key_cert_pair*)gpr_malloc(
397           sizeof(grpc_ssl_pem_key_cert_pair));
398   ssl_pair->private_key = gpr_strdup(test_private_key.c_str());
399   ssl_pair->cert_chain = gpr_strdup(test_cert_chain.c_str());
400   ::grpc_core::PemKeyCertPair pem_key_cert_pair =
401       ::grpc_core::PemKeyCertPair(ssl_pair);
402   ::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1> pem_key_cert_pair_list;
403   pem_key_cert_pair_list.push_back(pem_key_cert_pair);
404   grpc::string test_pem_root_certs = "pem_root_certs";
405   c_key_materials.set_key_materials(test_pem_root_certs.c_str(),
406                                     pem_key_cert_pair_list);
407   c_arg.key_materials_config = &c_key_materials;
408   c_arg.status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
409   grpc::string test_error_details = "error_details";
410   c_arg.error_details->set_error_details(test_error_details.c_str());
411 
412   grpc_tls_credential_reload_config* c_config = config.c_config();
413   c_arg.config = c_config;
414   int c_schedule_output = c_config->Schedule(&c_arg);
415   EXPECT_EQ(c_schedule_output, 0);
416   EXPECT_EQ(c_arg.cb_user_data, nullptr);
417   EXPECT_STREQ(c_arg.key_materials_config->pem_root_certs(),
418                "new_pem_root_certs");
419   ::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1> pair_list =
420       c_arg.key_materials_config->pem_key_cert_pair_list();
421   EXPECT_EQ(static_cast<int>(pair_list.size()), 2);
422   EXPECT_STREQ(pair_list[0].private_key(), "private_key");
423   EXPECT_STREQ(pair_list[0].cert_chain(), "cert_chain");
424   EXPECT_STREQ(pair_list[1].private_key(), "private_key3");
425   EXPECT_STREQ(pair_list[1].cert_chain(), "cert_chain3");
426   EXPECT_EQ(c_arg.status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
427   EXPECT_STREQ(c_arg.error_details->error_details().c_str(),
428                test_error_details.c_str());
429 
430   // Cleanup.
431   c_arg.destroy_context(c_arg.context);
432   delete c_arg.error_details;
433   delete config.c_config();
434 }
435 
436 typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckArg
437     TlsServerAuthorizationCheckArg;
438 typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckConfig
439     TlsServerAuthorizationCheckConfig;
440 
TEST_F(CredentialsTest,TlsServerAuthorizationCheckArgCallback)441 TEST_F(CredentialsTest, TlsServerAuthorizationCheckArgCallback) {
442   grpc_tls_server_authorization_check_arg* c_arg =
443       new grpc_tls_server_authorization_check_arg;
444   c_arg->cb = tls_server_authorization_check_callback;
445   c_arg->context = nullptr;
446   c_arg->error_details = new grpc_tls_error_details();
447   TlsServerAuthorizationCheckArg* arg =
448       new TlsServerAuthorizationCheckArg(c_arg);
449   arg->set_cb_user_data(nullptr);
450   arg->set_success(0);
451   arg->set_target_name("target_name");
452   arg->set_peer_cert("peer_cert");
453   arg->set_status(GRPC_STATUS_UNAUTHENTICATED);
454   arg->set_error_details("error_details");
455   const char* target_name_before_callback = c_arg->target_name;
456   const char* peer_cert_before_callback = c_arg->peer_cert;
457 
458   arg->OnServerAuthorizationCheckDoneCallback();
459   EXPECT_STREQ(static_cast<char*>(arg->cb_user_data()), "cb_user_data");
460   gpr_free(arg->cb_user_data());
461   EXPECT_EQ(arg->success(), 1);
462   EXPECT_STREQ(arg->target_name().c_str(), "callback_target_name");
463   EXPECT_STREQ(arg->peer_cert().c_str(), "callback_peer_cert");
464   EXPECT_EQ(arg->status(), GRPC_STATUS_OK);
465   EXPECT_STREQ(arg->error_details().c_str(), "callback_error_details");
466 
467   // Cleanup.
468   gpr_free(const_cast<char*>(target_name_before_callback));
469   gpr_free(const_cast<char*>(peer_cert_before_callback));
470   gpr_free(const_cast<char*>(c_arg->target_name));
471   gpr_free(const_cast<char*>(c_arg->peer_cert));
472   delete c_arg->error_details;
473   delete arg;
474   delete c_arg;
475 }
476 
TEST_F(CredentialsTest,TlsServerAuthorizationCheckConfigSchedule)477 TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) {
478   std::shared_ptr<TestTlsServerAuthorizationCheck>
479       test_server_authorization_check(new TestTlsServerAuthorizationCheck());
480   TlsServerAuthorizationCheckConfig config(test_server_authorization_check);
481   grpc_tls_server_authorization_check_arg* c_arg =
482       new grpc_tls_server_authorization_check_arg();
483   c_arg->error_details = new grpc_tls_error_details();
484   c_arg->context = nullptr;
485   TlsServerAuthorizationCheckArg* arg =
486       new TlsServerAuthorizationCheckArg(c_arg);
487   arg->set_cb_user_data(nullptr);
488   arg->set_success(0);
489   arg->set_target_name("target_name");
490   arg->set_peer_cert("peer_cert");
491   arg->set_status(GRPC_STATUS_PERMISSION_DENIED);
492   arg->set_error_details("error_details");
493   const char* target_name_before_schedule = c_arg->target_name;
494   const char* peer_cert_before_schedule = c_arg->peer_cert;
495 
496   int schedule_output = config.Schedule(arg);
497   EXPECT_EQ(schedule_output, 1);
498   EXPECT_STREQ(static_cast<char*>(arg->cb_user_data()), "cb_user_data");
499   EXPECT_EQ(arg->success(), 1);
500   EXPECT_STREQ(arg->target_name().c_str(), "sync_target_name");
501   EXPECT_STREQ(arg->peer_cert().c_str(), "sync_peer_cert");
502   EXPECT_EQ(arg->status(), GRPC_STATUS_OK);
503   EXPECT_STREQ(arg->error_details().c_str(), "sync_error_details");
504 
505   // Cleanup.
506   gpr_free(arg->cb_user_data());
507   gpr_free(const_cast<char*>(target_name_before_schedule));
508   gpr_free(const_cast<char*>(peer_cert_before_schedule));
509   gpr_free(const_cast<char*>(c_arg->target_name));
510   gpr_free(const_cast<char*>(c_arg->peer_cert));
511   delete c_arg->error_details;
512   if (c_arg->destroy_context != nullptr) {
513     c_arg->destroy_context(c_arg->context);
514   }
515   delete c_arg;
516   delete config.c_config();
517 }
518 
TEST_F(CredentialsTest,TlsServerAuthorizationCheckConfigCppToC)519 TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) {
520   std::shared_ptr<TestTlsServerAuthorizationCheck>
521       test_server_authorization_check(new TestTlsServerAuthorizationCheck());
522   TlsServerAuthorizationCheckConfig config(test_server_authorization_check);
523   grpc_tls_server_authorization_check_arg c_arg;
524   c_arg.cb = tls_server_authorization_check_callback;
525   c_arg.cb_user_data = nullptr;
526   c_arg.success = 0;
527   c_arg.target_name = "target_name";
528   c_arg.peer_cert = "peer_cert";
529   c_arg.status = GRPC_STATUS_UNAUTHENTICATED;
530   c_arg.error_details = new grpc_tls_error_details();
531   c_arg.error_details->set_error_details("error_details");
532   c_arg.config = config.c_config();
533   c_arg.context = nullptr;
534   int c_schedule_output = (c_arg.config)->Schedule(&c_arg);
535   EXPECT_EQ(c_schedule_output, 1);
536   EXPECT_STREQ(static_cast<char*>(c_arg.cb_user_data), "cb_user_data");
537   EXPECT_EQ(c_arg.success, 1);
538   EXPECT_STREQ(c_arg.target_name, "sync_target_name");
539   EXPECT_STREQ(c_arg.peer_cert, "sync_peer_cert");
540   EXPECT_EQ(c_arg.status, GRPC_STATUS_OK);
541   EXPECT_STREQ(c_arg.error_details->error_details().c_str(),
542                "sync_error_details");
543 
544   // Cleanup.
545   gpr_free(c_arg.cb_user_data);
546   c_arg.destroy_context(c_arg.context);
547   delete c_arg.error_details;
548   gpr_free(const_cast<char*>(c_arg.target_name));
549   gpr_free(const_cast<char*>(c_arg.peer_cert));
550   delete config.c_config();
551 }
552 
553 typedef class ::grpc_impl::experimental::TlsCredentialsOptions
554     TlsCredentialsOptions;
555 
TEST_F(CredentialsTest,TlsCredentialsOptionsCppToC)556 TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) {
557   std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config(
558       new TlsKeyMaterialsConfig());
559   struct TlsKeyMaterialsConfig::PemKeyCertPair pair = {"private_key",
560                                                        "cert_chain"};
561   std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pair_list = {pair};
562   key_materials_config->set_key_materials("pem_root_certs", pair_list);
563 
564   std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
565       new TestTlsCredentialReload());
566   std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config(
567       new TlsCredentialReloadConfig(test_credential_reload));
568 
569   std::shared_ptr<TestTlsServerAuthorizationCheck>
570       test_server_authorization_check(new TestTlsServerAuthorizationCheck());
571   std::shared_ptr<TlsServerAuthorizationCheckConfig>
572       server_authorization_check_config(new TlsServerAuthorizationCheckConfig(
573           test_server_authorization_check));
574 
575   TlsCredentialsOptions options = TlsCredentialsOptions(
576       GRPC_TLS_SERVER_VERIFICATION, key_materials_config,
577       credential_reload_config, server_authorization_check_config);
578   grpc_tls_credentials_options* c_options = options.c_credentials_options();
579   EXPECT_EQ(c_options->cert_request_type(),
580             GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
581   EXPECT_EQ(c_options->server_verification_option(),
582             GRPC_TLS_SERVER_VERIFICATION);
583   grpc_tls_key_materials_config* c_key_materials_config =
584       c_options->key_materials_config();
585   grpc_tls_credential_reload_config* c_credential_reload_config =
586       c_options->credential_reload_config();
587   grpc_tls_credential_reload_arg c_credential_reload_arg;
588   c_credential_reload_arg.cb_user_data = nullptr;
589   c_credential_reload_arg.key_materials_config =
590       c_options->key_materials_config();
591   c_credential_reload_arg.status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED;
592   grpc::string test_error_details = "error_details";
593   c_credential_reload_arg.error_details = new grpc_tls_error_details();
594   c_credential_reload_arg.error_details->set_error_details(
595       test_error_details.c_str());
596   c_credential_reload_arg.context = nullptr;
597   grpc_tls_server_authorization_check_config*
598       c_server_authorization_check_config =
599           c_options->server_authorization_check_config();
600   grpc_tls_server_authorization_check_arg c_server_authorization_check_arg;
601   c_server_authorization_check_arg.cb = tls_server_authorization_check_callback;
602   c_server_authorization_check_arg.cb_user_data = nullptr;
603   c_server_authorization_check_arg.success = 0;
604   c_server_authorization_check_arg.target_name = "target_name";
605   c_server_authorization_check_arg.peer_cert = "peer_cert";
606   c_server_authorization_check_arg.status = GRPC_STATUS_UNAUTHENTICATED;
607   c_server_authorization_check_arg.error_details = new grpc_tls_error_details();
608   c_server_authorization_check_arg.error_details->set_error_details(
609       "error_details");
610   c_server_authorization_check_arg.context = nullptr;
611   EXPECT_STREQ(c_key_materials_config->pem_root_certs(), "pem_root_certs");
612   EXPECT_EQ(
613       static_cast<int>(c_key_materials_config->pem_key_cert_pair_list().size()),
614       1);
615   EXPECT_STREQ(
616       c_key_materials_config->pem_key_cert_pair_list()[0].private_key(),
617       "private_key");
618   EXPECT_STREQ(c_key_materials_config->pem_key_cert_pair_list()[0].cert_chain(),
619                "cert_chain");
620 
621   GPR_ASSERT(c_credential_reload_config != nullptr);
622   int c_credential_reload_schedule_output =
623       c_credential_reload_config->Schedule(&c_credential_reload_arg);
624   EXPECT_EQ(c_credential_reload_schedule_output, 0);
625   EXPECT_EQ(c_credential_reload_arg.cb_user_data, nullptr);
626   EXPECT_STREQ(c_credential_reload_arg.key_materials_config->pem_root_certs(),
627                "new_pem_root_certs");
628   ::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1> c_pair_list =
629       c_credential_reload_arg.key_materials_config->pem_key_cert_pair_list();
630   EXPECT_EQ(static_cast<int>(c_pair_list.size()), 2);
631   EXPECT_STREQ(c_pair_list[0].private_key(), "private_key");
632   EXPECT_STREQ(c_pair_list[0].cert_chain(), "cert_chain");
633   EXPECT_STREQ(c_pair_list[1].private_key(), "private_key3");
634   EXPECT_STREQ(c_pair_list[1].cert_chain(), "cert_chain3");
635   EXPECT_EQ(c_credential_reload_arg.status,
636             GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW);
637   EXPECT_STREQ(c_credential_reload_arg.error_details->error_details().c_str(),
638                test_error_details.c_str());
639 
640   int c_server_authorization_check_schedule_output =
641       c_server_authorization_check_config->Schedule(
642           &c_server_authorization_check_arg);
643   EXPECT_EQ(c_server_authorization_check_schedule_output, 1);
644   EXPECT_STREQ(
645       static_cast<char*>(c_server_authorization_check_arg.cb_user_data),
646       "cb_user_data");
647   EXPECT_EQ(c_server_authorization_check_arg.success, 1);
648   EXPECT_STREQ(c_server_authorization_check_arg.target_name,
649                "sync_target_name");
650   EXPECT_STREQ(c_server_authorization_check_arg.peer_cert, "sync_peer_cert");
651   EXPECT_EQ(c_server_authorization_check_arg.status, GRPC_STATUS_OK);
652   EXPECT_STREQ(
653       c_server_authorization_check_arg.error_details->error_details().c_str(),
654       "sync_error_details");
655 
656   // Cleanup.
657   c_credential_reload_arg.destroy_context(c_credential_reload_arg.context);
658   delete c_credential_reload_arg.error_details;
659   c_server_authorization_check_arg.destroy_context(
660       c_server_authorization_check_arg.context);
661   gpr_free(c_server_authorization_check_arg.cb_user_data);
662   gpr_free(const_cast<char*>(c_server_authorization_check_arg.target_name));
663   gpr_free(const_cast<char*>(c_server_authorization_check_arg.peer_cert));
664   delete c_server_authorization_check_arg.error_details;
665   delete c_options;
666 }
667 
668 // This test demonstrates how the TLS credentials will be used.
TEST_F(CredentialsTest,LoadTlsChannelCredentials)669 TEST_F(CredentialsTest, LoadTlsChannelCredentials) {
670   std::shared_ptr<TestTlsCredentialReload> test_credential_reload(
671       new TestTlsCredentialReload());
672   std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config(
673       new TlsCredentialReloadConfig(test_credential_reload));
674 
675   std::shared_ptr<TestTlsServerAuthorizationCheck>
676       test_server_authorization_check(new TestTlsServerAuthorizationCheck());
677   std::shared_ptr<TlsServerAuthorizationCheckConfig>
678       server_authorization_check_config(new TlsServerAuthorizationCheckConfig(
679           test_server_authorization_check));
680 
681   TlsCredentialsOptions options = TlsCredentialsOptions(
682       GRPC_TLS_SERVER_VERIFICATION, nullptr, credential_reload_config,
683       server_authorization_check_config);
684   std::shared_ptr<grpc_impl::ChannelCredentials> channel_credentials =
685       grpc::experimental::TlsCredentials(options);
686   GPR_ASSERT(channel_credentials.get() != nullptr);
687 }
688 
TEST_F(CredentialsTest,TlsCredentialReloadConfigErrorMessages)689 TEST_F(CredentialsTest, TlsCredentialReloadConfigErrorMessages) {
690   std::shared_ptr<TlsCredentialReloadConfig> config(
691       new TlsCredentialReloadConfig(nullptr));
692   grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg;
693   c_arg->error_details = new grpc_tls_error_details();
694   c_arg->context = nullptr;
695   TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg);
696   int schedule_output = config->Schedule(arg);
697 
698   EXPECT_EQ(schedule_output, 1);
699   EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
700   EXPECT_STREQ(arg->error_details().c_str(),
701                "the interface of the credential reload config is nullptr");
702 
703   arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED);
704   config->Cancel(arg);
705   EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL);
706   EXPECT_STREQ(arg->error_details().c_str(),
707                "the interface of the credential reload config is nullptr");
708 
709   // Cleanup.
710   if (c_arg->destroy_context != nullptr) {
711     c_arg->destroy_context(c_arg->context);
712   }
713   delete c_arg->error_details;
714   delete c_arg;
715   delete config->c_config();
716 }
717 
TEST_F(CredentialsTest,TlsServerAuthorizationCheckConfigErrorMessages)718 TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) {
719   std::shared_ptr<TlsServerAuthorizationCheckConfig> config(
720       new TlsServerAuthorizationCheckConfig(nullptr));
721   grpc_tls_server_authorization_check_arg* c_arg =
722       new grpc_tls_server_authorization_check_arg;
723   c_arg->error_details = new grpc_tls_error_details();
724   c_arg->context = nullptr;
725   TlsServerAuthorizationCheckArg* arg =
726       new TlsServerAuthorizationCheckArg(c_arg);
727   int schedule_output = config->Schedule(arg);
728 
729   EXPECT_EQ(schedule_output, 1);
730   EXPECT_EQ(arg->status(), GRPC_STATUS_NOT_FOUND);
731   EXPECT_STREQ(
732       arg->error_details().c_str(),
733       "the interface of the server authorization check config is nullptr");
734 
735   arg->set_status(GRPC_STATUS_OK);
736   config->Cancel(arg);
737   EXPECT_EQ(arg->status(), GRPC_STATUS_NOT_FOUND);
738   EXPECT_STREQ(
739       arg->error_details().c_str(),
740       "the interface of the server authorization check config is nullptr");
741 
742   // Cleanup.
743   delete c_arg->error_details;
744   if (c_arg->destroy_context != nullptr) {
745     c_arg->destroy_context(c_arg->context);
746   }
747   delete c_arg;
748   delete config->c_config();
749 }
750 
751 }  // namespace testing
752 }  // namespace grpc
753 
main(int argc,char ** argv)754 int main(int argc, char** argv) {
755   ::testing::InitGoogleTest(&argc, argv);
756   int ret = RUN_ALL_TESTS();
757   return ret;
758 }
759