• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #ifndef GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H
18 #define GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H
19 
20 #include <grpc/credentials.h>
21 #include <grpc/grpc_security.h>
22 #include <grpc/status.h>
23 #include <grpc/support/port_platform.h>
24 
25 #include <functional>
26 #include <map>
27 
28 #include "absl/base/thread_annotations.h"
29 #include "absl/log/check.h"
30 #include "absl/status/status.h"
31 #include "src/core/util/ref_counted.h"
32 #include "src/core/util/sync.h"
33 #include "src/core/util/unique_type_name.h"
34 #include "src/core/util/useful.h"
35 
36 // An abstraction of the verifier that all verifier subclasses should extend.
37 struct grpc_tls_certificate_verifier
38     : public grpc_core::RefCounted<grpc_tls_certificate_verifier> {
39  public:
40   ~grpc_tls_certificate_verifier() override = default;
41   // Verifies the specific request. It can be processed in sync or async mode.
42   // If the caller want it to be processed asynchronously, return false
43   // immediately, and at the end of the async operation, invoke the callback
44   // with the verification results stored in absl::Status. Otherwise, populate
45   // the verification results in |sync_status| and return true. The caller is
46   // expected to populate verification results by setting request.
47   virtual bool Verify(grpc_tls_custom_verification_check_request* request,
48                       std::function<void(absl::Status)> callback,
49                       absl::Status* sync_status) = 0;
50   // Operations that will be performed when a request is cancelled.
51   // This is only needed when in async mode.
52   // TODO(roth): This needs to take an absl::Status argument so that we
53   // can pass the cancellation status through to the check_peer callback.
54   virtual void Cancel(grpc_tls_custom_verification_check_request* request) = 0;
55 
56   // Compares this grpc_tls_certificate_verifier object with \a other.
57   // If this method returns 0, it means that gRPC can treat the two certificate
58   // verifiers as effectively the same.
Comparegrpc_tls_certificate_verifier59   int Compare(const grpc_tls_certificate_verifier* other) const {
60     CHECK_NE(other, nullptr);
61     int r = type().Compare(other->type());
62     if (r != 0) return r;
63     return CompareImpl(other);
64   }
65 
66   // The pointer value \a type is used to uniquely identify a verifier
67   // implementation for down-casting purposes. Every verifier implementation
68   // should use a unique string instance, which should be returned by all
69   // instances of that verifier implementation.
70   virtual grpc_core::UniqueTypeName type() const = 0;
71 
72  private:
73   // Implementation for `Compare` method intended to be overridden by
74   // subclasses. Only invoked if `type()` and `other->type()` point to the same
75   // string.
76   virtual int CompareImpl(const grpc_tls_certificate_verifier* other) const = 0;
77 };
78 
79 namespace grpc_core {
80 
81 // A verifier that will transform grpc_tls_certificate_verifier_external to a
82 // verifier that extends grpc_tls_certificate_verifier.
83 class ExternalCertificateVerifier : public grpc_tls_certificate_verifier {
84  public:
ExternalCertificateVerifier(grpc_tls_certificate_verifier_external * external_verifier)85   explicit ExternalCertificateVerifier(
86       grpc_tls_certificate_verifier_external* external_verifier)
87       : external_verifier_(external_verifier) {}
88 
~ExternalCertificateVerifier()89   ~ExternalCertificateVerifier() override {
90     if (external_verifier_->destruct != nullptr) {
91       external_verifier_->destruct(external_verifier_->user_data);
92     }
93   }
94 
95   bool Verify(grpc_tls_custom_verification_check_request* request,
96               std::function<void(absl::Status)> callback,
97               absl::Status* sync_status) override;
98 
Cancel(grpc_tls_custom_verification_check_request * request)99   void Cancel(grpc_tls_custom_verification_check_request* request) override {
100     external_verifier_->cancel(external_verifier_->user_data, request);
101   }
102 
103   UniqueTypeName type() const override;
104 
105  private:
CompareImpl(const grpc_tls_certificate_verifier * other)106   int CompareImpl(const grpc_tls_certificate_verifier* other) const override {
107     const auto* o = static_cast<const ExternalCertificateVerifier*>(other);
108     return QsortCompare(external_verifier_, o->external_verifier_);
109   }
110 
111   static void OnVerifyDone(grpc_tls_custom_verification_check_request* request,
112                            void* callback_arg, grpc_status_code status,
113                            const char* error_details);
114 
115   grpc_tls_certificate_verifier_external* external_verifier_;
116 
117   // Guards members below.
118   Mutex mu_;
119   // stores each check request and its corresponding callback function.
120   std::map<grpc_tls_custom_verification_check_request*,
121            std::function<void(absl::Status)>>
122       request_map_ ABSL_GUARDED_BY(mu_);
123 };
124 
125 // An internal verifier that won't perform any post-handshake checks.
126 // Note: using this solely without any other authentication mechanisms on the
127 // peer identity will leave your applications to the MITM(Man-In-The-Middle)
128 // attacks. Users should avoid doing so in production environments.
129 class NoOpCertificateVerifier : public grpc_tls_certificate_verifier {
130  public:
Verify(grpc_tls_custom_verification_check_request *,std::function<void (absl::Status)>,absl::Status *)131   bool Verify(grpc_tls_custom_verification_check_request*,
132               std::function<void(absl::Status)>, absl::Status*) override {
133     return true;  // synchronous check
134   };
Cancel(grpc_tls_custom_verification_check_request *)135   void Cancel(grpc_tls_custom_verification_check_request*) override {}
136 
137   UniqueTypeName type() const override;
138 
139  private:
CompareImpl(const grpc_tls_certificate_verifier *)140   int CompareImpl(
141       const grpc_tls_certificate_verifier* /* other */) const override {
142     // No differentiating factor between different NoOpCertificateVerifier
143     // objects.
144     return 0;
145   }
146 };
147 
148 // An internal verifier that will perform hostname verification check.
149 class HostNameCertificateVerifier : public grpc_tls_certificate_verifier {
150  public:
151   bool Verify(grpc_tls_custom_verification_check_request* request,
152               std::function<void(absl::Status)> callback,
153               absl::Status* sync_status) override;
Cancel(grpc_tls_custom_verification_check_request *)154   void Cancel(grpc_tls_custom_verification_check_request*) override {}
155 
156   UniqueTypeName type() const override;
157 
158  private:
CompareImpl(const grpc_tls_certificate_verifier *)159   int CompareImpl(
160       const grpc_tls_certificate_verifier* /* other */) const override {
161     // No differentiating factor between different HostNameCertificateVerifier
162     // objects.
163     return 0;
164   }
165 };
166 
167 }  // namespace grpc_core
168 
169 #endif  // GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H
170