Skip to content

Commit a84d9ea

Browse files
committed
Define more errors
1 parent d2a7286 commit a84d9ea

2 files changed

Lines changed: 17 additions & 5 deletions

File tree

handshake.go

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

34+
var (
35+
// ErrCertNotAvailable is returned when no certificates are available for given name.
36+
ErrCertNotAvailable = errors.New("no certificates available")
37+
// ErrCertTimeout is returned when obtaining a certificate times out.
38+
ErrCertTimeout = errors.New("certificate timeout")
39+
)
40+
3441
// GetCertificate gets a certificate to satisfy clientHello. In getting
3542
// the certificate, it abides the rules and settings defined in the Config
3643
// that matches clientHello.ServerName. It tries to get certificates in
@@ -238,7 +245,7 @@ func DefaultCertificateSelector(hello *tls.ClientHelloInfo, choices []Certificat
238245
return choices[0], nil
239246
}
240247
if len(choices) == 0 {
241-
return Certificate{}, fmt.Errorf("no certificates available")
248+
return Certificate{}, ErrCertNotAvailable
242249
}
243250

244251
// Slow path: There are choices, so we need to check each of them.
@@ -306,7 +313,7 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client
306313
timeout := time.NewTimer(2 * time.Minute)
307314
select {
308315
case <-timeout.C:
309-
return Certificate{}, fmt.Errorf("timed out waiting to load certificate for %s", name)
316+
return Certificate{}, fmt.Errorf("%w: timed out waiting to load certificate for %s", ErrCertTimeout, name)
310317
case <-ctx.Done():
311318
timeout.Stop()
312319
return Certificate{}, ctx.Err()
@@ -401,7 +408,7 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client
401408
zap.Bool("load_or_obtain_if_necessary", loadOrObtainIfNecessary),
402409
zap.Bool("on_demand", cfg.OnDemand != nil))
403410

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

407414
// loadCertFromStorage loads the certificate for name from storage and maintains it
@@ -476,7 +483,7 @@ func (cfg *Config) checkIfCertShouldBeObtained(ctx context.Context, name string,
476483
}
477484
if len(cfg.OnDemand.hostAllowlist) > 0 {
478485
if _, ok := cfg.OnDemand.hostAllowlist[name]; !ok {
479-
return fmt.Errorf("certificate for '%s' is not managed", name)
486+
return fmt.Errorf("%w: certificate for '%s' is not managed", ErrCertNotAvailable, name)
480487
}
481488
}
482489
}
@@ -511,7 +518,7 @@ func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.Cli
511518
timeout := time.NewTimer(2 * time.Minute)
512519
select {
513520
case <-timeout.C:
514-
return Certificate{}, fmt.Errorf("timed out waiting to obtain certificate for %s", name)
521+
return Certificate{}, fmt.Errorf("%w: timed out waiting to obtain certificate for %s", ErrCertTimeout, name)
515522
case <-wait:
516523
timeout.Stop()
517524
}

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)