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 #ifndef GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H 18 #define GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H 19 20 #include <grpc/support/port_platform.h> 21 22 #include <functional> 23 #include <map> 24 25 #include "absl/base/thread_annotations.h" 26 #include "absl/status/status.h" 27 28 #include <grpc/grpc_security.h> 29 #include <grpc/status.h> 30 #include <grpc/support/log.h> 31 32 #include "src/core/lib/gpr/useful.h" 33 #include "src/core/lib/gprpp/ref_counted.h" 34 #include "src/core/lib/gprpp/sync.h" 35 #include "src/core/lib/gprpp/unique_type_name.h" 36 37 // An abstraction of the verifier that all verifier subclasses should extend. 38 struct grpc_tls_certificate_verifier 39 : public grpc_core::RefCounted<grpc_tls_certificate_verifier> { 40 public: 41 ~grpc_tls_certificate_verifier() override = default; 42 // Verifies the specific request. It can be processed in sync or async mode. 43 // If the caller want it to be processed asynchronously, return false 44 // immediately, and at the end of the async operation, invoke the callback 45 // with the verification results stored in absl::Status. Otherwise, populate 46 // the verification results in |sync_status| and return true. The caller is 47 // expected to populate verification results by setting request. 48 virtual bool Verify(grpc_tls_custom_verification_check_request* request, 49 std::function<void(absl::Status)> callback, 50 absl::Status* sync_status) = 0; 51 // Operations that will be performed when a request is cancelled. 52 // This is only needed when in async mode. 53 virtual void Cancel(grpc_tls_custom_verification_check_request* request) = 0; 54 55 // Compares this grpc_tls_certificate_verifier object with \a other. 56 // If this method returns 0, it means that gRPC can treat the two certificate 57 // verifiers as effectively the same. Comparegrpc_tls_certificate_verifier58 int Compare(const grpc_tls_certificate_verifier* other) const { 59 GPR_ASSERT(other != nullptr); 60 int r = type().Compare(other->type()); 61 if (r != 0) return r; 62 return CompareImpl(other); 63 } 64 65 // The pointer value \a type is used to uniquely identify a verifier 66 // implementation for down-casting purposes. Every verifier implementation 67 // should use a unique string instance, which should be returned by all 68 // instances of that verifier implementation. 69 virtual grpc_core::UniqueTypeName type() const = 0; 70 71 private: 72 // Implementation for `Compare` method intended to be overridden by 73 // subclasses. Only invoked if `type()` and `other->type()` point to the same 74 // string. 75 virtual int CompareImpl(const grpc_tls_certificate_verifier* other) const = 0; 76 }; 77 78 namespace grpc_core { 79 80 // A verifier that will transform grpc_tls_certificate_verifier_external to a 81 // verifier that extends grpc_tls_certificate_verifier. 82 class ExternalCertificateVerifier : public grpc_tls_certificate_verifier { 83 public: ExternalCertificateVerifier(grpc_tls_certificate_verifier_external * external_verifier)84 explicit ExternalCertificateVerifier( 85 grpc_tls_certificate_verifier_external* external_verifier) 86 : external_verifier_(external_verifier) {} 87 ~ExternalCertificateVerifier()88 ~ExternalCertificateVerifier() override { 89 if (external_verifier_->destruct != nullptr) { 90 external_verifier_->destruct(external_verifier_->user_data); 91 } 92 } 93 94 bool Verify(grpc_tls_custom_verification_check_request* request, 95 std::function<void(absl::Status)> callback, 96 absl::Status* sync_status) override; 97 Cancel(grpc_tls_custom_verification_check_request * request)98 void Cancel(grpc_tls_custom_verification_check_request* request) override { 99 external_verifier_->cancel(external_verifier_->user_data, request); 100 } 101 102 UniqueTypeName type() const override; 103 104 private: CompareImpl(const grpc_tls_certificate_verifier * other)105 int CompareImpl(const grpc_tls_certificate_verifier* other) const override { 106 const auto* o = static_cast<const ExternalCertificateVerifier*>(other); 107 return QsortCompare(external_verifier_, o->external_verifier_); 108 } 109 110 static void OnVerifyDone(grpc_tls_custom_verification_check_request* request, 111 void* callback_arg, grpc_status_code status, 112 const char* error_details); 113 114 grpc_tls_certificate_verifier_external* external_verifier_; 115 116 // Guards members below. 117 Mutex mu_; 118 // stores each check request and its corresponding callback function. 119 std::map<grpc_tls_custom_verification_check_request*, 120 std::function<void(absl::Status)>> 121 request_map_ ABSL_GUARDED_BY(mu_); 122 }; 123 124 // An internal verifier that won't perform any post-handshake checks. 125 // Note: using this solely without any other authentication mechanisms on the 126 // peer identity will leave your applications to the MITM(Man-In-The-Middle) 127 // attacks. Users should avoid doing so in production environments. 128 class NoOpCertificateVerifier : public grpc_tls_certificate_verifier { 129 public: Verify(grpc_tls_custom_verification_check_request *,std::function<void (absl::Status)>,absl::Status *)130 bool Verify(grpc_tls_custom_verification_check_request*, 131 std::function<void(absl::Status)>, absl::Status*) override { 132 return true; // synchronous check 133 }; Cancel(grpc_tls_custom_verification_check_request *)134 void Cancel(grpc_tls_custom_verification_check_request*) override {} 135 136 UniqueTypeName type() const override; 137 138 private: CompareImpl(const grpc_tls_certificate_verifier *)139 int CompareImpl( 140 const grpc_tls_certificate_verifier* /* other */) const override { 141 // No differentiating factor between different NoOpCertificateVerifier 142 // objects. 143 return 0; 144 } 145 }; 146 147 // An internal verifier that will perform hostname verification check. 148 class HostNameCertificateVerifier : public grpc_tls_certificate_verifier { 149 public: 150 bool Verify(grpc_tls_custom_verification_check_request* request, 151 std::function<void(absl::Status)> callback, 152 absl::Status* sync_status) override; Cancel(grpc_tls_custom_verification_check_request *)153 void Cancel(grpc_tls_custom_verification_check_request*) override {} 154 155 UniqueTypeName type() const override; 156 157 private: CompareImpl(const grpc_tls_certificate_verifier *)158 int CompareImpl( 159 const grpc_tls_certificate_verifier* /* other */) const override { 160 // No differentiating factor between different HostNameCertificateVerifier 161 // objects. 162 return 0; 163 } 164 }; 165 166 } // namespace grpc_core 167 168 #endif // GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H 169