Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ extensions/upstreams/tcp @ggreenway @mattklein123
/*/extensions/filters/listener/dynamic_modules @agrawroh @mathetake @wbpcode
/*/extensions/filters/udp/dynamic_modules @agrawroh @mathetake @wbpcode
/*/extensions/load_balancing_policies/dynamic_modules @agrawroh @mathetake @wbpcode
/*/extensions/transport_sockets/tls/cert_validator/dynamic_modules @agrawroh @mathetake @wbpcode
# Linux network namespace override
/*/extensions/local_address_selectors/filter_state_override @tonya11en @kyessenov

Expand Down
1 change: 1 addition & 0 deletions api/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ proto_library(
"//envoy/extensions/transport_sockets/tls/cert_mappers/sni/v3:pkg",
"//envoy/extensions/transport_sockets/tls/cert_mappers/static_name/v3:pkg",
"//envoy/extensions/transport_sockets/tls/cert_selectors/on_demand_secret/v3:pkg",
"//envoy/extensions/transport_sockets/tls/cert_validator/dynamic_modules/v3:pkg",
"//envoy/extensions/transport_sockets/tls/v3:pkg",
"//envoy/extensions/udp_packet_writer/v3:pkg",
"//envoy/extensions/upstreams/http/generic/v3:pkg",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.

load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")

licenses(["notice"]) # Apache 2

api_proto_package(
deps = [
"//envoy/extensions/dynamic_modules/v3:pkg",
"@xds//udpa/annotations:pkg",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
syntax = "proto3";

package envoy.extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3;

import "envoy/extensions/dynamic_modules/v3/dynamic_modules.proto";

import "google/protobuf/any.proto";

import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3";
option java_outer_classname = "DynamicModulesProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/cert_validator/dynamic_modules/v3;dynamic_modulesv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Dynamic Module Certificate Validator]
// [#extension: envoy.tls.cert_validator.dynamic_modules]

// Configuration for the dynamic module certificate validator.
//
// Example:
//
// .. validated-code-block:: yaml
// :type-name: envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext
//
// custom_validator_config:
// name: envoy.tls.cert_validator.dynamic_modules
// typed_config:
// "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3.DynamicModuleCertValidatorConfig
// dynamic_module_config:
// name: my_module
// validator_name: my_validator
//
message DynamicModuleCertValidatorConfig {
// Dynamic module configuration. See :ref:`dynamic module configuration
// <envoy_v3_api_msg_extensions.dynamic_modules.v3.DynamicModuleConfig>` for details.
envoy.extensions.dynamic_modules.v3.DynamicModuleConfig dynamic_module_config = 1
[(validate.rules).message = {required: true}];

// The name of the cert validator implementation in the dynamic module.
// This is passed to the module's ``envoy_dynamic_module_on_cert_validator_config_new``
// function.
string validator_name = 2 [(validate.rules).string = {min_len: 1}];

// Optional configuration for the cert validator. This is passed as bytes to the dynamic module.
google.protobuf.Any validator_config = 3;
}
1 change: 1 addition & 0 deletions api/versioning/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ proto_library(
"//envoy/extensions/transport_sockets/tls/cert_mappers/sni/v3:pkg",
"//envoy/extensions/transport_sockets/tls/cert_mappers/static_name/v3:pkg",
"//envoy/extensions/transport_sockets/tls/cert_selectors/on_demand_secret/v3:pkg",
"//envoy/extensions/transport_sockets/tls/cert_validator/dynamic_modules/v3:pkg",
"//envoy/extensions/transport_sockets/tls/v3:pkg",
"//envoy/extensions/udp_packet_writer/v3:pkg",
"//envoy/extensions/upstreams/http/generic/v3:pkg",
Expand Down
5 changes: 5 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ removed_config_or_runtime:
# *Normally occurs at the end of the* :ref:`deprecation period <deprecated>`

new_features:
- area: dynamic_modules
change: |
Added :ref:`TLS certificate validator
<envoy_v3_api_msg_extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3.DynamicModuleCertValidatorConfig>`
support for dynamic modules, enabling custom TLS certificate validation to be implemented in dynamic modules.
- area: ext_authz
change: |
Added support for the ``append_action`` enum in gRPC ext_authz ``OkHttpResponse.headers`` for upstream
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Certificate validators
======================

These extensions allow custom TLS certificate validation.

.. toctree::
:glob:
:maxdepth: 2

../../extensions/transport_sockets/tls/cert_validator/*/v3/*
1 change: 1 addition & 0 deletions docs/root/api-v3/config/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Extensions
accesslog/accesslog
certificate_mappers/certificate_mappers
certificate_selectors/certificate_selectors
certificate_validators/certificate_validators
cluster/cluster
common/common
compression/compression
Expand Down
1 change: 1 addition & 0 deletions docs/root/intro/arch_overview/advanced/dynamic_modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Currently, dynamic modules are supported at the following extension points:
* As an :ref:`access logger <envoy_v3_api_msg_extensions.access_loggers.dynamic_modules.v3.DynamicModuleAccessLog>`.
* As a :ref:`network filter <envoy_v3_api_msg_extensions.filters.network.dynamic_modules.v3.DynamicModuleNetworkFilter>`.
* As an :ref:`HTTP filter <envoy_v3_api_msg_extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter>`.
* As a :ref:`TLS certificate validator <envoy_v3_api_msg_extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3.DynamicModuleCertValidatorConfig>`.

There are a few design goals for the dynamic modules:

Expand Down
179 changes: 179 additions & 0 deletions source/extensions/dynamic_modules/abi/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -6476,6 +6476,185 @@ bool envoy_dynamic_module_callback_lb_context_get_downstream_header(
envoy_dynamic_module_type_module_buffer key,
envoy_dynamic_module_type_envoy_buffer* result_buffer, size_t index, size_t* optional_size);

// =============================================================================
// ============================ Cert Validator ==================================
// =============================================================================
//
// This extension enables custom TLS certificate validation via dynamic modules.
// It integrates with Envoy's custom_validator_config in CertificateValidationContext,
// registered under the envoy.tls.cert_validator category.
//
// The module receives DER-encoded certificates during validation and returns
// a result indicating success or failure with optional TLS alert and error details.

// =============================================================================
// Cert Validator Types
// =============================================================================

/**
* envoy_dynamic_module_type_cert_validator_config_envoy_ptr is a pointer to the
* DynamicModuleCertValidatorConfig object in Envoy. This is passed to the module during config
* creation and cert chain verification.
*
* OWNERSHIP: Envoy owns this object.
*/
typedef void* envoy_dynamic_module_type_cert_validator_config_envoy_ptr;

/**
* envoy_dynamic_module_type_cert_validator_config_module_ptr is a pointer to the in-module cert
* validator configuration created and owned by the module.
*
* OWNERSHIP: Module owns this pointer.
*/
typedef const void* envoy_dynamic_module_type_cert_validator_config_module_ptr;

/**
* envoy_dynamic_module_type_cert_validator_validation_status represents the status of the
* certificate chain validation. This corresponds to ValidationResults::ValidationStatus in
* cert_validator.h.
*
* Note: Pending (asynchronous) validation is not supported.
*/
typedef enum envoy_dynamic_module_type_cert_validator_validation_status {
envoy_dynamic_module_type_cert_validator_validation_status_Successful = 0,
envoy_dynamic_module_type_cert_validator_validation_status_Failed = 1,
} envoy_dynamic_module_type_cert_validator_validation_status;

/**
* envoy_dynamic_module_type_cert_validator_client_validation_status represents the detailed client
* validation status. This corresponds to Ssl::ClientValidationStatus in
* ssl_socket_extended_info.h.
*/
typedef enum envoy_dynamic_module_type_cert_validator_client_validation_status {
envoy_dynamic_module_type_cert_validator_client_validation_status_NotValidated = 0,
envoy_dynamic_module_type_cert_validator_client_validation_status_NoClientCertificate = 1,
envoy_dynamic_module_type_cert_validator_client_validation_status_Validated = 2,
envoy_dynamic_module_type_cert_validator_client_validation_status_Failed = 3,
} envoy_dynamic_module_type_cert_validator_client_validation_status;

/**
* envoy_dynamic_module_type_cert_validator_validation_result is the result of a certificate chain
* verification. Returned by the envoy_dynamic_module_on_cert_validator_do_verify_cert_chain event
* hook.
*
* Error details, if any, should be set via the
* envoy_dynamic_module_callback_cert_validator_set_error_details callback before returning.
*/
typedef struct envoy_dynamic_module_type_cert_validator_validation_result {
// The overall validation status (Successful or Failed).
envoy_dynamic_module_type_cert_validator_validation_status status;
// The detailed client validation status.
envoy_dynamic_module_type_cert_validator_client_validation_status detailed_status;
// The TLS alert code to send on failure (e.g. SSL_AD_BAD_CERTIFICATE).
uint8_t tls_alert;
// Whether the tls_alert field is set.
bool has_tls_alert;
} envoy_dynamic_module_type_cert_validator_validation_result;

// =============================================================================
// Cert Validator Event Hooks
// =============================================================================

/**
* envoy_dynamic_module_on_cert_validator_config_new is called by the main thread when the cert
* validator config is loaded. The function returns a
* envoy_dynamic_module_type_cert_validator_config_module_ptr for given name and config.
*
* @param config_envoy_ptr is the pointer to the DynamicModuleCertValidatorConfig object for the
* corresponding config.
* @param name is the name of the validator owned by Envoy.
* @param config is the configuration for the module owned by Envoy.
* @return envoy_dynamic_module_type_cert_validator_config_module_ptr is the pointer to the
* in-module cert validator configuration. Returning nullptr indicates a failure to initialize the
* module. When it fails, the cert validator configuration will be rejected.
*/
envoy_dynamic_module_type_cert_validator_config_module_ptr
envoy_dynamic_module_on_cert_validator_config_new(
envoy_dynamic_module_type_cert_validator_config_envoy_ptr config_envoy_ptr,
envoy_dynamic_module_type_envoy_buffer name, envoy_dynamic_module_type_envoy_buffer config);

/**
* envoy_dynamic_module_on_cert_validator_config_destroy is called when the cert validator
* configuration is destroyed in Envoy. The module should release any resources associated with
* the corresponding in-module cert validator configuration.
*
* @param config_module_ptr is a pointer to the in-module cert validator configuration whose
* corresponding Envoy cert validator configuration is being destroyed.
*/
void envoy_dynamic_module_on_cert_validator_config_destroy(
envoy_dynamic_module_type_cert_validator_config_module_ptr config_module_ptr);

/**
* envoy_dynamic_module_on_cert_validator_do_verify_cert_chain is called to verify a certificate
* chain during a TLS handshake. The certificates are provided as DER-encoded buffers. The first
* certificate (index 0) is the leaf certificate.
*
* The certs array and its buffer contents are owned by Envoy and are valid only for the duration
* of this event hook call.
*
* @param config_envoy_ptr is the pointer to the DynamicModuleCertValidatorConfig object.
* @param config_module_ptr is the pointer to the in-module cert validator configuration.
* @param certs is an array of DER-encoded certificate buffers.
* @param certs_count is the number of certificates in the array.
* @param host_name is the SNI host name for validation.
* @param is_server is true if the validation is on the server side (validating client certs).
* @return envoy_dynamic_module_type_cert_validator_validation_result is the validation result.
*/
envoy_dynamic_module_type_cert_validator_validation_result
envoy_dynamic_module_on_cert_validator_do_verify_cert_chain(
envoy_dynamic_module_type_cert_validator_config_envoy_ptr config_envoy_ptr,
envoy_dynamic_module_type_cert_validator_config_module_ptr config_module_ptr,
envoy_dynamic_module_type_envoy_buffer* certs, size_t certs_count,
envoy_dynamic_module_type_envoy_buffer host_name, bool is_server);

/**
* envoy_dynamic_module_on_cert_validator_get_ssl_verify_mode is called during SSL context
* initialization to get the SSL verify mode flags that should be applied to SSL contexts.
*
* The return value should be a combination of SSL_VERIFY_* flags (e.g. SSL_VERIFY_PEER,
* SSL_VERIFY_FAIL_IF_NO_PEER_CERT). Returning 0 means SSL_VERIFY_NONE.
*
* @param config_module_ptr is the pointer to the in-module cert validator configuration.
* @param handshaker_provides_certificates is true if the handshaker provides certificates itself.
* @return int the SSL verify mode flags.
*/
int envoy_dynamic_module_on_cert_validator_get_ssl_verify_mode(
envoy_dynamic_module_type_cert_validator_config_module_ptr config_module_ptr,
bool handshaker_provides_certificates);

/**
* envoy_dynamic_module_on_cert_validator_update_digest is called to contribute to the session
* context hash. The module should provide bytes that uniquely identify its validation configuration
* so that configuration changes invalidate existing TLS sessions. The output buffer must remain
* valid until the end of this event hook.
*
* @param config_module_ptr is the pointer to the in-module cert validator configuration.
* @param out_data is a pointer to a buffer that the module should fill with the digest data.
* The module should set the ptr and length fields.
*/
void envoy_dynamic_module_on_cert_validator_update_digest(
envoy_dynamic_module_type_cert_validator_config_module_ptr config_module_ptr,
envoy_dynamic_module_type_module_buffer* out_data);

// =============================================================================
// Cert Validator Callbacks
// =============================================================================

/**
* envoy_dynamic_module_callback_cert_validator_set_error_details is called by the module during
* envoy_dynamic_module_on_cert_validator_do_verify_cert_chain to set error details for a failed
* validation. Envoy copies the provided buffer immediately, so the module does not need to keep
* the buffer alive after this call returns.
*
* This must only be called from within the do_verify_cert_chain event hook.
*
* @param config_envoy_ptr is the pointer to the DynamicModuleCertValidatorConfig object.
* @param error_details is the error details string owned by the module.
*/
void envoy_dynamic_module_callback_cert_validator_set_error_details(
envoy_dynamic_module_type_cert_validator_config_envoy_ptr config_envoy_ptr,
envoy_dynamic_module_type_module_buffer error_details);

#ifdef __cplusplus
}
#endif
Expand Down
11 changes: 11 additions & 0 deletions source/extensions/dynamic_modules/abi_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ __attribute__((weak)) void envoy_dynamic_module_callback_bootstrap_extension_ite
"not implemented in this context");
}

// ---------------------- Cert Validator callbacks ------------------------
// These are weak symbols that provide default stub implementations. The actual implementation
// is provided in the cert validator config.cc when the cert validator extension is used.

__attribute__((weak)) void envoy_dynamic_module_callback_cert_validator_set_error_details(
envoy_dynamic_module_type_cert_validator_config_envoy_ptr,
envoy_dynamic_module_type_module_buffer) {
IS_ENVOY_BUG("envoy_dynamic_module_callback_cert_validator_set_error_details: "
"not implemented in this context");
}

// ---------------------- Bootstrap extension timer callbacks ------------------------
// These are weak symbols that provide default stub implementations. The actual implementations
// are provided in the bootstrap extension abi_impl.cc when the bootstrap extension is used.
Expand Down
Loading
Loading