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