• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 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_TEST_CORE_TEST_UTIL_TLS_UTILS_H
18 #define GRPC_TEST_CORE_TEST_UTIL_TLS_UTILS_H
19 
20 #include <grpc/grpc.h>
21 #include <grpc/grpc_security.h>
22 #include <grpc/status.h>
23 
24 #include <deque>
25 #include <string>
26 #include <utility>
27 
28 #include "absl/base/thread_annotations.h"
29 #include "absl/strings/string_view.h"
30 #include "src/core/lib/security/security_connector/ssl_utils.h"
31 #include "src/core/util/sync.h"
32 #include "src/core/util/thd.h"
33 
34 namespace grpc_core {
35 
36 namespace testing {
37 
38 class TmpFile {
39  public:
40   // Create a temporary file with |data| written in.
41   explicit TmpFile(absl::string_view data);
42 
43   ~TmpFile();
44 
name()45   const std::string& name() { return name_; }
46 
47   // Rewrite |data| to the temporary file, in an atomic way.
48   void RewriteFile(absl::string_view data);
49 
50  private:
51   std::string CreateTmpFileAndWriteData(absl::string_view data);
52 
53   std::string name_;
54 };
55 
56 PemKeyCertPairList MakeCertKeyPairs(absl::string_view private_key,
57                                     absl::string_view certs);
58 
59 std::string GetFileContents(const std::string& path);
60 
61 // A synchronous external verifier implementation that simply returns
62 // verification results based on users' inputs. Note that it will delete itself
63 // in Destruct(), so create it like
64 // ```
65 // auto* sync_verifier_ = new SyncExternalVerifier(false);
66 // ```
67 // and no need to delete it later. This is basically to keep consistent with the
68 // semantics in AsyncExternalVerifier.
69 class SyncExternalVerifier {
70  public:
SyncExternalVerifier(bool success)71   explicit SyncExternalVerifier(bool success)
72       : success_(success), base_{this, Verify, Cancel, Destruct} {}
73 
base()74   grpc_tls_certificate_verifier_external* base() { return &base_; }
75 
76  private:
77   static int Verify(void* user_data,
78                     grpc_tls_custom_verification_check_request* request,
79                     grpc_tls_on_custom_verification_check_done_cb callback,
80                     void* callback_arg, grpc_status_code* sync_status,
81                     char** sync_error_details);
82 
Cancel(void *,grpc_tls_custom_verification_check_request *)83   static void Cancel(void*, grpc_tls_custom_verification_check_request*) {}
84 
85   static void Destruct(void* user_data);
86 
87   bool success_ = false;
88   grpc_tls_certificate_verifier_external base_;
89 };
90 
91 // An asynchronous external verifier implementation that runs a thread and
92 // process each request received from the verifier sequentially. Note that it
93 // will delete itself in Destruct(), so create it like
94 // ```
95 // auto* async_verifier = new AsyncExternalVerifier(true, &event);
96 // auto* core_external_verifier =
97 //       new ExternalCertificateVerifier(async_verifier->base());
98 // ```
99 // and no need to delete it later.
100 // We delete AsyncExternalVerifier in Destruct() instead of its dtor because we
101 // wanted AsyncExternalVerifier to outlive the underlying core
102 // ExternalCertificateVerifier implementation.
103 class AsyncExternalVerifier {
104  public:
AsyncExternalVerifier(bool success)105   explicit AsyncExternalVerifier(bool success)
106       : success_(success),
107         thread_("AsyncExternalVerifierWorkerThread", WorkerThread, this),
108         base_{this, Verify, Cancel, Destruct} {
109     grpc_init();
110     thread_.Start();
111   }
112 
113   ~AsyncExternalVerifier();
114 
base()115   grpc_tls_certificate_verifier_external* base() { return &base_; }
116 
117  private:
118   // A request to pass to the worker thread.
119   struct Request {
120     grpc_tls_custom_verification_check_request* request;
121     grpc_tls_on_custom_verification_check_done_cb callback;
122     void* callback_arg;
123     bool shutdown;  // If true, thread will exit.
124   };
125 
126   static int Verify(void* user_data,
127                     grpc_tls_custom_verification_check_request* request,
128                     grpc_tls_on_custom_verification_check_done_cb callback,
129                     void* callback_arg, grpc_status_code* sync_status,
130                     char** sync_error_details);
131 
Cancel(void *,grpc_tls_custom_verification_check_request *)132   static void Cancel(void*, grpc_tls_custom_verification_check_request*) {}
133 
134   static void Destruct(void* user_data);
135 
136   static void WorkerThread(void* arg);
137 
138   bool success_ = false;
139   Thread thread_;
140   grpc_tls_certificate_verifier_external base_;
141   Mutex mu_;
142   std::deque<Request> queue_ ABSL_GUARDED_BY(mu_);
143 };
144 
145 // A synchronous external verifier implementation that verifies configured
146 // properties exist with the correct values. Note that it will delete itself in
147 // Destruct(), so create it like
148 // ```
149 // auto* verifier_ = new PeerPropertyExternalVerifier(...);
150 // ```
151 // and no need to delete it later. This is basically to keep consistent with the
152 // semantics in AsyncExternalVerifier.
153 class PeerPropertyExternalVerifier {
154  public:
PeerPropertyExternalVerifier(std::string expected_verified_root_cert_subject)155   explicit PeerPropertyExternalVerifier(
156       std::string expected_verified_root_cert_subject)
157       : expected_verified_root_cert_subject_(
158             std::move(expected_verified_root_cert_subject)),
159         base_{this, Verify, Cancel, Destruct} {}
160 
base()161   grpc_tls_certificate_verifier_external* base() { return &base_; }
162 
163  private:
164   static int Verify(void* user_data,
165                     grpc_tls_custom_verification_check_request* request,
166                     grpc_tls_on_custom_verification_check_done_cb callback,
167                     void* callback_arg, grpc_status_code* sync_status,
168                     char** sync_error_details);
169 
Cancel(void *,grpc_tls_custom_verification_check_request *)170   static void Cancel(void*, grpc_tls_custom_verification_check_request*) {}
171 
172   static void Destruct(void* user_data);
173 
174   std::string expected_verified_root_cert_subject_;
175   grpc_tls_certificate_verifier_external base_;
176 };
177 
178 }  // namespace testing
179 
180 }  // namespace grpc_core
181 
182 #endif  // GRPC_TEST_CORE_TEST_UTIL_TLS_UTILS_H
183