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, 00:15 UTC
pki: Avoid provisioning the `local` CA when not necessary (#4463)
* pki: Avoid provisioning the `local` CA when not necessary * pki: Refactor CA loading to keep the logic in the PKI app
Francis Lavoie committed
Dec 13, 2021 at 14:25 UTC
c04d24cafa60e522842d5188587ab07af2082e9b
3 files changed
+59
-20
modules/caddypki/acmeserver/acmeserver.go
+3
-3
@@ -102,9 +102,9 @@ func (ash *Handler) Provision(ctx caddy.Context) error {
102
return err
103
}
104
pkiApp := appModule.(*caddypki.PKI)
105
- ca, ok := pkiApp.CAs[ash.CA]
106
- if !ok {
107
- return fmt.Errorf("no certificate authority configured with id: %s", ash.CA)
105
+ ca, err := pkiApp.GetCA(ash.CA, &ctx)
106
+ if err != nil {
107
+ return err
108
}
109
110
database, err := ash.openDatabase()
modules/caddypki/pki.go
+48
-10
@@ -34,6 +34,8 @@ func init() {
34
type PKI struct {
35
// The certificate authorities to manage. Each CA is keyed by an
36
// ID that is used to uniquely identify it from other CAs.
37
+ // At runtime, the GetCA() method should be used instead to ensure
38
+ // the default CA is provisioned if it hadn't already been.
39
// The default CA ID is "local".
40
CAs map[string]*CA `json:"certificate_authorities,omitempty"`
41
@@ -54,16 +56,6 @@ func (p *PKI) Provision(ctx caddy.Context) error {
56
p.ctx = ctx
57
p.log = ctx.Logger(p)
58
57
- // if this app is initialized at all, ensure there's at
58
- // least a default CA that can be used: the standard CA
59
- // which is used implicitly for signing local-use certs
60
- if p.CAs == nil {
61
- p.CAs = make(map[string]*CA)
62
- }
63
- if _, ok := p.CAs[DefaultCAID]; !ok {
64
- p.CAs[DefaultCAID] = new(CA)
65
- }
66
-
59
for caID, ca := range p.CAs {
60
err := ca.Provision(ctx, caID, p.log)
61
if err != nil {
@@ -71,9 +63,29 @@ func (p *PKI) Provision(ctx caddy.Context) error {
63
}
64
}
65
66
+ // if this app is initialized at all, ensure there's at
67
+ // least a default CA that can be used: the standard CA
68
+ // which is used implicitly for signing local-use certs
69
+ if len(p.CAs) == 0 {
70
+ err := p.ProvisionDefaultCA(ctx)
71
+ if err != nil {
72
+ return fmt.Errorf("provisioning CA '%s': %v", DefaultCAID, err)
73
+ }
74
+ }
75
+
76
return nil
77
}
78
79
+// ProvisionDefaultCA sets up the default CA.
80
+func (p *PKI) ProvisionDefaultCA(ctx caddy.Context) error {
81
+ if p.CAs == nil {
82
+ p.CAs = make(map[string]*CA)
83
+ }
84
+
85
+ p.CAs[DefaultCAID] = new(CA)
86
+ return p.CAs[DefaultCAID].Provision(ctx, DefaultCAID, p.log)
87
+}
88
+
89
// Start starts the PKI app.
90
func (p *PKI) Start() error {
91
// install roots to trust store, if not disabled
@@ -107,6 +119,32 @@ func (p *PKI) Stop() error {
119
return nil
120
}
121
122
+// GetCA retrieves a CA by ID. If the ID is the default
123
+// CA ID, and it hasn't been provisioned yet, it will
124
+// be provisioned. The context must be passed if this
125
+// is called from a module's Provision().
126
+func (p *PKI) GetCA(id string, ctx *caddy.Context) (*CA, error) {
127
+ ca, ok := p.CAs[id]
128
+ if !ok {
129
+ // for anything other than the default CA ID, error out if it wasn't configured
130
+ if id != DefaultCAID {
131
+ return nil, fmt.Errorf("no certificate authority configured with id: %s", id)
132
+ }
133
+
134
+ // for the default CA ID, provision it, because we want it to "just work"
135
+ if ctx == nil {
136
+ return nil, fmt.Errorf("cannot provision default CA without the context")
137
+ }
138
+ err := p.ProvisionDefaultCA(*ctx)
139
+ if err != nil {
140
+ return nil, fmt.Errorf("failed to provision default CA: %s", err)
141
+ }
142
+ ca = p.CAs[id]
143
+ }
144
+
145
+ return ca, nil
146
+}
147
+
148
// Interface guards
149
var (
150
_ caddy.Provisioner = (*PKI)(nil)
modules/caddytls/internalissuer.go
+8
-7
@@ -19,7 +19,6 @@ import (
19
"context"
20
"crypto/x509"
21
"encoding/pem"
22
- "fmt"
22
"time"
23
24
"github.com/caddyserver/caddy/v2"
@@ -68,18 +67,20 @@ func (InternalIssuer) CaddyModule() caddy.ModuleInfo {
67
func (iss *InternalIssuer) Provision(ctx caddy.Context) error {
68
iss.logger = ctx.Logger(iss)
69
70
+ // set some defaults
71
+ if iss.CA == "" {
72
+ iss.CA = caddypki.DefaultCAID
73
+ }
74
+
75
// get a reference to the configured CA
76
appModule, err := ctx.App("pki")
77
if err != nil {
78
return err
79
}
80
pkiApp := appModule.(*caddypki.PKI)
77
- if iss.CA == "" {
78
- iss.CA = caddypki.DefaultCAID
79
- }
80
- ca, ok := pkiApp.CAs[iss.CA]
81
- if !ok {
82
- return fmt.Errorf("no certificate authority configured with id: %s", iss.CA)
81
+ ca, err := pkiApp.GetCA(iss.CA, &ctx)
82
+ if err != nil {
83
+ return err
84
}
85
iss.ca = ca
86