blob: 1416037926cd28e7a6ba1e0bc8bc3aa129a28fb0 [file] [log] [blame]
//
// 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.
//
#ifndef GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H
#define GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H
#include <grpc/support/port_platform.h>
#include <functional>
#include <map>
#include "absl/base/thread_annotations.h"
#include "absl/status/status.h"
#include <grpc/grpc_security.h>
#include <grpc/status.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/gprpp/unique_type_name.h"
// An abstraction of the verifier that all verifier subclasses should extend.
struct grpc_tls_certificate_verifier
: public grpc_core::RefCounted<grpc_tls_certificate_verifier> {
public:
~grpc_tls_certificate_verifier() override = default;
// Verifies the specific request. It can be processed in sync or async mode.
// If the caller want it to be processed asynchronously, return false
// immediately, and at the end of the async operation, invoke the callback
// with the verification results stored in absl::Status. Otherwise, populate
// the verification results in |sync_status| and return true. The caller is
// expected to populate verification results by setting request.
virtual bool Verify(grpc_tls_custom_verification_check_request* request,
std::function<void(absl::Status)> callback,
absl::Status* sync_status) = 0;
// Operations that will be performed when a request is cancelled.
// This is only needed when in async mode.
virtual void Cancel(grpc_tls_custom_verification_check_request* request) = 0;
// Compares this grpc_tls_certificate_verifier object with \a other.
// If this method returns 0, it means that gRPC can treat the two certificate
// verifiers as effectively the same.
int Compare(const grpc_tls_certificate_verifier* other) const {
GPR_ASSERT(other != nullptr);
int r = type().Compare(other->type());
if (r != 0) return r;
return CompareImpl(other);
}
// The pointer value \a type is used to uniquely identify a verifier
// implementation for down-casting purposes. Every verifier implementation
// should use a unique string instance, which should be returned by all
// instances of that verifier implementation.
virtual grpc_core::UniqueTypeName type() const = 0;
private:
// Implementation for `Compare` method intended to be overridden by
// subclasses. Only invoked if `type()` and `other->type()` point to the same
// string.
virtual int CompareImpl(const grpc_tls_certificate_verifier* other) const = 0;
};
namespace grpc_core {
// A verifier that will transform grpc_tls_certificate_verifier_external to a
// verifier that extends grpc_tls_certificate_verifier.
class ExternalCertificateVerifier : public grpc_tls_certificate_verifier {
public:
explicit ExternalCertificateVerifier(
grpc_tls_certificate_verifier_external* external_verifier)
: external_verifier_(external_verifier) {}
~ExternalCertificateVerifier() override {
if (external_verifier_->destruct != nullptr) {
external_verifier_->destruct(external_verifier_->user_data);
}
}
bool Verify(grpc_tls_custom_verification_check_request* request,
std::function<void(absl::Status)> callback,
absl::Status* sync_status) override;
void Cancel(grpc_tls_custom_verification_check_request* request) override {
external_verifier_->cancel(external_verifier_->user_data, request);
}
UniqueTypeName type() const override;
private:
int CompareImpl(const grpc_tls_certificate_verifier* other) const override {
const auto* o = static_cast<const ExternalCertificateVerifier*>(other);
return QsortCompare(external_verifier_, o->external_verifier_);
}
static void OnVerifyDone(grpc_tls_custom_verification_check_request* request,
void* callback_arg, grpc_status_code status,
const char* error_details);
grpc_tls_certificate_verifier_external* external_verifier_;
// Guards members below.
Mutex mu_;
// stores each check request and its corresponding callback function.
std::map<grpc_tls_custom_verification_check_request*,
std::function<void(absl::Status)>>
request_map_ ABSL_GUARDED_BY(mu_);
};
// An internal verifier that won't perform any post-handshake checks.
// Note: using this solely without any other authentication mechanisms on the
// peer identity will leave your applications to the MITM(Man-In-The-Middle)
// attacks. Users should avoid doing so in production environments.
class NoOpCertificateVerifier : public grpc_tls_certificate_verifier {
public:
bool Verify(grpc_tls_custom_verification_check_request*,
std::function<void(absl::Status)>, absl::Status*) override {
return true; // synchronous check
};
void Cancel(grpc_tls_custom_verification_check_request*) override {}
UniqueTypeName type() const override;
private:
int CompareImpl(
const grpc_tls_certificate_verifier* /* other */) const override {
// No differentiating factor between different NoOpCertificateVerifier
// objects.
return 0;
}
};
// An internal verifier that will perform hostname verification check.
class HostNameCertificateVerifier : public grpc_tls_certificate_verifier {
public:
bool Verify(grpc_tls_custom_verification_check_request* request,
std::function<void(absl::Status)> callback,
absl::Status* sync_status) override;
void Cancel(grpc_tls_custom_verification_check_request*) override {}
UniqueTypeName type() const override;
private:
int CompareImpl(
const grpc_tls_certificate_verifier* /* other */) const override {
// No differentiating factor between different HostNameCertificateVerifier
// objects.
return 0;
}
};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CERTIFICATE_VERIFIER_H