summaryrefslogtreecommitdiff
path: root/modules/caddytls
diff options
context:
space:
mode:
authorevtr <eva@kvalitetsit.dk>2020-03-08 16:48:25 +0100
committerGitHub <noreply@github.com>2020-03-08 09:48:25 -0600
commitca6e54bbb8ab2bad3cc9192bd4857be7e9501c6c (patch)
tree41fc43f8351419113ee9e70be6c63632ebfc4e28 /modules/caddytls
parentfb5168d3b42a368925dad05b9678837990416260 (diff)
caddytls: customizable client auth modes (#2913)
* ability to specify that client cert must be present in SSL * changed the clientauthtype to string and make room for the values supported by go as in caddy1 * renamed the config parameter according to review comments and added documentation on allowed values * missed a reference * Minor cleanup; docs enhancements Co-authored-by: Matthew Holt <mholt@users.noreply.github.com>
Diffstat (limited to 'modules/caddytls')
-rw-r--r--modules/caddytls/connpolicy.go43
1 files changed, 37 insertions, 6 deletions
diff --git a/modules/caddytls/connpolicy.go b/modules/caddytls/connpolicy.go
index 9c61c72..5b830f9 100644
--- a/modules/caddytls/connpolicy.go
+++ b/modules/caddytls/connpolicy.go
@@ -276,6 +276,20 @@ type ClientAuthentication struct {
// which are not in this list will be rejected.
TrustedLeafCerts []string `json:"trusted_leaf_certs,omitempty"`
+ // The mode for authenticating the client. Allowed values are:
+ //
+ // Mode | Description
+ // -----|---------------
+ // `request` | Ask clients for a certificate, but allow even if there isn't one; do not verify it
+ // `require` | Require clients to present a certificate, but do not verify it
+ // `verify_if_given` | Ask clients for a certificate; allow even if there isn't one, but verify it if there is
+ // `require_and_verify` | Require clients to present a valid certificate that is verified
+ //
+ // The default mode is `require_and_verify` if any
+ // TrustedCACerts or TrustedLeafCerts are provided;
+ // otherwise, the default mode is `require`.
+ Mode string `json:"mode,omitempty"`
+
// state established with the last call to ConfigureTLSConfig
trustedLeafCerts []*x509.Certificate
existingVerifyPeerCert func([][]byte, [][]*x509.Certificate) error
@@ -283,7 +297,7 @@ type ClientAuthentication struct {
// Active returns true if clientauth has an actionable configuration.
func (clientauth ClientAuthentication) Active() bool {
- return len(clientauth.TrustedCACerts) > 0 || len(clientauth.TrustedLeafCerts) > 0
+ return len(clientauth.TrustedCACerts) > 0 || len(clientauth.TrustedLeafCerts) > 0 || len(clientauth.Mode) > 0
}
// ConfigureTLSConfig sets up cfg to enforce clientauth's configuration.
@@ -294,8 +308,28 @@ func (clientauth *ClientAuthentication) ConfigureTLSConfig(cfg *tls.Config) erro
return nil
}
- // otherwise, at least require any client certificate
- cfg.ClientAuth = tls.RequireAnyClientCert
+ // enforce desired mode of client authentication
+ if len(clientauth.Mode) > 0 {
+ switch clientauth.Mode {
+ case "request":
+ cfg.ClientAuth = tls.RequestClientCert
+ case "require":
+ cfg.ClientAuth = tls.RequireAnyClientCert
+ case "verify_if_given":
+ cfg.ClientAuth = tls.VerifyClientCertIfGiven
+ case "require_and_verify":
+ cfg.ClientAuth = tls.RequireAndVerifyClientCert
+ default:
+ return fmt.Errorf("client auth mode %s not allowed", clientauth.Mode)
+ }
+ } else {
+ // otherwise, set a safe default mode
+ if len(clientauth.TrustedCACerts) > 0 || len(clientauth.TrustedLeafCerts) > 0 {
+ cfg.ClientAuth = tls.RequireAndVerifyClientCert
+ } else {
+ cfg.ClientAuth = tls.RequireAnyClientCert
+ }
+ }
// enforce CA verification by adding CA certs to the ClientCAs pool
if len(clientauth.TrustedCACerts) > 0 {
@@ -308,9 +342,6 @@ func (clientauth *ClientAuthentication) ConfigureTLSConfig(cfg *tls.Config) erro
caPool.AddCert(clientCA)
}
cfg.ClientCAs = caPool
-
- // now ensure the standard lib will verify client certificates
- cfg.ClientAuth = tls.RequireAndVerifyClientCert
}
// enforce leaf verification by writing our own verify function