@marcel91200 / caddy Mirror · read-only / commits / 294910c6
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 14, 05:15 UTC

caddyhttp: Add client.public_key(_sha256) placeholders

Matthew Holt committed May 26, 2020 at 15:52 UTC 294910c68c315af41f4f47ec6c767fbe318c0e43
1 file changed +30
modules/caddyhttp/replacer.go
+30
@@ -16,9 +16,14 @@ package caddyhttp
16
17 import (
18 "context"
19 + "crypto/ecdsa"
20 + "crypto/ed25519"
21 + "crypto/elliptic"
22 + "crypto/rsa"
23 "crypto/sha256"
24 "crypto/tls"
25 "crypto/x509"
26 + "encoding/asn1"
27 "fmt"
28 "net"
29 "net/http"
@@ -243,6 +248,18 @@ func getReqTLSReplacement(req *http.Request, key string) (interface{}, bool) {
248 switch field {
249 case "client.fingerprint":
250 return fmt.Sprintf("%x", sha256.Sum256(cert.Raw)), true
251 + case "client.public_key", "client.public_key_sha256":
252 + if cert.PublicKey == nil {
253 + return nil, true
254 + }
255 + pubKeyBytes, err := marshalPublicKey(cert.PublicKey)
256 + if err != nil {
257 + return nil, true
258 + }
259 + if strings.HasSuffix(field, "_sha256") {
260 + return fmt.Sprintf("%x", sha256.Sum256(pubKeyBytes)), true
261 + }
262 + return fmt.Sprintf("%x", pubKeyBytes), true
263 case "client.issuer":
264 return cert.Issuer, true
265 case "client.serial":
@@ -271,6 +288,19 @@ func getReqTLSReplacement(req *http.Request, key string) (interface{}, bool) {
288 return nil, false
289 }
290
291 +// marshalPublicKey returns the byte encoding of pubKey.
292 +func marshalPublicKey(pubKey interface{}) ([]byte, error) {
293 + switch key := pubKey.(type) {
294 + case *rsa.PublicKey:
295 + return asn1.Marshal(key)
296 + case *ecdsa.PublicKey:
297 + return elliptic.Marshal(key.Curve, key.X, key.Y), nil
298 + case ed25519.PublicKey:
299 + return key, nil
300 + }
301 + return nil, fmt.Errorf("unrecognized public key type: %T", pubKey)
302 +}
303 +
304 // getTLSPeerCert retrieves the first peer certificate from a TLS session.
305 // Returns nil if no peer cert is in use.
306 func getTLSPeerCert(cs *tls.ConnectionState) *x509.Certificate {