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 <grpc/support/alloc.h>
20 #include <grpcpp/security/tls_credentials_options.h>
21
22 #include "absl/container/inlined_vector.h"
23 #include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
24 #include "src/cpp/common/tls_credentials_options_util.h"
25
26 namespace grpc_impl {
27 namespace experimental {
28
29 /** TLS key materials config API implementation **/
set_pem_root_certs(const std::string & pem_root_certs)30 void TlsKeyMaterialsConfig::set_pem_root_certs(
31 const std::string& pem_root_certs) {
32 pem_root_certs_ = pem_root_certs;
33 }
34
add_pem_key_cert_pair(const PemKeyCertPair & pem_key_cert_pair)35 void TlsKeyMaterialsConfig::add_pem_key_cert_pair(
36 const PemKeyCertPair& pem_key_cert_pair) {
37 pem_key_cert_pair_list_.push_back(pem_key_cert_pair);
38 }
39
set_key_materials(const std::string & pem_root_certs,const std::vector<PemKeyCertPair> & pem_key_cert_pair_list)40 void TlsKeyMaterialsConfig::set_key_materials(
41 const std::string& pem_root_certs,
42 const std::vector<PemKeyCertPair>& pem_key_cert_pair_list) {
43 pem_key_cert_pair_list_ = pem_key_cert_pair_list;
44 pem_root_certs_ = pem_root_certs;
45 }
46
47 /** TLS credential reload arg API implementation **/
TlsCredentialReloadArg(grpc_tls_credential_reload_arg * arg)48 TlsCredentialReloadArg::TlsCredentialReloadArg(
49 grpc_tls_credential_reload_arg* arg)
50 : c_arg_(arg) {
51 if (c_arg_ != nullptr && c_arg_->context != nullptr) {
52 gpr_log(GPR_ERROR, "c_arg context has already been set");
53 }
54 c_arg_->context = static_cast<void*>(this);
55 c_arg_->destroy_context = &TlsCredentialReloadArgDestroyContext;
56 }
57
~TlsCredentialReloadArg()58 TlsCredentialReloadArg::~TlsCredentialReloadArg() {}
59
cb_user_data() const60 void* TlsCredentialReloadArg::cb_user_data() const {
61 return c_arg_->cb_user_data;
62 }
is_pem_key_cert_pair_list_empty() const63 bool TlsCredentialReloadArg::is_pem_key_cert_pair_list_empty() const {
64 return c_arg_->key_materials_config->pem_key_cert_pair_list().empty();
65 }
66
status() const67 grpc_ssl_certificate_config_reload_status TlsCredentialReloadArg::status()
68 const {
69 return c_arg_->status;
70 }
71
error_details() const72 std::string TlsCredentialReloadArg::error_details() const {
73 return c_arg_->error_details->error_details();
74 }
75
set_cb_user_data(void * cb_user_data)76 void TlsCredentialReloadArg::set_cb_user_data(void* cb_user_data) {
77 c_arg_->cb_user_data = cb_user_data;
78 }
79
set_pem_root_certs(const std::string & pem_root_certs)80 void TlsCredentialReloadArg::set_pem_root_certs(
81 const std::string& pem_root_certs) {
82 ::grpc_core::UniquePtr<char> c_pem_root_certs(
83 gpr_strdup(pem_root_certs.c_str()));
84 c_arg_->key_materials_config->set_pem_root_certs(std::move(c_pem_root_certs));
85 }
86
87 namespace {
88
ConvertToCorePemKeyCertPair(const TlsKeyMaterialsConfig::PemKeyCertPair & pem_key_cert_pair)89 ::grpc_core::PemKeyCertPair ConvertToCorePemKeyCertPair(
90 const TlsKeyMaterialsConfig::PemKeyCertPair& pem_key_cert_pair) {
91 grpc_ssl_pem_key_cert_pair* ssl_pair =
92 (grpc_ssl_pem_key_cert_pair*)gpr_malloc(
93 sizeof(grpc_ssl_pem_key_cert_pair));
94 ssl_pair->private_key = gpr_strdup(pem_key_cert_pair.private_key.c_str());
95 ssl_pair->cert_chain = gpr_strdup(pem_key_cert_pair.cert_chain.c_str());
96 return ::grpc_core::PemKeyCertPair(ssl_pair);
97 }
98
99 } // namespace
100
add_pem_key_cert_pair(const TlsKeyMaterialsConfig::PemKeyCertPair & pem_key_cert_pair)101 void TlsCredentialReloadArg::add_pem_key_cert_pair(
102 const TlsKeyMaterialsConfig::PemKeyCertPair& pem_key_cert_pair) {
103 c_arg_->key_materials_config->add_pem_key_cert_pair(
104 ConvertToCorePemKeyCertPair(pem_key_cert_pair));
105 }
106
set_key_materials(const std::string & pem_root_certs,std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pem_key_cert_pair_list)107 void TlsCredentialReloadArg::set_key_materials(
108 const std::string& pem_root_certs,
109 std::vector<TlsKeyMaterialsConfig::PemKeyCertPair> pem_key_cert_pair_list) {
110 /** Initialize the |key_materials_config| field of |c_arg_|, if it has not
111 * already been done. **/
112 if (c_arg_->key_materials_config == nullptr) {
113 c_arg_->key_materials_config = grpc_tls_key_materials_config_create();
114 }
115 /** Convert |pem_key_cert_pair_list| to an inlined vector of ssl pairs. **/
116 ::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1>
117 c_pem_key_cert_pair_list;
118 for (const auto& key_cert_pair : pem_key_cert_pair_list) {
119 c_pem_key_cert_pair_list.emplace_back(
120 ConvertToCorePemKeyCertPair(key_cert_pair));
121 }
122 /** Populate the key materials config field of |c_arg_|. **/
123 c_arg_->key_materials_config->set_key_materials(pem_root_certs.c_str(),
124 c_pem_key_cert_pair_list);
125 }
126
set_key_materials_config(const std::shared_ptr<TlsKeyMaterialsConfig> & key_materials_config)127 void TlsCredentialReloadArg::set_key_materials_config(
128 const std::shared_ptr<TlsKeyMaterialsConfig>& key_materials_config) {
129 if (key_materials_config == nullptr) {
130 c_arg_->key_materials_config = nullptr;
131 return;
132 }
133 ::absl::InlinedVector<::grpc_core::PemKeyCertPair, 1>
134 c_pem_key_cert_pair_list;
135 for (const auto& key_cert_pair :
136 key_materials_config->pem_key_cert_pair_list()) {
137 grpc_ssl_pem_key_cert_pair* ssl_pair =
138 (grpc_ssl_pem_key_cert_pair*)gpr_malloc(
139 sizeof(grpc_ssl_pem_key_cert_pair));
140 ssl_pair->private_key = gpr_strdup(key_cert_pair.private_key.c_str());
141 ssl_pair->cert_chain = gpr_strdup(key_cert_pair.cert_chain.c_str());
142 ::grpc_core::PemKeyCertPair c_pem_key_cert_pair =
143 ::grpc_core::PemKeyCertPair(ssl_pair);
144 c_pem_key_cert_pair_list.emplace_back(std::move(c_pem_key_cert_pair));
145 }
146 ::grpc_core::UniquePtr<char> c_pem_root_certs(
147 gpr_strdup(key_materials_config->pem_root_certs().c_str()));
148 if (c_arg_->key_materials_config == nullptr) {
149 c_arg_->key_materials_config = grpc_tls_key_materials_config_create();
150 }
151 c_arg_->key_materials_config->set_key_materials(
152 key_materials_config->pem_root_certs().c_str(), c_pem_key_cert_pair_list);
153 c_arg_->key_materials_config->set_version(key_materials_config->version());
154 }
155
set_status(grpc_ssl_certificate_config_reload_status status)156 void TlsCredentialReloadArg::set_status(
157 grpc_ssl_certificate_config_reload_status status) {
158 c_arg_->status = status;
159 }
160
set_error_details(const std::string & error_details)161 void TlsCredentialReloadArg::set_error_details(
162 const std::string& error_details) {
163 c_arg_->error_details->set_error_details(error_details.c_str());
164 }
165
OnCredentialReloadDoneCallback()166 void TlsCredentialReloadArg::OnCredentialReloadDoneCallback() {
167 if (c_arg_->cb == nullptr) {
168 gpr_log(GPR_ERROR, "credential reload arg callback API is nullptr");
169 return;
170 }
171 c_arg_->cb(c_arg_);
172 }
173
174 /** gRPC TLS credential reload config API implementation **/
TlsCredentialReloadConfig(std::shared_ptr<TlsCredentialReloadInterface> credential_reload_interface)175 TlsCredentialReloadConfig::TlsCredentialReloadConfig(
176 std::shared_ptr<TlsCredentialReloadInterface> credential_reload_interface)
177 : credential_reload_interface_(std::move(credential_reload_interface)) {
178 c_config_ = grpc_tls_credential_reload_config_create(
179 nullptr, &TlsCredentialReloadConfigCSchedule,
180 &TlsCredentialReloadConfigCCancel, nullptr);
181 c_config_->set_context(static_cast<void*>(this));
182 }
183
~TlsCredentialReloadConfig()184 TlsCredentialReloadConfig::~TlsCredentialReloadConfig() {}
185
186 /** gRPC TLS server authorization check arg API implementation **/
TlsServerAuthorizationCheckArg(grpc_tls_server_authorization_check_arg * arg)187 TlsServerAuthorizationCheckArg::TlsServerAuthorizationCheckArg(
188 grpc_tls_server_authorization_check_arg* arg)
189 : c_arg_(arg) {
190 if (c_arg_ != nullptr && c_arg_->context != nullptr) {
191 gpr_log(GPR_ERROR, "c_arg context has already been set");
192 }
193 c_arg_->context = static_cast<void*>(this);
194 c_arg_->destroy_context = &TlsServerAuthorizationCheckArgDestroyContext;
195 }
196
~TlsServerAuthorizationCheckArg()197 TlsServerAuthorizationCheckArg::~TlsServerAuthorizationCheckArg() {}
198
cb_user_data() const199 void* TlsServerAuthorizationCheckArg::cb_user_data() const {
200 return c_arg_->cb_user_data;
201 }
202
success() const203 int TlsServerAuthorizationCheckArg::success() const { return c_arg_->success; }
204
target_name() const205 std::string TlsServerAuthorizationCheckArg::target_name() const {
206 std::string cpp_target_name(c_arg_->target_name);
207 return cpp_target_name;
208 }
209
peer_cert() const210 std::string TlsServerAuthorizationCheckArg::peer_cert() const {
211 std::string cpp_peer_cert(c_arg_->peer_cert);
212 return cpp_peer_cert;
213 }
214
peer_cert_full_chain() const215 std::string TlsServerAuthorizationCheckArg::peer_cert_full_chain() const {
216 std::string cpp_peer_cert_full_chain(c_arg_->peer_cert_full_chain);
217 return cpp_peer_cert_full_chain;
218 }
219
status() const220 grpc_status_code TlsServerAuthorizationCheckArg::status() const {
221 return c_arg_->status;
222 }
223
error_details() const224 std::string TlsServerAuthorizationCheckArg::error_details() const {
225 return c_arg_->error_details->error_details();
226 }
227
set_cb_user_data(void * cb_user_data)228 void TlsServerAuthorizationCheckArg::set_cb_user_data(void* cb_user_data) {
229 c_arg_->cb_user_data = cb_user_data;
230 }
231
set_success(int success)232 void TlsServerAuthorizationCheckArg::set_success(int success) {
233 c_arg_->success = success;
234 }
235
set_target_name(const std::string & target_name)236 void TlsServerAuthorizationCheckArg::set_target_name(
237 const std::string& target_name) {
238 c_arg_->target_name = gpr_strdup(target_name.c_str());
239 }
240
set_peer_cert(const std::string & peer_cert)241 void TlsServerAuthorizationCheckArg::set_peer_cert(
242 const std::string& peer_cert) {
243 c_arg_->peer_cert = gpr_strdup(peer_cert.c_str());
244 }
245
set_peer_cert_full_chain(const std::string & peer_cert_full_chain)246 void TlsServerAuthorizationCheckArg::set_peer_cert_full_chain(
247 const std::string& peer_cert_full_chain) {
248 c_arg_->peer_cert_full_chain = gpr_strdup(peer_cert_full_chain.c_str());
249 }
250
set_status(grpc_status_code status)251 void TlsServerAuthorizationCheckArg::set_status(grpc_status_code status) {
252 c_arg_->status = status;
253 }
254
set_error_details(const std::string & error_details)255 void TlsServerAuthorizationCheckArg::set_error_details(
256 const std::string& error_details) {
257 c_arg_->error_details->set_error_details(error_details.c_str());
258 }
259
OnServerAuthorizationCheckDoneCallback()260 void TlsServerAuthorizationCheckArg::OnServerAuthorizationCheckDoneCallback() {
261 if (c_arg_->cb == nullptr) {
262 gpr_log(GPR_ERROR, "server authorizaton check arg callback API is nullptr");
263 return;
264 }
265 c_arg_->cb(c_arg_);
266 }
267
268 /** gRPC TLS server authorization check config API implementation. **/
TlsServerAuthorizationCheckConfig(std::shared_ptr<TlsServerAuthorizationCheckInterface> server_authorization_check_interface)269 TlsServerAuthorizationCheckConfig::TlsServerAuthorizationCheckConfig(
270 std::shared_ptr<TlsServerAuthorizationCheckInterface>
271 server_authorization_check_interface)
272 : server_authorization_check_interface_(
273 std::move(server_authorization_check_interface)) {
274 c_config_ = grpc_tls_server_authorization_check_config_create(
275 nullptr, &TlsServerAuthorizationCheckConfigCSchedule,
276 &TlsServerAuthorizationCheckConfigCCancel, nullptr);
277 c_config_->set_context(static_cast<void*>(this));
278 }
279
~TlsServerAuthorizationCheckConfig()280 TlsServerAuthorizationCheckConfig::~TlsServerAuthorizationCheckConfig() {}
281
282 /** gRPC TLS credential options API implementation **/
TlsCredentialsOptions(grpc_tls_server_verification_option server_verification_option,std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,std::shared_ptr<TlsServerAuthorizationCheckConfig> server_authorization_check_config)283 TlsCredentialsOptions::TlsCredentialsOptions(
284 grpc_tls_server_verification_option server_verification_option,
285 std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
286 std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,
287 std::shared_ptr<TlsServerAuthorizationCheckConfig>
288 server_authorization_check_config)
289 : TlsCredentialsOptions(
290 GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, server_verification_option,
291 std::move(key_materials_config), std::move(credential_reload_config),
292 std::move(server_authorization_check_config)) {}
293
TlsCredentialsOptions(grpc_ssl_client_certificate_request_type cert_request_type,std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config)294 TlsCredentialsOptions::TlsCredentialsOptions(
295 grpc_ssl_client_certificate_request_type cert_request_type,
296 std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
297 std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config)
298 : TlsCredentialsOptions(cert_request_type, GRPC_TLS_SERVER_VERIFICATION,
299 std::move(key_materials_config),
300 std::move(credential_reload_config), nullptr) {}
301
TlsCredentialsOptions(grpc_ssl_client_certificate_request_type cert_request_type,grpc_tls_server_verification_option server_verification_option,std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,std::shared_ptr<TlsServerAuthorizationCheckConfig> server_authorization_check_config)302 TlsCredentialsOptions::TlsCredentialsOptions(
303 grpc_ssl_client_certificate_request_type cert_request_type,
304 grpc_tls_server_verification_option server_verification_option,
305 std::shared_ptr<TlsKeyMaterialsConfig> key_materials_config,
306 std::shared_ptr<TlsCredentialReloadConfig> credential_reload_config,
307 std::shared_ptr<TlsServerAuthorizationCheckConfig>
308 server_authorization_check_config)
309 : cert_request_type_(cert_request_type),
310 server_verification_option_(server_verification_option),
311 key_materials_config_(std::move(key_materials_config)),
312 credential_reload_config_(std::move(credential_reload_config)),
313 server_authorization_check_config_(
314 std::move(server_authorization_check_config)) {
315 c_credentials_options_ = grpc_tls_credentials_options_create();
316 grpc_tls_credentials_options_set_cert_request_type(c_credentials_options_,
317 cert_request_type_);
318 if (key_materials_config_ != nullptr) {
319 grpc_tls_credentials_options_set_key_materials_config(
320 c_credentials_options_,
321 ConvertToCKeyMaterialsConfig(key_materials_config_));
322 }
323 if (credential_reload_config_ != nullptr) {
324 grpc_tls_credentials_options_set_credential_reload_config(
325 c_credentials_options_, credential_reload_config_->c_config());
326 }
327 if (server_authorization_check_config_ != nullptr) {
328 grpc_tls_credentials_options_set_server_authorization_check_config(
329 c_credentials_options_, server_authorization_check_config_->c_config());
330 }
331 grpc_tls_credentials_options_set_server_verification_option(
332 c_credentials_options_, server_verification_option);
333 }
334
335 /** Whenever a TlsCredentialsOptions instance is created, the caller takes
336 * ownership of the c_credentials_options_ pointer (see e.g. the implementation
337 * of the TlsCredentials API in secure_credentials.cc). For this reason, the
338 * TlsCredentialsOptions destructor is not responsible for freeing
339 * c_credentials_options_. **/
~TlsCredentialsOptions()340 TlsCredentialsOptions::~TlsCredentialsOptions() {}
341
342 } // namespace experimental
343 } // namespace grpc_impl
344