NewAuthority returns a new Smallstep-powered signing authority for this CA. Note that we receive *CA (a pointer) in this method to ensure the closure within it, which executes at a later time, always has the only copy of the CA so it can access the latest, renewed certificates since NewAuthority was
(authorityConfig AuthorityConfig)
| 217 | // executes at a later time, always has the only copy of the CA so it can access the latest, |
| 218 | // renewed certificates since NewAuthority was called. See #4517 and #4669. |
| 219 | func (ca *CA) NewAuthority(authorityConfig AuthorityConfig) (*authority.Authority, error) { |
| 220 | // get the root certificate and the issuer cert+key |
| 221 | rootCert := ca.RootCertificate() |
| 222 | |
| 223 | // set up the signer; cert/key which signs the leaf certs |
| 224 | var signerOption authority.Option |
| 225 | if authorityConfig.SignWithRoot { |
| 226 | // if we're signing with root, we can just pass the |
| 227 | // cert/key directly, since it's unlikely to expire |
| 228 | // while Caddy is running (long lifetime) |
| 229 | var issuerCert *x509.Certificate |
| 230 | var issuerKey crypto.Signer |
| 231 | issuerCert = rootCert |
| 232 | var err error |
| 233 | issuerKey, err = ca.RootKey() |
| 234 | if err != nil { |
| 235 | return nil, fmt.Errorf("loading signing key: %v", err) |
| 236 | } |
| 237 | signerOption = authority.WithX509Signer(issuerCert, issuerKey) |
| 238 | } else { |
| 239 | // if we're signing with intermediate, we need to make |
| 240 | // sure it's always fresh, because the intermediate may |
| 241 | // renew while Caddy is running (medium lifetime) |
| 242 | signerOption = authority.WithX509SignerFunc(func() ([]*x509.Certificate, crypto.Signer, error) { |
| 243 | issuerChain := ca.IntermediateCertificateChain() |
| 244 | issuerCert := issuerChain[0] |
| 245 | issuerKey := ca.IntermediateKey() |
| 246 | ca.log.Debug("using intermediate signer", |
| 247 | zap.String("serial", issuerCert.SerialNumber.String()), |
| 248 | zap.String("not_before", issuerCert.NotBefore.String()), |
| 249 | zap.String("not_after", issuerCert.NotAfter.String())) |
| 250 | return issuerChain, issuerKey, nil |
| 251 | }) |
| 252 | } |
| 253 | |
| 254 | opts := []authority.Option{ |
| 255 | authority.WithConfig(&authority.Config{ |
| 256 | AuthorityConfig: authorityConfig.AuthConfig, |
| 257 | }), |
| 258 | signerOption, |
| 259 | authority.WithX509RootCerts(rootCert), |
| 260 | } |
| 261 | |
| 262 | // Add a database if we have one |
| 263 | if authorityConfig.DB != nil { |
| 264 | opts = append(opts, authority.WithDatabase(*authorityConfig.DB)) |
| 265 | } |
| 266 | auth, err := authority.NewEmbedded(opts...) |
| 267 | if err != nil { |
| 268 | return nil, fmt.Errorf("initializing certificate authority: %v", err) |
| 269 | } |
| 270 | |
| 271 | return auth, nil |
| 272 | } |
| 273 | |
| 274 | func (ca CA) loadOrGenRoot() (rootCert *x509.Certificate, rootKey crypto.Signer, err error) { |
| 275 | if ca.Root != nil { |
no test coverage detected