@marcel91200 / caddy Mirror · read-only / commits / b0f8fc7a
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

caddytls: Configure trusted CAs from PEM files (#3882)

Closes #3563

Matt Holt committed Nov 25, 2020 at 10:53 UTC b0f8fc7aaecb9ffc40d75df2a5a114bec3b50c10
1 file changed +24 -5
modules/caddytls/connpolicy.go
+24 -5
@@ -19,6 +19,7 @@ import (
19 "crypto/x509"
20 "encoding/base64"
21 "fmt"
22 + "io/ioutil"
23 "strings"
24
25 "github.com/caddyserver/caddy/v2"
@@ -286,6 +287,12 @@ type ClientAuthentication struct {
287 // these CAs will be rejected.
288 TrustedCACerts []string `json:"trusted_ca_certs,omitempty"`
289
290 + // TrustedCACertPEMFiles is a list of PEM file names
291 + // from which to load certificates of trusted CAs.
292 + // Client certificates which are not signed by any of
293 + // these CA certificates will be rejected.
294 + TrustedCACertPEMFiles []string `json:"trusted_ca_certs_pem_files,omitempty"`
295 +
296 // A list of base64 DER-encoded client leaf certs
297 // to accept. If this list is not empty, client certs
298 // which are not in this list will be rejected.
@@ -301,8 +308,8 @@ type ClientAuthentication struct {
308 // `require_and_verify` | Require clients to present a valid certificate that is verified
309 //
310 // The default mode is `require_and_verify` if any
304 - // TrustedCACerts or TrustedLeafCerts are provided;
305 - // otherwise, the default mode is `require`.
311 + // TrustedCACerts or TrustedCACertPEMFiles or TrustedLeafCerts
312 + // are provided; otherwise, the default mode is `require`.
313 Mode string `json:"mode,omitempty"`
314
315 // state established with the last call to ConfigureTLSConfig
@@ -312,7 +319,10 @@ type ClientAuthentication struct {
319
320 // Active returns true if clientauth has an actionable configuration.
321 func (clientauth ClientAuthentication) Active() bool {
315 - return len(clientauth.TrustedCACerts) > 0 || len(clientauth.TrustedLeafCerts) > 0 || len(clientauth.Mode) > 0
322 + return len(clientauth.TrustedCACerts) > 0 ||
323 + len(clientauth.TrustedCACertPEMFiles) > 0 ||
324 + len(clientauth.TrustedLeafCerts) > 0 ||
325 + len(clientauth.Mode) > 0
326 }
327
328 // ConfigureTLSConfig sets up cfg to enforce clientauth's configuration.
@@ -339,7 +349,9 @@ func (clientauth *ClientAuthentication) ConfigureTLSConfig(cfg *tls.Config) erro
349 }
350 } else {
351 // otherwise, set a safe default mode
342 - if len(clientauth.TrustedCACerts) > 0 || len(clientauth.TrustedLeafCerts) > 0 {
352 + if len(clientauth.TrustedCACerts) > 0 ||
353 + len(clientauth.TrustedCACertPEMFiles) > 0 ||
354 + len(clientauth.TrustedLeafCerts) > 0 {
355 cfg.ClientAuth = tls.RequireAndVerifyClientCert
356 } else {
357 cfg.ClientAuth = tls.RequireAnyClientCert
@@ -347,7 +359,7 @@ func (clientauth *ClientAuthentication) ConfigureTLSConfig(cfg *tls.Config) erro
359 }
360
361 // enforce CA verification by adding CA certs to the ClientCAs pool
350 - if len(clientauth.TrustedCACerts) > 0 {
362 + if len(clientauth.TrustedCACerts) > 0 || len(clientauth.TrustedCACertPEMFiles) > 0 {
363 caPool := x509.NewCertPool()
364 for _, clientCAString := range clientauth.TrustedCACerts {
365 clientCA, err := decodeBase64DERCert(clientCAString)
@@ -356,6 +368,13 @@ func (clientauth *ClientAuthentication) ConfigureTLSConfig(cfg *tls.Config) erro
368 }
369 caPool.AddCert(clientCA)
370 }
371 + for _, pemFile := range clientauth.TrustedCACertPEMFiles {
372 + pemContents, err := ioutil.ReadFile(pemFile)
373 + if err != nil {
374 + return fmt.Errorf("reading %s: %v", pemFile, err)
375 + }
376 + caPool.AppendCertsFromPEM(pemContents)
377 + }
378 cfg.ClientCAs = caPool
379 }
380