xref: /aosp_15_r20/external/grpc-grpc/test/cpp/util/tls_test_utils.cc (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 #include "test/cpp/util/tls_test_utils.h"
18 
19 #include <memory>
20 
21 #include "src/core/lib/gprpp/thd.h"
22 #include "test/core/util/port.h"
23 #include "test/core/util/test_config.h"
24 
25 using ::grpc::experimental::TlsCustomVerificationCheckRequest;
26 
27 namespace grpc {
28 namespace testing {
29 
Verify(TlsCustomVerificationCheckRequest *,std::function<void (grpc::Status)>,grpc::Status * sync_status)30 bool SyncCertificateVerifier::Verify(TlsCustomVerificationCheckRequest*,
31                                      std::function<void(grpc::Status)>,
32                                      grpc::Status* sync_status) {
33   if (!success_) {
34     *sync_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED,
35                                 "SyncCertificateVerifier failed");
36   } else {
37     *sync_status = grpc::Status(grpc::StatusCode::OK, "");
38   }
39   return true;
40 }
41 
AsyncCertificateVerifier(bool success)42 AsyncCertificateVerifier::AsyncCertificateVerifier(bool success)
43     : success_(success),
44       thread_("AsyncCertificateVerifierWorkerThread", WorkerThread, this) {
45   thread_.Start();
46 }
47 
~AsyncCertificateVerifier()48 AsyncCertificateVerifier::~AsyncCertificateVerifier() {
49   // Tell the thread to shut down.
50   {
51     internal::MutexLock lock(&mu_);
52     queue_.push_back(Request{nullptr, nullptr, true});
53   }
54   // Wait for thread to exit.
55   thread_.Join();
56 }
57 
Verify(TlsCustomVerificationCheckRequest * request,std::function<void (grpc::Status)> callback,grpc::Status *)58 bool AsyncCertificateVerifier::Verify(
59     TlsCustomVerificationCheckRequest* request,
60     std::function<void(grpc::Status)> callback, grpc::Status*) {
61   internal::MutexLock lock(&mu_);
62   queue_.push_back(Request{request, std::move(callback), false});
63   return false;  // Asynchronous call
64 }
65 
WorkerThread(void * arg)66 void AsyncCertificateVerifier::WorkerThread(void* arg) {
67   auto* self = static_cast<AsyncCertificateVerifier*>(arg);
68   while (true) {
69     // Check queue for work.
70     bool got_request = false;
71     Request request;
72     {
73       internal::MutexLock lock(&self->mu_);
74       if (!self->queue_.empty()) {
75         got_request = true;
76         request = self->queue_.front();
77         self->queue_.pop_front();
78       }
79     }
80     // If nothing found in the queue, sleep for a bit and try again.
81     if (!got_request) {
82       gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100));
83       continue;
84     }
85     // If we're being told to shut down, return.
86     if (request.shutdown) return;
87     auto return_status = grpc::Status(grpc::StatusCode::OK, "");
88     // Process the request.
89     if (!self->success_) {
90       return_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED,
91                                    "AsyncCertificateVerifier failed");
92     }
93     request.callback(return_status);
94   }
95 }
96 
Verify(TlsCustomVerificationCheckRequest * request,std::function<void (grpc::Status)>,grpc::Status * sync_status)97 bool VerifiedRootCertSubjectVerifier::Verify(
98     TlsCustomVerificationCheckRequest* request,
99     std::function<void(grpc::Status)>, grpc::Status* sync_status) {
100   if (request->verified_root_cert_subject() != expected_subject_) {
101     *sync_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED,
102                                 "VerifiedRootCertSubjectVerifier failed");
103   } else {
104     *sync_status = grpc::Status::OK;
105   }
106   return true;
107 }
108 
109 }  // namespace testing
110 }  // namespace grpc
111