Skip to content

Commit c04d24c

Browse files
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
1 parent 81ee34e commit c04d24c

File tree

3 files changed

+59
-20
lines changed

3 files changed

+59
-20
lines changed

modules/caddypki/acmeserver/acmeserver.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ func (ash *Handler) Provision(ctx caddy.Context) error {
102102
return err
103103
}
104104
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
108108
}
109109

110110
database, err := ash.openDatabase()

modules/caddypki/pki.go

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ func init() {
3434
type PKI struct {
3535
// The certificate authorities to manage. Each CA is keyed by an
3636
// 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.
3739
// The default CA ID is "local".
3840
CAs map[string]*CA `json:"certificate_authorities,omitempty"`
3941

@@ -54,26 +56,36 @@ func (p *PKI) Provision(ctx caddy.Context) error {
5456
p.ctx = ctx
5557
p.log = ctx.Logger(p)
5658

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-
6759
for caID, ca := range p.CAs {
6860
err := ca.Provision(ctx, caID, p.log)
6961
if err != nil {
7062
return fmt.Errorf("provisioning CA '%s': %v", caID, err)
7163
}
7264
}
7365

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+
7476
return nil
7577
}
7678

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+
7789
// Start starts the PKI app.
7890
func (p *PKI) Start() error {
7991
// install roots to trust store, if not disabled
@@ -107,6 +119,32 @@ func (p *PKI) Stop() error {
107119
return nil
108120
}
109121

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+
110148
// Interface guards
111149
var (
112150
_ caddy.Provisioner = (*PKI)(nil)

modules/caddytls/internalissuer.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"context"
2020
"crypto/x509"
2121
"encoding/pem"
22-
"fmt"
2322
"time"
2423

2524
"github.com/caddyserver/caddy/v2"
@@ -68,18 +67,20 @@ func (InternalIssuer) CaddyModule() caddy.ModuleInfo {
6867
func (iss *InternalIssuer) Provision(ctx caddy.Context) error {
6968
iss.logger = ctx.Logger(iss)
7069

70+
// set some defaults
71+
if iss.CA == "" {
72+
iss.CA = caddypki.DefaultCAID
73+
}
74+
7175
// get a reference to the configured CA
7276
appModule, err := ctx.App("pki")
7377
if err != nil {
7478
return err
7579
}
7680
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
8384
}
8485
iss.ca = ca
8586

0 commit comments

Comments
 (0)