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