xref: /aosp_15_r20/external/grpc-grpc/include/grpcpp/security/tls_certificate_verifier.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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 GRPCPP_SECURITY_TLS_CERTIFICATE_VERIFIER_H
18 #define GRPCPP_SECURITY_TLS_CERTIFICATE_VERIFIER_H
19 
20 #include <functional>
21 #include <map>
22 #include <memory>
23 #include <utility>
24 #include <vector>
25 
26 #include <grpc/grpc_security_constants.h>
27 #include <grpc/status.h>
28 #include <grpc/support/log.h>
29 #include <grpcpp/impl/grpc_library.h>
30 #include <grpcpp/impl/sync.h>
31 #include <grpcpp/support/config.h>
32 #include <grpcpp/support/status.h>
33 #include <grpcpp/support/string_ref.h>
34 
35 // TODO(yihuazhang): remove the forward declaration here and include
36 // <grpc/grpc_security.h> directly once the insecure builds are cleaned up.
37 typedef struct grpc_tls_custom_verification_check_request
38     grpc_tls_custom_verification_check_request;
39 typedef struct grpc_tls_certificate_verifier grpc_tls_certificate_verifier;
40 typedef struct grpc_tls_certificate_verifier_external
41     grpc_tls_certificate_verifier_external;
42 typedef void (*grpc_tls_on_custom_verification_check_done_cb)(
43     grpc_tls_custom_verification_check_request* request, void* callback_arg,
44     grpc_status_code status, const char* error_details);
45 extern "C" grpc_tls_certificate_verifier*
46 grpc_tls_certificate_verifier_external_create(
47     grpc_tls_certificate_verifier_external* external_verifier);
48 
49 namespace grpc {
50 namespace experimental {
51 
52 // Contains the verification-related information associated with a connection
53 // request. Users should not directly create or destroy this request object, but
54 // shall interact with it through CertificateVerifier's Verify() and Cancel().
55 class TlsCustomVerificationCheckRequest {
56  public:
57   explicit TlsCustomVerificationCheckRequest(
58       grpc_tls_custom_verification_check_request* request);
~TlsCustomVerificationCheckRequest()59   ~TlsCustomVerificationCheckRequest() {}
60 
61   grpc::string_ref target_name() const;
62   grpc::string_ref peer_cert() const;
63   grpc::string_ref peer_cert_full_chain() const;
64   grpc::string_ref common_name() const;
65   // The subject name of the root certificate used to verify the peer chain
66   // If verification fails or the peer cert is self-signed, this will be an
67   // empty string. If verification is successful, it is a comma-separated list,
68   // where the entries are of the form "FIELD_ABBREVIATION=string"
69   // ex: "CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"
70   // ex: "CN=GTS Root R1,O=Google Trust Services LLC,C=US"
71   grpc::string_ref verified_root_cert_subject() const;
72   std::vector<grpc::string_ref> uri_names() const;
73   std::vector<grpc::string_ref> dns_names() const;
74   std::vector<grpc::string_ref> email_names() const;
75   std::vector<grpc::string_ref> ip_names() const;
76 
c_request()77   grpc_tls_custom_verification_check_request* c_request() { return c_request_; }
78 
79  private:
80   grpc_tls_custom_verification_check_request* c_request_ = nullptr;
81 };
82 
83 // The base class of all internal verifier implementations, and the ultimate
84 // class that all external verifiers will eventually be transformed into.
85 // To implement a custom verifier, do not extend this class; instead,
86 // implement a subclass of ExternalCertificateVerifier. Note that custom
87 // verifier implementations can compose their functionality with existing
88 // implementations of this interface, such as HostnameVerifier, by delegating
89 // to an instance of that class.
90 class CertificateVerifier {
91  public:
92   explicit CertificateVerifier(grpc_tls_certificate_verifier* v);
93 
94   ~CertificateVerifier();
95 
96   // Verifies a connection request, based on the logic specified in an internal
97   // verifier. The check on each internal verifier could be either synchronous
98   // or asynchronous, and we will need to use return value to know.
99   //
100   // request: the verification information associated with this request
101   // callback: This will only take effect if the verifier is asynchronous.
102   //           The function that gRPC will invoke when the verifier has already
103   //           completed its asynchronous check. Callers can use this function
104   //           to perform any additional checks. The input parameter of the
105   //           std::function indicates the status of the verifier check.
106   // sync_status: This will only be useful if the verifier is synchronous.
107   //              The status of the verifier as it has already done it's
108   //              synchronous check.
109   // return: return true if executed synchronously, otherwise return false
110   bool Verify(TlsCustomVerificationCheckRequest* request,
111               std::function<void(grpc::Status)> callback,
112               grpc::Status* sync_status);
113 
114   // Cancels a verification request previously started via Verify().
115   // Used when the connection attempt times out or is cancelled while an async
116   // verification request is pending.
117   //
118   // request: the verification information associated with this request
119   void Cancel(TlsCustomVerificationCheckRequest* request);
120 
121   // Gets the core verifier used internally.
c_verifier()122   grpc_tls_certificate_verifier* c_verifier() { return verifier_; }
123 
124  private:
125   static void AsyncCheckDone(
126       grpc_tls_custom_verification_check_request* request, void* callback_arg,
127       grpc_status_code status, const char* error_details);
128 
129   grpc_tls_certificate_verifier* verifier_ = nullptr;
130   grpc::internal::Mutex mu_;
131   std::map<grpc_tls_custom_verification_check_request*,
132            std::function<void(grpc::Status)>>
133       request_map_ ABSL_GUARDED_BY(mu_);
134 };
135 
136 // The base class of all external, user-specified verifiers. Users should
137 // inherit this class to implement a custom verifier.
138 // Note that while implementing the custom verifier that extends this class, it
139 // is possible to compose an existing ExternalCertificateVerifier or
140 // CertificateVerifier, inside the Verify() and Cancel() function of the new
141 // custom verifier.
142 class ExternalCertificateVerifier {
143  public:
144   // A factory method for creating a |CertificateVerifier| from this class. All
145   // the user-implemented verifiers should use this function to be converted to
146   // verifiers compatible with |TlsCredentialsOptions|.
147   // The resulting CertificateVerifier takes ownership of the newly instantiated
148   // Subclass.
149   template <typename Subclass, typename... Args>
Create(Args &&...args)150   static std::shared_ptr<CertificateVerifier> Create(Args&&... args) {
151     auto* external_verifier = new Subclass(std::forward<Args>(args)...);
152     return std::make_shared<CertificateVerifier>(
153         grpc_tls_certificate_verifier_external_create(
154             external_verifier->base_));
155   }
156 
157   // The verification logic that will be performed after the TLS handshake
158   // completes. Implementers can choose to do their checks synchronously or
159   // asynchronously.
160   //
161   // request: the verification information associated with this request
162   // callback: This should only be used if your check is done asynchronously.
163   //           When the asynchronous work is done, invoke this callback function
164   //           with the proper status, indicating the success or the failure of
165   //           the check. The implementer MUST NOT invoke this |callback| in the
166   //           same thread before Verify() returns, otherwise it can lead to
167   //           deadlocks.
168   // sync_status: This should only be used if your check is done synchronously.
169   //              Modifies this value to indicate the success or the failure of
170   //              the check.
171   // return: return true if your check is done synchronously, otherwise return
172   //         false
173   virtual bool Verify(TlsCustomVerificationCheckRequest* request,
174                       std::function<void(grpc::Status)> callback,
175                       grpc::Status* sync_status) = 0;
176 
177   // Cancels a verification request previously started via Verify().
178   // Used when the connection attempt times out or is cancelled while an async
179   // verification request is pending. The implementation should abort whatever
180   // async operation it is waiting for and quickly invoke the callback that was
181   // passed to Verify() with a status indicating the cancellation.
182   //
183   // request: the verification information associated with this request
184   virtual void Cancel(TlsCustomVerificationCheckRequest* request) = 0;
185 
186  protected:
187   ExternalCertificateVerifier();
188 
189   virtual ~ExternalCertificateVerifier();
190 
191  private:
192   struct AsyncRequestState {
AsyncRequestStateAsyncRequestState193     AsyncRequestState(grpc_tls_on_custom_verification_check_done_cb cb,
194                       void* arg,
195                       grpc_tls_custom_verification_check_request* request)
196         : callback(cb), callback_arg(arg), cpp_request(request) {}
197 
198     grpc_tls_on_custom_verification_check_done_cb callback;
199     void* callback_arg;
200     TlsCustomVerificationCheckRequest cpp_request;
201   };
202 
203   static int VerifyInCoreExternalVerifier(
204       void* user_data, grpc_tls_custom_verification_check_request* request,
205       grpc_tls_on_custom_verification_check_done_cb callback,
206       void* callback_arg, grpc_status_code* sync_status,
207       char** sync_error_details);
208 
209   static void CancelInCoreExternalVerifier(
210       void* user_data, grpc_tls_custom_verification_check_request* request);
211 
212   static void DestructInCoreExternalVerifier(void* user_data);
213 
214   // TODO(yihuazhang): after the insecure build is removed, make this an object
215   // member instead of a pointer.
216   grpc_tls_certificate_verifier_external* base_ = nullptr;
217   grpc::internal::Mutex mu_;
218   std::map<grpc_tls_custom_verification_check_request*, AsyncRequestState>
219       request_map_ ABSL_GUARDED_BY(mu_);
220 };
221 
222 // A CertificateVerifier that doesn't perform any additional checks other than
223 // certificate verification, if specified.
224 // Note: using this solely without any other authentication mechanisms on the
225 // peer identity will leave your applications to the MITM(Man-In-The-Middle)
226 // attacks. Users should avoid doing so in production environments.
227 class NoOpCertificateVerifier : public CertificateVerifier {
228  public:
229   NoOpCertificateVerifier();
230 };
231 
232 // A CertificateVerifier that will perform hostname verification, to see if the
233 // target name set from the client side matches the identity information
234 // specified on the server's certificate.
235 class HostNameCertificateVerifier : public CertificateVerifier {
236  public:
237   HostNameCertificateVerifier();
238 };
239 
240 }  // namespace experimental
241 }  // namespace grpc
242 
243 #endif  // GRPCPP_SECURITY_TLS_CERTIFICATE_VERIFIER_H
244