grpc_tls_certificate_verifier.cc
Go to the documentation of this file.
1 //
2 // Copyright 2021 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
18 
20 
21 #include <string.h>
22 
23 #include <string>
24 #include <utility>
25 
26 #include "absl/strings/string_view.h"
27 
28 #include <grpc/support/alloc.h>
29 #include <grpc/support/log.h>
31 
37 
38 namespace grpc_core {
39 
40 //
41 // ExternalCertificateVerifier
42 //
43 
46  std::function<void(absl::Status)> callback, absl::Status* sync_status) {
47  {
48  MutexLock lock(&mu_);
49  request_map_.emplace(request, std::move(callback));
50  }
51  // Invoke the caller-specified verification logic embedded in
52  // external_verifier_.
53  grpc_status_code status_code = GRPC_STATUS_OK;
54  char* error_details = nullptr;
56  request, &OnVerifyDone, this,
57  &status_code, &error_details);
58  if (is_done) {
59  if (status_code != GRPC_STATUS_OK) {
60  *sync_status = absl::Status(static_cast<absl::StatusCode>(status_code),
61  error_details);
62  }
63  MutexLock lock(&mu_);
64  request_map_.erase(request);
65  }
66  gpr_free(error_details);
67  return is_done;
68 }
69 
71  static UniqueTypeName::Factory kFactory("External");
72  return kFactory.Create();
73 }
74 
77  grpc_status_code status, const char* error_details) {
79  auto* self = static_cast<ExternalCertificateVerifier*>(callback_arg);
81  {
82  MutexLock lock(&self->mu_);
83  auto it = self->request_map_.find(request);
84  if (it != self->request_map_.end()) {
85  callback = std::move(it->second);
86  self->request_map_.erase(it);
87  }
88  }
89  if (callback != nullptr) {
90  absl::Status return_status = absl::OkStatus();
91  if (status != GRPC_STATUS_OK) {
92  return_status =
93  absl::Status(static_cast<absl::StatusCode>(status), error_details);
94  }
95  callback(return_status);
96  }
97 }
98 
99 //
100 // NoOpCertificateVerifier
101 //
102 
104  static UniqueTypeName::Factory kFactory("NoOp");
105  return kFactory.Create();
106 }
107 
108 //
109 // HostNameCertificateVerifier
110 //
111 
114  std::function<void(absl::Status)>, absl::Status* sync_status) {
115  GPR_ASSERT(request != nullptr);
116  // Extract the target name, and remove its port.
117  const char* target_name = request->target_name;
118  if (target_name == nullptr) {
120  "Target name is not specified.");
121  return true; // synchronous check
122  }
123  absl::string_view target_host;
124  absl::string_view ignored_port;
125  SplitHostPort(target_name, &target_host, &ignored_port);
126  if (target_host.empty()) {
128  "Failed to split hostname and port.");
129  return true; // synchronous check
130  }
131  // IPv6 zone-id should not be included in comparisons.
132  const size_t zone_id = target_host.find('%');
133  if (zone_id != absl::string_view::npos) {
134  target_host.remove_suffix(target_host.size() - zone_id);
135  }
136  // Perform the hostname check.
137  // First check the DNS field. We allow prefix or suffix wildcard matching.
138  char** dns_names = request->peer_info.san_names.dns_names;
139  size_t dns_names_size = request->peer_info.san_names.dns_names_size;
140  if (dns_names != nullptr && dns_names_size > 0) {
141  for (size_t i = 0; i < dns_names_size; ++i) {
142  const char* dns_name = dns_names[i];
143  // We are using the target name sent from the client as a matcher to match
144  // against identity name on the peer cert.
145  if (VerifySubjectAlternativeName(dns_name, std::string(target_host))) {
146  return true; // synchronous check
147  }
148  }
149  }
150  // Then check the IP address. We only allow exact matching.
151  char** ip_names = request->peer_info.san_names.ip_names;
152  size_t ip_names_size = request->peer_info.san_names.ip_names_size;
153  if (ip_names != nullptr && ip_names_size > 0) {
154  for (size_t i = 0; i < ip_names_size; ++i) {
155  const char* ip_name = ip_names[i];
156  if (target_host == ip_name) {
157  return true; // synchronous check
158  }
159  }
160  }
161  // If there's no SAN, try the CN.
162  if (dns_names_size == 0) {
163  const char* common_name = request->peer_info.common_name;
164  // We are using the target name sent from the client as a matcher to match
165  // against identity name on the peer cert.
166  if (common_name != nullptr &&
167  VerifySubjectAlternativeName(common_name, std::string(target_host))) {
168  return true; // synchronous check
169  }
170  }
172  "Hostname Verification Check failed.");
173  return true; // synchronous check
174 }
175 
177  static UniqueTypeName::Factory kFactory("Hostname");
178  return kFactory.Create();
179 }
180 
181 } // namespace grpc_core
182 
183 //
184 // Wrapper APIs declared in grpc_security.h
185 //
186 
191  grpc_status_code* sync_status, char** sync_error_details) {
194  [callback, request, callback_arg](absl::Status async_status) {
195  callback(request, callback_arg,
196  static_cast<grpc_status_code>(async_status.code()),
197  std::string(async_status.message()).c_str());
198  };
199  absl::Status sync_status_cpp;
200  bool is_done = verifier->Verify(request, async_cb, &sync_status_cpp);
201  if (is_done) {
202  if (!sync_status_cpp.ok()) {
203  *sync_status = static_cast<grpc_status_code>(sync_status_cpp.code());
204  *sync_error_details =
205  gpr_strdup(std::string(sync_status_cpp.message()).c_str());
206  }
207  }
208  return is_done;
209 }
210 
215  verifier->Cancel(request);
216 }
217 
219  grpc_tls_certificate_verifier_external* external_verifier) {
221  return new grpc_core::ExternalCertificateVerifier(external_verifier);
222 }
223 
227 }
228 
233 }
234 
237  GRPC_API_TRACE("grpc_tls_certificate_verifier_release(verifier=%p)", 1,
238  (verifier));
240  if (verifier != nullptr) verifier->Unref();
241 }
trace.h
grpc_core::UniqueTypeName::Factory::Create
UniqueTypeName Create()
Definition: unique_type_name.h:67
grpc_tls_certificate_verifier_verify
int grpc_tls_certificate_verifier_verify(grpc_tls_certificate_verifier *verifier, grpc_tls_custom_verification_check_request *request, grpc_tls_on_custom_verification_check_done_cb callback, void *callback_arg, grpc_status_code *sync_status, char **sync_error_details)
Definition: grpc_tls_certificate_verifier.cc:187
regen-readme.it
it
Definition: regen-readme.py:15
log.h
absl::string_view::remove_suffix
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_suffix(size_type n)
Definition: abseil-cpp/absl/strings/string_view.h:354
grpc_core::NoOpCertificateVerifier
Definition: grpc_tls_certificate_verifier.h:128
absl::string_view::find
size_type find(string_view s, size_type pos=0) const noexcept
Definition: abseil-cpp/absl/strings/string_view.cc:81
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::MutexLock
Definition: src/core/lib/gprpp/sync.h:88
string.h
benchmark.request
request
Definition: benchmark.py:77
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
grpc_core::ExternalCertificateVerifier::mu_
Mutex mu_
Definition: grpc_tls_certificate_verifier.h:117
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc_status_code
grpc_status_code
Definition: include/grpc/impl/codegen/status.h:28
grpc_core::ExternalCertificateVerifier
Definition: grpc_tls_certificate_verifier.h:82
absl::OkStatus
Status OkStatus()
Definition: third_party/abseil-cpp/absl/status/status.h:882
grpc_core::SplitHostPort
bool SplitHostPort(absl::string_view name, absl::string_view *host, absl::string_view *port)
Definition: host_port.cc:88
status
absl::Status status
Definition: rls.cc:251
grpc_tls_on_custom_verification_check_done_cb
void(* grpc_tls_on_custom_verification_check_done_cb)(grpc_tls_custom_verification_check_request *request, void *callback_arg, grpc_status_code status, const char *error_details)
Definition: grpc_security.h:946
verifier
static void verifier(grpc_server *server, grpc_completion_queue *cq, void *)
Definition: badreq.cc:31
grpc_tls_certificate_verifier_no_op_create
grpc_tls_certificate_verifier * grpc_tls_certificate_verifier_no_op_create()
Definition: grpc_tls_certificate_verifier.cc:224
grpc_core::ExternalCertificateVerifier::type
UniqueTypeName type() const override
Definition: grpc_tls_certificate_verifier.cc:70
string_util.h
grpc_tls_certificate_verifier_external
Definition: grpc_security.h:963
GRPC_STATUS_OK
@ GRPC_STATUS_OK
Definition: include/grpc/impl/codegen/status.h:30
grpc_tls_certificate_verifier.h
grpc_tls_certificate_verifier_cancel
void grpc_tls_certificate_verifier_cancel(grpc_tls_certificate_verifier *verifier, grpc_tls_custom_verification_check_request *request)
Definition: grpc_tls_certificate_verifier.cc:211
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
grpc_core::HostNameCertificateVerifier
Definition: grpc_tls_certificate_verifier.h:148
absl::string_view::size
constexpr size_type size() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:277
grpc_core::ExternalCertificateVerifier::external_verifier_
grpc_tls_certificate_verifier_external * external_verifier_
Definition: grpc_tls_certificate_verifier.h:114
absl::Status::message
absl::string_view message() const
Definition: third_party/abseil-cpp/absl/status/status.h:806
grpc_tls_certificate_verifier_external::user_data
void * user_data
Definition: grpc_security.h:964
grpc_tls_certificate_verifier_external::verify
int(* verify)(void *user_data, grpc_tls_custom_verification_check_request *request, grpc_tls_on_custom_verification_check_done_cb callback, void *callback_arg, grpc_status_code *sync_status, char **sync_error_details)
Definition: grpc_security.h:998
grpc_core::NoOpCertificateVerifier::type
UniqueTypeName type() const override
Definition: grpc_tls_certificate_verifier.cc:103
grpc_core::HostNameCertificateVerifier::Verify
bool Verify(grpc_tls_custom_verification_check_request *request, std::function< void(absl::Status)> callback, absl::Status *sync_status) override
Definition: grpc_tls_certificate_verifier.cc:112
callback
static void callback(void *arg, int status, int timeouts, struct hostent *host)
Definition: acountry.c:224
host_port.h
absl::StatusCode::kUnauthenticated
@ kUnauthenticated
grpc_core::ExecCtx
Definition: exec_ctx.h:97
absl::Status
ABSL_NAMESPACE_BEGIN class ABSL_MUST_USE_RESULT Status
Definition: abseil-cpp/absl/status/internal/status_internal.h:36
async_cb
static void async_cb(uv_async_t *handle)
Definition: benchmark-async-pummel.c:39
grpc_core::UniqueTypeName
Definition: unique_type_name.h:56
absl::StatusCode
StatusCode
Definition: third_party/abseil-cpp/absl/status/status.h:92
grpc_core::ExternalCertificateVerifier::Verify
bool Verify(grpc_tls_custom_verification_check_request *request, std::function< void(absl::Status)> callback, absl::Status *sync_status) override
Definition: grpc_tls_certificate_verifier.cc:44
exec_ctx
grpc_core::ExecCtx exec_ctx
Definition: end2end_binder_transport_test.cc:75
absl::Status
Definition: third_party/abseil-cpp/absl/status/status.h:424
alloc.h
exec_ctx.h
absl::Status::ok
ABSL_MUST_USE_RESULT bool ok() const
Definition: third_party/abseil-cpp/absl/status/status.h:802
grpc_tls_certificate_verifier_external_create
grpc_tls_certificate_verifier * grpc_tls_certificate_verifier_external_create(grpc_tls_certificate_verifier_external *external_verifier)
Definition: grpc_tls_certificate_verifier.cc:218
grpc_tls_certificate_verifier
Definition: grpc_tls_certificate_verifier.h:38
grpc_core::ExternalCertificateVerifier::OnVerifyDone
static void OnVerifyDone(grpc_tls_custom_verification_check_request *request, void *callback_arg, grpc_status_code status, const char *error_details)
Definition: grpc_tls_certificate_verifier.cc:75
grpc_tls_custom_verification_check_request
Definition: grpc_security.h:907
api_trace.h
grpc_core::HostNameCertificateVerifier::type
UniqueTypeName type() const override
Definition: grpc_tls_certificate_verifier.cc:176
gpr_strdup
GPRAPI char * gpr_strdup(const char *src)
Definition: string.cc:39
absl::string_view::empty
constexpr bool empty() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:292
grpc_tls_certificate_verifier_release
void grpc_tls_certificate_verifier_release(grpc_tls_certificate_verifier *verifier)
Definition: grpc_tls_certificate_verifier.cc:235
absl::string_view::npos
static constexpr size_type npos
Definition: abseil-cpp/absl/strings/string_view.h:182
function
std::function< bool(GrpcTool *, int, const char **, const CliCredentials &, GrpcToolOutputCallback)> function
Definition: grpc_tool.cc:250
self
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern self
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/map.c:543
absl::Status::code
absl::StatusCode code() const
Definition: third_party/abseil-cpp/absl/status/status.cc:233
grpc_tls_certificate_verifier_host_name_create
grpc_tls_certificate_verifier * grpc_tls_certificate_verifier_host_name_create()
Definition: grpc_tls_certificate_verifier.cc:230
grpc_core::UniqueTypeName::Factory
Definition: unique_type_name.h:60
grpc_core::VerifySubjectAlternativeName
bool VerifySubjectAlternativeName(absl::string_view subject_alternative_name, const std::string &matcher)
Definition: src/core/lib/security/credentials/tls/tls_utils.cc:33
tls_utils.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
GRPC_API_TRACE
#define GRPC_API_TRACE(fmt, nargs, args)
Definition: api_trace.h:48
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:45