1 /*
2  *
3  * Copyright 2019 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 "absl/container/inlined_vector.h"
20 
21 #include <grpcpp/security/tls_credentials_options.h>
22 #include "src/cpp/common/tls_credentials_options_util.h"
23 
24 namespace grpc_impl {
25 namespace experimental {
26 
27 /** Converts the Cpp key materials to C key materials; this allocates memory for
28  * the C key materials. Note that the user must free
29  * the underlying pointer to private key and cert chain duplicates; they are not
30  * freed when the grpc_core::UniquePtr<char> member variables of PemKeyCertPair
31  * are unused. Similarly, the user must free the underlying pointer to
32  * c_pem_root_certs. **/
ConvertToCKeyMaterialsConfig(const std::shared_ptr<TlsKeyMaterialsConfig> & config)33 grpc_tls_key_materials_config* ConvertToCKeyMaterialsConfig(
34     const std::shared_ptr<TlsKeyMaterialsConfig>& config) {
35   if (config == nullptr) {
36     return nullptr;
37   }
38   grpc_tls_key_materials_config* c_config =
39       grpc_tls_key_materials_config_create();
40   ::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1>
41       c_pem_key_cert_pair_list;
42   for (const auto& key_cert_pair : config->pem_key_cert_pair_list()) {
43     grpc_ssl_pem_key_cert_pair* ssl_pair =
44         (grpc_ssl_pem_key_cert_pair*)gpr_malloc(
45             sizeof(grpc_ssl_pem_key_cert_pair));
46     ssl_pair->private_key = gpr_strdup(key_cert_pair.private_key.c_str());
47     ssl_pair->cert_chain = gpr_strdup(key_cert_pair.cert_chain.c_str());
48     ::grpc_core::PemKeyCertPair c_pem_key_cert_pair =
49         ::grpc_core::PemKeyCertPair(ssl_pair);
50     c_pem_key_cert_pair_list.push_back(::std::move(c_pem_key_cert_pair));
51   }
52   c_config->set_key_materials(config->pem_root_certs().c_str(),
53                               c_pem_key_cert_pair_list);
54   c_config->set_version(config->version());
55   return c_config;
56 }
57 
58 /** The C schedule and cancel functions for the credential reload config.
59  * They populate a C credential reload arg with the result of a C++ credential
60  * reload schedule/cancel API. **/
TlsCredentialReloadConfigCSchedule(void *,grpc_tls_credential_reload_arg * arg)61 int TlsCredentialReloadConfigCSchedule(void* /*config_user_data*/,
62                                        grpc_tls_credential_reload_arg* arg) {
63   if (arg == nullptr || arg->config == nullptr ||
64       arg->config->context() == nullptr) {
65     gpr_log(GPR_ERROR, "credential reload arg was not properly initialized");
66     return 1;
67   }
68   TlsCredentialReloadConfig* cpp_config =
69       static_cast<TlsCredentialReloadConfig*>(arg->config->context());
70   TlsCredentialReloadArg* cpp_arg = new TlsCredentialReloadArg(arg);
71   int schedule_result = cpp_config->Schedule(cpp_arg);
72   return schedule_result;
73 }
74 
TlsCredentialReloadConfigCCancel(void *,grpc_tls_credential_reload_arg * arg)75 void TlsCredentialReloadConfigCCancel(void* /*config_user_data*/,
76                                       grpc_tls_credential_reload_arg* arg) {
77   if (arg == nullptr || arg->config == nullptr ||
78       arg->config->context() == nullptr) {
79     gpr_log(GPR_ERROR, "credential reload arg was not properly initialized");
80     return;
81   }
82   if (arg->context == nullptr) {
83     gpr_log(GPR_ERROR, "credential reload arg schedule has already completed");
84     return;
85   }
86   TlsCredentialReloadConfig* cpp_config =
87       static_cast<TlsCredentialReloadConfig*>(arg->config->context());
88   TlsCredentialReloadArg* cpp_arg =
89       static_cast<TlsCredentialReloadArg*>(arg->context);
90   cpp_config->Cancel(cpp_arg);
91 }
92 
TlsCredentialReloadArgDestroyContext(void * context)93 void TlsCredentialReloadArgDestroyContext(void* context) {
94   if (context != nullptr) {
95     TlsCredentialReloadArg* cpp_arg =
96         static_cast<TlsCredentialReloadArg*>(context);
97     delete cpp_arg;
98   }
99 }
100 
101 /** The C schedule and cancel functions for the server authorization check
102  * config. They populate a C server authorization check arg with the result
103  * of a C++ server authorization check schedule/cancel API. **/
TlsServerAuthorizationCheckConfigCSchedule(void *,grpc_tls_server_authorization_check_arg * arg)104 int TlsServerAuthorizationCheckConfigCSchedule(
105     void* /*config_user_data*/, grpc_tls_server_authorization_check_arg* arg) {
106   if (arg == nullptr || arg->config == nullptr ||
107       arg->config->context() == nullptr) {
108     gpr_log(GPR_ERROR,
109             "server authorization check arg was not properly initialized");
110     return 1;
111   }
112   TlsServerAuthorizationCheckConfig* cpp_config =
113       static_cast<TlsServerAuthorizationCheckConfig*>(arg->config->context());
114   TlsServerAuthorizationCheckArg* cpp_arg =
115       new TlsServerAuthorizationCheckArg(arg);
116   int schedule_result = cpp_config->Schedule(cpp_arg);
117   return schedule_result;
118 }
119 
TlsServerAuthorizationCheckConfigCCancel(void *,grpc_tls_server_authorization_check_arg * arg)120 void TlsServerAuthorizationCheckConfigCCancel(
121     void* /*config_user_data*/, grpc_tls_server_authorization_check_arg* arg) {
122   if (arg == nullptr || arg->config == nullptr ||
123       arg->config->context() == nullptr) {
124     gpr_log(GPR_ERROR,
125             "server authorization check arg was not properly initialized");
126     return;
127   }
128   if (arg->context == nullptr) {
129     gpr_log(GPR_ERROR,
130             "server authorization check arg schedule has already completed");
131     return;
132   }
133   TlsServerAuthorizationCheckConfig* cpp_config =
134       static_cast<TlsServerAuthorizationCheckConfig*>(arg->config->context());
135   TlsServerAuthorizationCheckArg* cpp_arg =
136       static_cast<TlsServerAuthorizationCheckArg*>(arg->context);
137   cpp_config->Cancel(cpp_arg);
138 }
139 
TlsServerAuthorizationCheckArgDestroyContext(void * context)140 void TlsServerAuthorizationCheckArgDestroyContext(void* context) {
141   if (context != nullptr) {
142     TlsServerAuthorizationCheckArg* cpp_arg =
143         static_cast<TlsServerAuthorizationCheckArg*>(context);
144     delete cpp_arg;
145   }
146 }
147 
148 }  // namespace experimental
149 }  // namespace grpc_impl
150