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