diff options
author | Matthew Holt <[email protected]> | 2020-05-26 15:52:32 -0600 |
---|---|---|
committer | Matthew Holt <[email protected]> | 2020-05-26 15:52:53 -0600 |
commit | 294910c68c315af41f4f47ec6c767fbe318c0e43 (patch) | |
tree | 706c4d532b1b81902cf9a0bf978bd61bd98e8781 /modules/caddyhttp/replacer.go | |
parent | 8c5d00b2bc815c182e1a510be6dddc128949bf23 (diff) | |
download | caddy-294910c68c315af41f4f47ec6c767fbe318c0e43.tar.gz caddy-294910c68c315af41f4f47ec6c767fbe318c0e43.zip |
caddyhttp: Add client.public_key(_sha256) placeholders
Diffstat (limited to 'modules/caddyhttp/replacer.go')
-rw-r--r-- | modules/caddyhttp/replacer.go | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/modules/caddyhttp/replacer.go b/modules/caddyhttp/replacer.go index 670b2e3ea..37b53d273 100644 --- a/modules/caddyhttp/replacer.go +++ b/modules/caddyhttp/replacer.go @@ -16,9 +16,14 @@ package caddyhttp import ( "context" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" + "crypto/rsa" "crypto/sha256" "crypto/tls" "crypto/x509" + "encoding/asn1" "fmt" "net" "net/http" @@ -243,6 +248,18 @@ func getReqTLSReplacement(req *http.Request, key string) (interface{}, bool) { switch field { case "client.fingerprint": return fmt.Sprintf("%x", sha256.Sum256(cert.Raw)), true + case "client.public_key", "client.public_key_sha256": + if cert.PublicKey == nil { + return nil, true + } + pubKeyBytes, err := marshalPublicKey(cert.PublicKey) + if err != nil { + return nil, true + } + if strings.HasSuffix(field, "_sha256") { + return fmt.Sprintf("%x", sha256.Sum256(pubKeyBytes)), true + } + return fmt.Sprintf("%x", pubKeyBytes), true case "client.issuer": return cert.Issuer, true case "client.serial": @@ -271,6 +288,19 @@ func getReqTLSReplacement(req *http.Request, key string) (interface{}, bool) { return nil, false } +// marshalPublicKey returns the byte encoding of pubKey. +func marshalPublicKey(pubKey interface{}) ([]byte, error) { + switch key := pubKey.(type) { + case *rsa.PublicKey: + return asn1.Marshal(key) + case *ecdsa.PublicKey: + return elliptic.Marshal(key.Curve, key.X, key.Y), nil + case ed25519.PublicKey: + return key, nil + } + return nil, fmt.Errorf("unrecognized public key type: %T", pubKey) +} + // getTLSPeerCert retrieves the first peer certificate from a TLS session. // Returns nil if no peer cert is in use. func getTLSPeerCert(cs *tls.ConnectionState) *x509.Certificate { |