tls: Account for a change in BoringSSL verify depth semantics (#31287)

Prior to OpenSSL 1.1.0, the certificate depth limit in OpenSSL omitted
the leaf but included the trust anchor. That is, if your chain was Leaf,
Intermediate, Root, any depth limit of 2 or more allowed the
certificate.

OpenSSL 1.1.0 included d9b8b89bec4480de3a10bdaf9425db371c19145b, which
was described as a cleanup change to X509_verify_cert. However, this
change the semantics of the depth limit to omit *both* the leaf and
trust anchor. So the example above was accepted also at depth limit 1.
This is also why common.proto had a comment about different semantics
between the libraries.

BoringSSL originally forked a little before 1.0.2, so it had the older
OpenSSL behavior. Now that the new behavior has been in OpenSSL upstream
for a while, BoringSSL plans to match the new behavior in
https://boringssl-review.googlesource.com/c/boringssl/+/64707/

This change makes Envoy compatible with BoringSSLs before and after that
change. When BORINGSSL_API_VERSION is new enough, we adjust the value
before passing it in, to preserve the original semantics. I'm assuming
here that Envoy would prefer to maintain its existing semantics, rather
than change the test expectation. I've also removed the comment about
backend-specific behavior difference. Supposing Envoy prefers to
maintain existing semantics, any OpenSSL port of Envoy should similarly
adjust the value on OpenSSL 1.1.0 and up.

Along the way, fix an overflow. maxVerifyDepth is a uint32_t, but the
OpenSSL API takes an int. When we exceed INT_MAX, saturate the cast.

Signed-off-by: David Benjamin <davidben@google.com>

Mirrored from https://github.com/envoyproxy/envoy @ f7ef1eeca94f714f0d48af3dd8a43757dc63d770
main
update-envoy[bot] 1 year ago
parent 674de4c962
commit dd03497769
  1. 10
      envoy/extensions/transport_sockets/tls/v3/common.proto

@ -536,12 +536,10 @@ message CertificateValidationContext {
bool only_verify_leaf_cert_crl = 14;
// Defines maximum depth of a certificate chain accepted in verification, the default limit is 100, though this can be system-dependent.
// This number does not include the leaf, so a depth of 1 allows the leaf and one CA certificate. If a trusted issuer appears in the chain,
// but in a depth larger than configured, the certificate validation will fail.
// See `BoringSSL SSL_CTX_set_verify_depth <https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_verify_depth>`_
// If you use OpenSSL, its behavior is different from BoringSSL, this will define a limit on the number of certificates between the end-entity and trust-anchor certificates.
// Neither the end-entity nor the trust-anchor certificates count against depth.
// See `OpenSSL SSL set_verify_depth <https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_verify_depth.html>`_.
// This number does not include the leaf but includes the trust anchor, so a depth of 1 allows the leaf and one CA certificate. If a trusted issuer
// appears in the chain, but in a depth larger than configured, the certificate validation will fail.
// This matches the semantics of ``SSL_CTX_set_verify_depth`` in OpenSSL 1.0.x and older versions of BoringSSL. It differs from ``SSL_CTX_set_verify_depth``
// in OpenSSL 1.1.x and newer versions of BoringSSL in that the trust anchor is included.
// Trusted issues are specified by setting :ref:`trusted_ca <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.trusted_ca>`
google.protobuf.UInt32Value max_verify_depth = 16 [(validate.rules).uint32 = {lte: 100}];
}

Loading…
Cancel
Save