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