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 std::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 std::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 std::string test_private_key = "private_key";
394 std::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 std::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 std::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 std::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