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