@@ -34,6 +34,8 @@ func init() {
3434type 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.
7890func (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
111149var (
112150 _ caddy.Provisioner = (* PKI )(nil )
0 commit comments