Return error if cert manager returns error

Don't try to issue certificate. If a cert manager returns an error, it indicates that
it was supposed to be able to get a cert for that
name but was unable to do so.
This commit is contained in:
Matthew Holt 2024-04-12 10:09:24 -06:00
parent 7681257d05
commit aa4d957707
No known key found for this signature in database
GPG Key ID: 2A349DD577D586A5
2 changed files with 15 additions and 10 deletions

View File

@ -348,9 +348,12 @@ type Revoker interface {
type Manager interface {
// GetCertificate returns the certificate to use to complete the handshake.
// Since this is called during every TLS handshake, it must be very fast and not block.
// Returning (nil, nil) is valid and is simply treated as a no-op. Return (nil, nil)
// when the Manager has no certificate for this handshake. Return an error or a
// certificate only if the Manager is supposed to get a certificate for this handshake.
// Returning any non-nil value indicates that this Manager manages a certificate
// for the described handshake. Returning (nil, nil) is valid and is simply treated as
// a no-op Return (nil, nil) when the Manager has no certificate for this handshake.
// Return an error or a certificate only if the Manager is supposed to get a certificate
// for this handshake. Returning (nil, nil) other Managers or Issuers to try to get
// a certificate for the handshake.
GetCertificate(context.Context, *tls.ClientHelloInfo) (*tls.Certificate, error)
}

View File

@ -752,16 +752,16 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli
return Certificate{}, nil
}
var upstreamCert *tls.Certificate
// try all the GetCertificate methods on external managers; use first one that returns a certificate
var upstreamCert *tls.Certificate
var err error
for i, certManager := range cfg.OnDemand.Managers {
var err error
upstreamCert, err = certManager.GetCertificate(ctx, hello)
if err != nil {
logger.Error("getting certificate from external certificate manager",
logger.Error("external certificate manager",
zap.String("sni", hello.ServerName),
zap.Int("cert_manager", i),
zap.String("cert_manager", fmt.Sprintf("%T", certManager)),
zap.Int("cert_manager_idx", i),
zap.Error(err))
continue
}
@ -769,14 +769,16 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli
break
}
}
if err != nil {
return Certificate{}, fmt.Errorf("external certificate manager indicated that it is unable to yield certificate: %v", err)
}
if upstreamCert == nil {
logger.Debug("all external certificate managers yielded no certificates and no errors", zap.String("sni", hello.ServerName))
return Certificate{}, nil
}
var cert Certificate
err := fillCertFromLeaf(&cert, *upstreamCert)
if err != nil {
if err = fillCertFromLeaf(&cert, *upstreamCert); err != nil {
return Certificate{}, fmt.Errorf("external certificate manager: %s: filling cert from leaf: %v", hello.ServerName, err)
}