Skip to content

Commit 778f3d7

Browse files
committed
Define more errors
1 parent d2a7286 commit 778f3d7

2 files changed

Lines changed: 15 additions & 5 deletions

File tree

handshake.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ import (
3131
"golang.org/x/net/idna"
3232
)
3333

34+
var (
35+
ErrCertNotAvailable = errors.New("no certificates available")
36+
ErrCertTimeout = errors.New("certificate timeout")
37+
)
38+
3439
// GetCertificate gets a certificate to satisfy clientHello. In getting
3540
// the certificate, it abides the rules and settings defined in the Config
3641
// that matches clientHello.ServerName. It tries to get certificates in
@@ -238,7 +243,7 @@ func DefaultCertificateSelector(hello *tls.ClientHelloInfo, choices []Certificat
238243
return choices[0], nil
239244
}
240245
if len(choices) == 0 {
241-
return Certificate{}, fmt.Errorf("no certificates available")
246+
return Certificate{}, ErrCertNotAvailable
242247
}
243248

244249
// Slow path: There are choices, so we need to check each of them.
@@ -306,7 +311,7 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client
306311
timeout := time.NewTimer(2 * time.Minute)
307312
select {
308313
case <-timeout.C:
309-
return Certificate{}, fmt.Errorf("timed out waiting to load certificate for %s", name)
314+
return Certificate{}, fmt.Errorf("%w: timed out waiting to load certificate for %s", ErrCertTimeout, name)
310315
case <-ctx.Done():
311316
timeout.Stop()
312317
return Certificate{}, ctx.Err()
@@ -401,7 +406,7 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client
401406
zap.Bool("load_or_obtain_if_necessary", loadOrObtainIfNecessary),
402407
zap.Bool("on_demand", cfg.OnDemand != nil))
403408

404-
return Certificate{}, fmt.Errorf("no certificate available for '%s'", name)
409+
return Certificate{}, fmt.Errorf("%w: '%s'", ErrCertNotAvailable, name)
405410
}
406411

407412
// loadCertFromStorage loads the certificate for name from storage and maintains it
@@ -476,7 +481,7 @@ func (cfg *Config) checkIfCertShouldBeObtained(ctx context.Context, name string,
476481
}
477482
if len(cfg.OnDemand.hostAllowlist) > 0 {
478483
if _, ok := cfg.OnDemand.hostAllowlist[name]; !ok {
479-
return fmt.Errorf("certificate for '%s' is not managed", name)
484+
return fmt.Errorf("%w: certificate for '%s' is not managed", ErrCertNotAvailable, name)
480485
}
481486
}
482487
}
@@ -511,7 +516,7 @@ func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.Cli
511516
timeout := time.NewTimer(2 * time.Minute)
512517
select {
513518
case <-timeout.C:
514-
return Certificate{}, fmt.Errorf("timed out waiting to obtain certificate for %s", name)
519+
return Certificate{}, fmt.Errorf("%w: timed out waiting to obtain certificate for %s", ErrCertTimeout, name)
515520
case <-wait:
516521
timeout.Stop()
517522
}

handshake_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package certmagic
1616
import (
1717
"crypto/tls"
1818
"crypto/x509"
19+
"errors"
1920
"net"
2021
"testing"
2122
)
@@ -78,6 +79,10 @@ func TestGetCertificate(t *testing.T) {
7879
// When cache is NOT empty but there's no SNI
7980
if _, err := cfg.GetCertificate(helloNoSNI); err == nil {
8081
t.Errorf("Expected TLS allert when no SNI and no DefaultServerName, but got: %v", err)
82+
} else {
83+
if !errors.Is(err, ErrCertNotAvailable) {
84+
t.Errorf("Expected ErrCertNotAvailable, got: %v", err)
85+
}
8186
}
8287

8388
// When no certificate matches, raise an alert

0 commit comments

Comments
 (0)