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