@marcel91200 / caddy Mirror · read-only / commits / 9b4acc24
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 12, 08:15 UTC

caddytls: Support new tls.context module (#6369)

* caddytls: Support new tls.context module This allows modules to manipulate the context passed into CertMagic's GetCertificate function, which can be useful for tracing/metrics, or other custom logic. This is experimental and may resolve the request of a sponsor, so we'll see how it goes! * Derpy derp

Matt Holt committed Oct 1, 2024 at 17:18 UTC 9b4acc2449b10ff7c32eff4ddf1838cd2d93c9cf
1 file changed +36 -2
modules/caddytls/connpolicy.go
+36 -2
@@ -15,6 +15,7 @@
15 package caddytls
16
17 import (
18 + "context"
19 "crypto/tls"
20 "crypto/x509"
21 "encoding/base64"
@@ -78,6 +79,14 @@ func (cp ConnectionPolicies) Provision(ctx caddy.Context) error {
79 cp[i].ClientAuthentication.verifiers = append(cp[i].ClientAuthentication.verifiers, validator.(ClientCertificateVerifier))
80 }
81 }
82 +
83 + if len(pol.HandshakeContextRaw) > 0 {
84 + modIface, err := ctx.LoadModule(pol, "HandshakeContextRaw")
85 + if err != nil {
86 + return fmt.Errorf("loading handshake context module: %v", err)
87 + }
88 + cp[i].handshakeContext = modIface.(HandshakeContext)
89 + }
90 }
91
92 return nil
@@ -137,6 +146,7 @@ type ConnectionPolicy struct {
146 // How to match this policy with a TLS ClientHello. If
147 // this policy is the first to match, it will be used.
148 MatchersRaw caddy.ModuleMap `json:"match,omitempty" caddy:"namespace=tls.handshake_match"`
149 + matchers []ConnectionMatcher
150
151 // How to choose a certificate if more than one matched
152 // the given ServerName (SNI) value.
@@ -192,6 +202,12 @@ type ConnectionPolicy struct {
202 // This feature is EXPERIMENTAL and subject to change or removal.
203 InsecureSecretsLog string `json:"insecure_secrets_log,omitempty"`
204
205 + // A module that can manipulate the context passed into CertMagic's
206 + // certificate management functions during TLS handshakes.
207 + // EXPERIMENTAL - subject to change or removal.
208 + HandshakeContextRaw json.RawMessage `json:"handshake_context,omitempty" caddy:"namespace=tls.context inline_key=module"`
209 + handshakeContext HandshakeContext
210 +
211 // TLSConfig is the fully-formed, standard lib TLS config
212 // used to serve TLS connections. Provision all
213 // ConnectionPolicies to populate this. It is exported only
@@ -199,8 +215,15 @@ type ConnectionPolicy struct {
215 // if necessary (like to adjust NextProtos to disable HTTP/2),
216 // and may be unexported in the future.
217 TLSConfig *tls.Config `json:"-"`
218 +}
219
203 - matchers []ConnectionMatcher
220 +type HandshakeContext interface {
221 + // HandshakeContext returns a context to pass into CertMagic's
222 + // GetCertificate function used to serve, load, and manage certs
223 + // during TLS handshakes. Generally you'll start with the context
224 + // from the ClientHelloInfo, but you may use other information
225 + // from it as well. Return an error to abort the handshake.
226 + HandshakeContext(*tls.ClientHelloInfo) (context.Context, error)
227 }
228
229 func (p *ConnectionPolicy) buildStandardTLSConfig(ctx caddy.Context) error {
@@ -240,7 +263,18 @@ func (p *ConnectionPolicy) buildStandardTLSConfig(ctx caddy.Context) error {
263 }
264 cfg.DefaultServerName = p.DefaultSNI
265 cfg.FallbackServerName = p.FallbackSNI
243 - return cfg.GetCertificate(hello)
266 +
267 + // TODO: experimental: if a handshake context module is configured, allow it
268 + // to modify the context before passing it into CertMagic's GetCertificate
269 + ctx := hello.Context()
270 + if p.handshakeContext != nil {
271 + ctx, err = p.handshakeContext.HandshakeContext(hello)
272 + if err != nil {
273 + return nil, fmt.Errorf("handshake context: %v", err)
274 + }
275 + }
276 +
277 + return cfg.GetCertificateWithContext(ctx, hello)
278 },
279 MinVersion: tls.VersionTLS12,
280 MaxVersion: tls.VersionTLS13,