Skip to content

Commit 8762f09

Browse files
committed
dynamic_modules: add dynamic modules support for cert validator
Signed-off-by: Rohit Agrawal <rohit.agrawal@databricks.com>
1 parent 19ad0bd commit 8762f09

File tree

26 files changed

+1941
-1
lines changed

26 files changed

+1941
-1
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ extensions/upstreams/tcp @ggreenway @mattklein123
409409
/*/extensions/filters/listener/dynamic_modules @agrawroh @mathetake @wbpcode
410410
/*/extensions/filters/udp/dynamic_modules @agrawroh @mathetake @wbpcode
411411
/*/extensions/load_balancing_policies/dynamic_modules @agrawroh @mathetake @wbpcode
412+
/*/extensions/transport_sockets/tls/cert_validator/dynamic_modules @agrawroh @mathetake @wbpcode
412413
# Linux network namespace override
413414
/*/extensions/local_address_selectors/filter_state_override @tonya11en @kyessenov
414415

api/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ proto_library(
406406
"//envoy/extensions/transport_sockets/tls/cert_mappers/sni/v3:pkg",
407407
"//envoy/extensions/transport_sockets/tls/cert_mappers/static_name/v3:pkg",
408408
"//envoy/extensions/transport_sockets/tls/cert_selectors/on_demand_secret/v3:pkg",
409+
"//envoy/extensions/transport_sockets/tls/cert_validator/dynamic_modules/v3:pkg",
409410
"//envoy/extensions/transport_sockets/tls/v3:pkg",
410411
"//envoy/extensions/udp_packet_writer/v3:pkg",
411412
"//envoy/extensions/upstreams/http/generic/v3:pkg",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.
2+
3+
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")
4+
5+
licenses(["notice"]) # Apache 2
6+
7+
api_proto_package(
8+
deps = [
9+
"//envoy/extensions/dynamic_modules/v3:pkg",
10+
"@xds//udpa/annotations:pkg",
11+
],
12+
)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
syntax = "proto3";
2+
3+
package envoy.extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3;
4+
5+
import "envoy/extensions/dynamic_modules/v3/dynamic_modules.proto";
6+
7+
import "google/protobuf/any.proto";
8+
9+
import "udpa/annotations/status.proto";
10+
import "validate/validate.proto";
11+
12+
option java_package = "io.envoyproxy.envoy.extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3";
13+
option java_outer_classname = "DynamicModulesProto";
14+
option java_multiple_files = true;
15+
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/cert_validator/dynamic_modules/v3;dynamic_modulesv3";
16+
option (udpa.annotations.file_status).package_version_status = ACTIVE;
17+
18+
// [#protodoc-title: Dynamic Module Certificate Validator]
19+
// [#extension: envoy.tls.cert_validator.dynamic_modules]
20+
21+
// Configuration for the dynamic module certificate validator.
22+
//
23+
// Example:
24+
//
25+
// .. validated-code-block:: yaml
26+
// :type-name: envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext
27+
//
28+
// custom_validator_config:
29+
// name: envoy.tls.cert_validator.dynamic_modules
30+
// typed_config:
31+
// "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3.DynamicModuleCertValidatorConfig
32+
// dynamic_module_config:
33+
// name: my_module
34+
// validator_name: my_validator
35+
//
36+
message DynamicModuleCertValidatorConfig {
37+
// Dynamic module configuration. See :ref:`dynamic module configuration
38+
// <envoy_v3_api_msg_extensions.dynamic_modules.v3.DynamicModuleConfig>` for details.
39+
envoy.extensions.dynamic_modules.v3.DynamicModuleConfig dynamic_module_config = 1
40+
[(validate.rules).message = {required: true}];
41+
42+
// The name of the cert validator implementation in the dynamic module.
43+
// This is passed to the module's ``envoy_dynamic_module_on_cert_validator_config_new``
44+
// function.
45+
string validator_name = 2 [(validate.rules).string = {min_len: 1}];
46+
47+
// Optional configuration for the cert validator. This is passed as bytes to the dynamic module.
48+
google.protobuf.Any validator_config = 3;
49+
}

api/versioning/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ proto_library(
346346
"//envoy/extensions/transport_sockets/tls/cert_mappers/sni/v3:pkg",
347347
"//envoy/extensions/transport_sockets/tls/cert_mappers/static_name/v3:pkg",
348348
"//envoy/extensions/transport_sockets/tls/cert_selectors/on_demand_secret/v3:pkg",
349+
"//envoy/extensions/transport_sockets/tls/cert_validator/dynamic_modules/v3:pkg",
349350
"//envoy/extensions/transport_sockets/tls/v3:pkg",
350351
"//envoy/extensions/udp_packet_writer/v3:pkg",
351352
"//envoy/extensions/upstreams/http/generic/v3:pkg",

changelogs/current.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ removed_config_or_runtime:
119119
# *Normally occurs at the end of the* :ref:`deprecation period <deprecated>`
120120

121121
new_features:
122+
- area: dynamic_modules
123+
change: |
124+
Added :ref:`TLS certificate validator
125+
<envoy_v3_api_msg_extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3.DynamicModuleCertValidatorConfig>`
126+
support for dynamic modules, enabling custom TLS certificate validation to be implemented in dynamic modules.
122127
- area: ext_authz
123128
change: |
124129
Added support for the ``append_action`` enum in gRPC ext_authz ``OkHttpResponse.headers`` for upstream
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Certificate validators
2+
======================
3+
4+
These extensions allow custom TLS certificate validation.
5+
6+
.. toctree::
7+
:glob:
8+
:maxdepth: 2
9+
10+
../../extensions/transport_sockets/tls/cert_validator/*/v3/*

docs/root/api-v3/config/config.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Extensions
1212
accesslog/accesslog
1313
certificate_mappers/certificate_mappers
1414
certificate_selectors/certificate_selectors
15+
certificate_validators/certificate_validators
1516
cluster/cluster
1617
common/common
1718
compression/compression

docs/root/intro/arch_overview/advanced/dynamic_modules.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Currently, dynamic modules are supported at the following extension points:
2727
* As an :ref:`access logger <envoy_v3_api_msg_extensions.access_loggers.dynamic_modules.v3.DynamicModuleAccessLog>`.
2828
* As a :ref:`network filter <envoy_v3_api_msg_extensions.filters.network.dynamic_modules.v3.DynamicModuleNetworkFilter>`.
2929
* As an :ref:`HTTP filter <envoy_v3_api_msg_extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter>`.
30+
* As a :ref:`TLS certificate validator <envoy_v3_api_msg_extensions.transport_sockets.tls.cert_validator.dynamic_modules.v3.DynamicModuleCertValidatorConfig>`.
3031

3132
There are a few design goals for the dynamic modules:
3233

source/extensions/dynamic_modules/abi/abi.h

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6326,6 +6326,166 @@ bool envoy_dynamic_module_callback_lb_context_get_downstream_header(
63266326
envoy_dynamic_module_type_module_buffer key,
63276327
envoy_dynamic_module_type_envoy_buffer* result_buffer, size_t index, size_t* optional_size);
63286328

6329+
// =============================================================================
6330+
// ============================ Cert Validator ==================================
6331+
// =============================================================================
6332+
//
6333+
// This extension enables custom TLS certificate validation via dynamic modules.
6334+
// It integrates with Envoy's custom_validator_config in CertificateValidationContext,
6335+
// registered under the envoy.tls.cert_validator category.
6336+
//
6337+
// The module receives DER-encoded certificates during validation and returns
6338+
// a result indicating success or failure with optional TLS alert and error details.
6339+
6340+
// =============================================================================
6341+
// Cert Validator Types
6342+
// =============================================================================
6343+
6344+
/**
6345+
* envoy_dynamic_module_type_cert_validator_config_envoy_ptr is a pointer to the
6346+
* DynamicModuleCertValidatorConfig object in Envoy. This is passed to the module during config
6347+
* creation and cert chain verification.
6348+
*
6349+
* OWNERSHIP: Envoy owns this object.
6350+
*/
6351+
typedef void* envoy_dynamic_module_type_cert_validator_config_envoy_ptr;
6352+
6353+
/**
6354+
* envoy_dynamic_module_type_cert_validator_config_module_ptr is a pointer to the in-module cert
6355+
* validator configuration created and owned by the module.
6356+
*
6357+
* OWNERSHIP: Module owns this pointer.
6358+
*/
6359+
typedef const void* envoy_dynamic_module_type_cert_validator_config_module_ptr;
6360+
6361+
/**
6362+
* envoy_dynamic_module_type_cert_validator_validation_status represents the status of the
6363+
* certificate chain validation. This corresponds to ValidationResults::ValidationStatus in
6364+
* cert_validator.h.
6365+
*
6366+
* Note: Pending (asynchronous) validation is not supported.
6367+
*/
6368+
typedef enum envoy_dynamic_module_type_cert_validator_validation_status {
6369+
envoy_dynamic_module_type_cert_validator_validation_status_Successful = 0,
6370+
envoy_dynamic_module_type_cert_validator_validation_status_Failed = 1,
6371+
} envoy_dynamic_module_type_cert_validator_validation_status;
6372+
6373+
/**
6374+
* envoy_dynamic_module_type_cert_validator_client_validation_status represents the detailed client
6375+
* validation status. This corresponds to Ssl::ClientValidationStatus in
6376+
* ssl_socket_extended_info.h.
6377+
*/
6378+
typedef enum envoy_dynamic_module_type_cert_validator_client_validation_status {
6379+
envoy_dynamic_module_type_cert_validator_client_validation_status_NotValidated = 0,
6380+
envoy_dynamic_module_type_cert_validator_client_validation_status_NoClientCertificate = 1,
6381+
envoy_dynamic_module_type_cert_validator_client_validation_status_Validated = 2,
6382+
envoy_dynamic_module_type_cert_validator_client_validation_status_Failed = 3,
6383+
} envoy_dynamic_module_type_cert_validator_client_validation_status;
6384+
6385+
/**
6386+
* envoy_dynamic_module_type_cert_validator_validation_result is the result of a certificate chain
6387+
* verification. Returned by the envoy_dynamic_module_on_cert_validator_do_verify_cert_chain event
6388+
* hook.
6389+
*/
6390+
typedef struct envoy_dynamic_module_type_cert_validator_validation_result {
6391+
// The overall validation status (Successful or Failed).
6392+
envoy_dynamic_module_type_cert_validator_validation_status status;
6393+
// The detailed client validation status.
6394+
envoy_dynamic_module_type_cert_validator_client_validation_status detailed_status;
6395+
// The TLS alert code to send on failure (e.g. SSL_AD_BAD_CERTIFICATE).
6396+
uint8_t tls_alert;
6397+
// Whether the tls_alert field is set.
6398+
bool has_tls_alert;
6399+
// Error details string owned by the module. Must remain valid until the end of the
6400+
// do_verify_cert_chain event hook. Can be empty (length 0) if no details are available.
6401+
envoy_dynamic_module_type_module_buffer error_details;
6402+
} envoy_dynamic_module_type_cert_validator_validation_result;
6403+
6404+
// =============================================================================
6405+
// Cert Validator Event Hooks
6406+
// =============================================================================
6407+
6408+
/**
6409+
* envoy_dynamic_module_on_cert_validator_config_new is called by the main thread when the cert
6410+
* validator config is loaded. The function returns a
6411+
* envoy_dynamic_module_type_cert_validator_config_module_ptr for given name and config.
6412+
*
6413+
* @param config_envoy_ptr is the pointer to the DynamicModuleCertValidatorConfig object for the
6414+
* corresponding config.
6415+
* @param name is the name of the validator owned by Envoy.
6416+
* @param config is the configuration for the module owned by Envoy.
6417+
* @return envoy_dynamic_module_type_cert_validator_config_module_ptr is the pointer to the
6418+
* in-module cert validator configuration. Returning nullptr indicates a failure to initialize the
6419+
* module. When it fails, the cert validator configuration will be rejected.
6420+
*/
6421+
envoy_dynamic_module_type_cert_validator_config_module_ptr
6422+
envoy_dynamic_module_on_cert_validator_config_new(
6423+
envoy_dynamic_module_type_cert_validator_config_envoy_ptr config_envoy_ptr,
6424+
envoy_dynamic_module_type_envoy_buffer name, envoy_dynamic_module_type_envoy_buffer config);
6425+
6426+
/**
6427+
* envoy_dynamic_module_on_cert_validator_config_destroy is called when the cert validator
6428+
* configuration is destroyed in Envoy. The module should release any resources associated with
6429+
* the corresponding in-module cert validator configuration.
6430+
*
6431+
* @param config_module_ptr is a pointer to the in-module cert validator configuration whose
6432+
* corresponding Envoy cert validator configuration is being destroyed.
6433+
*/
6434+
void envoy_dynamic_module_on_cert_validator_config_destroy(
6435+
envoy_dynamic_module_type_cert_validator_config_module_ptr config_module_ptr);
6436+
6437+
/**
6438+
* envoy_dynamic_module_on_cert_validator_do_verify_cert_chain is called to verify a certificate
6439+
* chain during a TLS handshake. The certificates are provided as DER-encoded buffers. The first
6440+
* certificate (index 0) is the leaf certificate.
6441+
*
6442+
* The certs array and its buffer contents are owned by Envoy and are valid only for the duration
6443+
* of this event hook call.
6444+
*
6445+
* @param config_envoy_ptr is the pointer to the DynamicModuleCertValidatorConfig object.
6446+
* @param config_module_ptr is the pointer to the in-module cert validator configuration.
6447+
* @param certs is an array of DER-encoded certificate buffers.
6448+
* @param certs_count is the number of certificates in the array.
6449+
* @param host_name is the SNI host name for validation.
6450+
* @param is_server is true if the validation is on the server side (validating client certs).
6451+
* @return envoy_dynamic_module_type_cert_validator_validation_result is the validation result.
6452+
*/
6453+
envoy_dynamic_module_type_cert_validator_validation_result
6454+
envoy_dynamic_module_on_cert_validator_do_verify_cert_chain(
6455+
envoy_dynamic_module_type_cert_validator_config_envoy_ptr config_envoy_ptr,
6456+
envoy_dynamic_module_type_cert_validator_config_module_ptr config_module_ptr,
6457+
envoy_dynamic_module_type_envoy_buffer* certs, size_t certs_count,
6458+
envoy_dynamic_module_type_envoy_buffer host_name, bool is_server);
6459+
6460+
/**
6461+
* envoy_dynamic_module_on_cert_validator_get_ssl_verify_mode is called during SSL context
6462+
* initialization to get the SSL verify mode flags that should be applied to SSL contexts.
6463+
*
6464+
* The return value should be a combination of SSL_VERIFY_* flags (e.g. SSL_VERIFY_PEER,
6465+
* SSL_VERIFY_FAIL_IF_NO_PEER_CERT). Returning 0 means SSL_VERIFY_NONE.
6466+
*
6467+
* @param config_module_ptr is the pointer to the in-module cert validator configuration.
6468+
* @param handshaker_provides_certificates is true if the handshaker provides certificates itself.
6469+
* @return int the SSL verify mode flags.
6470+
*/
6471+
int envoy_dynamic_module_on_cert_validator_get_ssl_verify_mode(
6472+
envoy_dynamic_module_type_cert_validator_config_module_ptr config_module_ptr,
6473+
bool handshaker_provides_certificates);
6474+
6475+
/**
6476+
* envoy_dynamic_module_on_cert_validator_update_digest is called to contribute to the session
6477+
* context hash. The module should provide bytes that uniquely identify its validation configuration
6478+
* so that configuration changes invalidate existing TLS sessions. The output buffer must remain
6479+
* valid until the end of this event hook.
6480+
*
6481+
* @param config_module_ptr is the pointer to the in-module cert validator configuration.
6482+
* @param out_data is a pointer to a buffer that the module should fill with the digest data.
6483+
* The module should set the ptr and length fields.
6484+
*/
6485+
void envoy_dynamic_module_on_cert_validator_update_digest(
6486+
envoy_dynamic_module_type_cert_validator_config_module_ptr config_module_ptr,
6487+
envoy_dynamic_module_type_module_buffer* out_data);
6488+
63296489
#ifdef __cplusplus
63306490
}
63316491
#endif

0 commit comments

Comments
 (0)