// // Copyright 2021 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "test/cpp/util/tls_test_utils.h" #include #include "src/core/lib/gprpp/thd.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" using ::grpc::experimental::TlsCustomVerificationCheckRequest; namespace grpc { namespace testing { bool SyncCertificateVerifier::Verify(TlsCustomVerificationCheckRequest*, std::function, grpc::Status* sync_status) { if (!success_) { *sync_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED, "SyncCertificateVerifier failed"); } else { *sync_status = grpc::Status(grpc::StatusCode::OK, ""); } return true; } AsyncCertificateVerifier::AsyncCertificateVerifier(bool success) : success_(success), thread_("AsyncCertificateVerifierWorkerThread", WorkerThread, this) { thread_.Start(); } AsyncCertificateVerifier::~AsyncCertificateVerifier() { // Tell the thread to shut down. { internal::MutexLock lock(&mu_); queue_.push_back(Request{nullptr, nullptr, true}); } // Wait for thread to exit. thread_.Join(); } bool AsyncCertificateVerifier::Verify( TlsCustomVerificationCheckRequest* request, std::function callback, grpc::Status*) { internal::MutexLock lock(&mu_); queue_.push_back(Request{request, std::move(callback), false}); return false; // Asynchronous call } void AsyncCertificateVerifier::WorkerThread(void* arg) { auto* self = static_cast(arg); while (true) { // Check queue for work. bool got_request = false; Request request; { internal::MutexLock lock(&self->mu_); if (!self->queue_.empty()) { got_request = true; request = self->queue_.front(); self->queue_.pop_front(); } } // If nothing found in the queue, sleep for a bit and try again. if (!got_request) { gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100)); continue; } // If we're being told to shut down, return. if (request.shutdown) return; auto return_status = grpc::Status(grpc::StatusCode::OK, ""); // Process the request. if (!self->success_) { return_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED, "AsyncCertificateVerifier failed"); } request.callback(return_status); } } bool VerifiedRootCertSubjectVerifier::Verify( TlsCustomVerificationCheckRequest* request, std::function, grpc::Status* sync_status) { if (request->verified_root_cert_subject() != expected_subject_) { *sync_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED, "VerifiedRootCertSubjectVerifier failed"); } else { *sync_status = grpc::Status::OK; } return true; } } // namespace testing } // namespace grpc