From 8b11fdf718394538062ab43355ac2bbd3b0f5348 Mon Sep 17 00:00:00 2001 From: "data-plane-api(CircleCI)" Date: Thu, 24 Sep 2020 18:02:58 +0000 Subject: [PATCH] tls: add OCSP stapling support with configurable stapling policy (#12685) Add OCSP stapling support with configurable stapling policy. A pre-fetched OCSP response can be configured with its corresponding certificate via the new ocsp_staple field in the TlsCertificate message. The new ocsp_staple_policy field on DownstreamTlsContext determines whether an OCSP response is required and whether to continue using the TLS certificate for new connections once its OCSP response expires. The ocsp_staple_policy defaults to LENIENT_STAPLING, which allows the operator to omit ocsp_staples from the configuration and will only use OCSP responses that are present and valid. This should therefore not break any existing configurations. Risk Level: Medium - touches some core functionality of certificate selection but does not alter any existing behavior Testing: added Docs Changes: Added OCSP Stapling subsection in the SSL section of the architecture overview. Release Notes: Added Runtime flags: envoy.reloadable_features.check_ocsp_policy envoy.reloadable_features.require_ocsp_response_for_must_staple_certs Signed-off-by: Daniel Goldstein Signed-off-by: Stephan Zuercher Mirrored from https://github.com/envoyproxy/envoy @ cdd3a837056dc6935c0d8e0fb693d4de89b998e9 --- envoy/admin/v3/certs.proto | 13 ++++++++- envoy/admin/v4alpha/certs.proto | 16 +++++++++- .../transport_sockets/tls/v3/common.proto | 9 +++--- .../transport_sockets/tls/v3/tls.proto | 29 ++++++++++++++++++- .../tls/v4alpha/common.proto | 9 +++--- .../transport_sockets/tls/v4alpha/tls.proto | 29 ++++++++++++++++++- 6 files changed, 91 insertions(+), 14 deletions(-) diff --git a/envoy/admin/v3/certs.proto b/envoy/admin/v3/certs.proto index 158c8aea..5580bb5e 100644 --- a/envoy/admin/v3/certs.proto +++ b/envoy/admin/v3/certs.proto @@ -34,11 +34,19 @@ message Certificate { repeated CertificateDetails cert_chain = 2; } -// [#next-free-field: 7] +// [#next-free-field: 8] message CertificateDetails { option (udpa.annotations.versioning).previous_message_type = "envoy.admin.v2alpha.CertificateDetails"; + message OcspDetails { + // Indicates the time from which the OCSP response is valid. + google.protobuf.Timestamp valid_from = 1; + + // Indicates the time at which the OCSP response expires. + google.protobuf.Timestamp expiration = 2; + } + // Path of the certificate. string path = 1; @@ -56,6 +64,9 @@ message CertificateDetails { // Indicates the time at which the certificate expires. google.protobuf.Timestamp expiration_time = 6; + + // Details related to the OCSP response associated with this certificate, if any. + OcspDetails ocsp_details = 7; } message SubjectAlternateName { diff --git a/envoy/admin/v4alpha/certs.proto b/envoy/admin/v4alpha/certs.proto index 585b09bc..0dd868f7 100644 --- a/envoy/admin/v4alpha/certs.proto +++ b/envoy/admin/v4alpha/certs.proto @@ -34,10 +34,21 @@ message Certificate { repeated CertificateDetails cert_chain = 2; } -// [#next-free-field: 7] +// [#next-free-field: 8] message CertificateDetails { option (udpa.annotations.versioning).previous_message_type = "envoy.admin.v3.CertificateDetails"; + message OcspDetails { + option (udpa.annotations.versioning).previous_message_type = + "envoy.admin.v3.CertificateDetails.OcspDetails"; + + // Indicates the time from which the OCSP response is valid. + google.protobuf.Timestamp valid_from = 1; + + // Indicates the time at which the OCSP response expires. + google.protobuf.Timestamp expiration = 2; + } + // Path of the certificate. string path = 1; @@ -55,6 +66,9 @@ message CertificateDetails { // Indicates the time at which the certificate expires. google.protobuf.Timestamp expiration_time = 6; + + // Details related to the OCSP response associated with this certificate, if any. + OcspDetails ocsp_details = 7; } message SubjectAlternateName { diff --git a/envoy/extensions/transport_sockets/tls/v3/common.proto b/envoy/extensions/transport_sockets/tls/v3/common.proto index 5eab3c10..3ba4e198 100644 --- a/envoy/extensions/transport_sockets/tls/v3/common.proto +++ b/envoy/extensions/transport_sockets/tls/v3/common.proto @@ -151,7 +151,9 @@ message TlsCertificate { // TLS private key is not password encrypted. config.core.v3.DataSource password = 3 [(udpa.annotations.sensitive) = true]; - // [#not-implemented-hide:] + // The OCSP response to be stapled with this certificate during the handshake. + // The response must be DER-encoded and may only be provided via ``filename`` or + // ``inline_bytes``. The response may pertain to only one certificate. config.core.v3.DataSource ocsp_staple = 4; // [#not-implemented-hide:] @@ -205,7 +207,7 @@ message CertificateValidationContext { ACCEPT_UNTRUSTED = 1; } - reserved 4; + reserved 4, 5; reserved "verify_subject_alt_name"; @@ -315,9 +317,6 @@ message CertificateValidationContext { // `. repeated type.matcher.v3.StringMatcher match_subject_alt_names = 9; - // [#not-implemented-hide:] Must present a signed time-stamped OCSP response. - google.protobuf.BoolValue require_ocsp_staple = 5; - // [#not-implemented-hide:] Must present signed certificate time-stamp. google.protobuf.BoolValue require_signed_certificate_timestamp = 6; diff --git a/envoy/extensions/transport_sockets/tls/v3/tls.proto b/envoy/extensions/transport_sockets/tls/v3/tls.proto index f746f3d2..ab716a6a 100644 --- a/envoy/extensions/transport_sockets/tls/v3/tls.proto +++ b/envoy/extensions/transport_sockets/tls/v3/tls.proto @@ -54,11 +54,33 @@ message UpstreamTlsContext { google.protobuf.UInt32Value max_session_keys = 4; } -// [#next-free-field: 8] +// [#next-free-field: 9] message DownstreamTlsContext { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.DownstreamTlsContext"; + enum OcspStaplePolicy { + // OCSP responses are optional. If an OCSP response is absent + // or expired, the associated certificate will be used for + // connections without an OCSP staple. + LENIENT_STAPLING = 0; + + // OCSP responses are optional. If an OCSP response is absent, + // the associated certificate will be used without an + // OCSP staple. If a response is provided but is expired, + // the associated certificate will not be used for + // subsequent connections. If no suitable certificate is found, + // the connection is rejected. + STRICT_STAPLING = 1; + + // OCSP responses are required. Configuration will fail if + // a certificate is provided without an OCSP response. If a + // response expires, the associated certificate will not be + // used connections. If no suitable certificate is found, the + // connection is rejected. + MUST_STAPLE = 2; + } + // Common TLS context settings. CommonTlsContext common_tls_context = 1; @@ -96,6 +118,11 @@ message DownstreamTlsContext { lt {seconds: 4294967296} gte {} }]; + + // Config for whether to use certificates if they do not have + // an accompanying OCSP response or if the response expires at runtime. + // Defaults to LENIENT_STAPLING + OcspStaplePolicy ocsp_staple_policy = 8 [(validate.rules).enum = {defined_only: true}]; } // TLS context shared by both client and server TLS contexts. diff --git a/envoy/extensions/transport_sockets/tls/v4alpha/common.proto b/envoy/extensions/transport_sockets/tls/v4alpha/common.proto index 589dd17b..f3b936a4 100644 --- a/envoy/extensions/transport_sockets/tls/v4alpha/common.proto +++ b/envoy/extensions/transport_sockets/tls/v4alpha/common.proto @@ -153,7 +153,9 @@ message TlsCertificate { // TLS private key is not password encrypted. config.core.v4alpha.DataSource password = 3 [(udpa.annotations.sensitive) = true]; - // [#not-implemented-hide:] + // The OCSP response to be stapled with this certificate during the handshake. + // The response must be DER-encoded and may only be provided via ``filename`` or + // ``inline_bytes``. The response may pertain to only one certificate. config.core.v4alpha.DataSource ocsp_staple = 4; // [#not-implemented-hide:] @@ -207,7 +209,7 @@ message CertificateValidationContext { ACCEPT_UNTRUSTED = 1; } - reserved 4; + reserved 4, 5; reserved "verify_subject_alt_name"; @@ -317,9 +319,6 @@ message CertificateValidationContext { // `. repeated type.matcher.v4alpha.StringMatcher match_subject_alt_names = 9; - // [#not-implemented-hide:] Must present a signed time-stamped OCSP response. - google.protobuf.BoolValue require_ocsp_staple = 5; - // [#not-implemented-hide:] Must present signed certificate time-stamp. google.protobuf.BoolValue require_signed_certificate_timestamp = 6; diff --git a/envoy/extensions/transport_sockets/tls/v4alpha/tls.proto b/envoy/extensions/transport_sockets/tls/v4alpha/tls.proto index 44963f68..64b312a1 100644 --- a/envoy/extensions/transport_sockets/tls/v4alpha/tls.proto +++ b/envoy/extensions/transport_sockets/tls/v4alpha/tls.proto @@ -53,11 +53,33 @@ message UpstreamTlsContext { google.protobuf.UInt32Value max_session_keys = 4; } -// [#next-free-field: 8] +// [#next-free-field: 9] message DownstreamTlsContext { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext"; + enum OcspStaplePolicy { + // OCSP responses are optional. If an OCSP response is absent + // or expired, the associated certificate will be used for + // connections without an OCSP staple. + LENIENT_STAPLING = 0; + + // OCSP responses are optional. If an OCSP response is absent, + // the associated certificate will be used without an + // OCSP staple. If a response is provided but is expired, + // the associated certificate will not be used for + // subsequent connections. If no suitable certificate is found, + // the connection is rejected. + STRICT_STAPLING = 1; + + // OCSP responses are required. Configuration will fail if + // a certificate is provided without an OCSP response. If a + // response expires, the associated certificate will not be + // used connections. If no suitable certificate is found, the + // connection is rejected. + MUST_STAPLE = 2; + } + // Common TLS context settings. CommonTlsContext common_tls_context = 1; @@ -95,6 +117,11 @@ message DownstreamTlsContext { lt {seconds: 4294967296} gte {} }]; + + // Config for whether to use certificates if they do not have + // an accompanying OCSP response or if the response expires at runtime. + // Defaults to LENIENT_STAPLING + OcspStaplePolicy ocsp_staple_policy = 8 [(validate.rules).enum = {defined_only: true}]; } // TLS context shared by both client and server TLS contexts.