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,