@@ -81,7 +81,7 @@ func (cfg *Config) GetCertificateWithContext(ctx context.Context, clientHello *t
81
81
}
82
82
83
83
// get the certificate and serve it up
84
- cert , err := cfg .getCertDuringHandshake (ctx , clientHello , true , true )
84
+ cert , err := cfg .getCertDuringHandshake (ctx , clientHello , true )
85
85
86
86
return & cert .Certificate , err
87
87
}
@@ -253,19 +253,19 @@ func DefaultCertificateSelector(hello *tls.ClientHelloInfo, choices []Certificat
253
253
// An error will be returned if and only if no certificate is available.
254
254
//
255
255
// This function is safe for concurrent use.
256
- func (cfg * Config ) getCertDuringHandshake (ctx context.Context , hello * tls.ClientHelloInfo , loadIfNecessary , obtainIfNecessary bool ) (Certificate , error ) {
257
- log := logWithRemote (cfg .Logger .Named ("handshake" ), hello )
256
+ func (cfg * Config ) getCertDuringHandshake (ctx context.Context , hello * tls.ClientHelloInfo , loadOrObtainIfNecessary bool ) (Certificate , error ) {
257
+ logger := logWithRemote (cfg .Logger .Named ("handshake" ), hello )
258
258
name := cfg .getNameFromClientHello (hello )
259
259
260
260
// First check our in-memory cache to see if we've already loaded it
261
261
cert , matched , defaulted := cfg .getCertificateFromCache (hello )
262
262
if matched {
263
- log .Debug ("matched certificate in cache" ,
263
+ logger .Debug ("matched certificate in cache" ,
264
264
zap .Strings ("subjects" , cert .Names ),
265
265
zap .Bool ("managed" , cert .managed ),
266
266
zap .Time ("expiration" , expiresAt (cert .Leaf )),
267
267
zap .String ("hash" , cert .hash ))
268
- if cert .managed && cfg .OnDemand != nil && obtainIfNecessary {
268
+ if cert .managed && cfg .OnDemand != nil && loadOrObtainIfNecessary {
269
269
// On-demand certificates are maintained in the background, but
270
270
// maintenance is triggered by handshakes instead of by a timer
271
271
// as in maintain.go.
@@ -294,7 +294,7 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client
294
294
timeout .Stop ()
295
295
}
296
296
297
- return cfg .getCertDuringHandshake (ctx , hello , false , false )
297
+ return cfg .getCertDuringHandshake (ctx , hello , false )
298
298
} else {
299
299
// no other goroutine is currently trying to load this cert
300
300
wait = make (chan struct {})
@@ -319,7 +319,7 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client
319
319
320
320
// If an external Manager is configured, try to get it from them.
321
321
// Only continue to use our own logic if it returns empty+nil.
322
- externalCert , err := cfg .getCertFromAnyCertManager (ctx , hello , log )
322
+ externalCert , err := cfg .getCertFromAnyCertManager (ctx , hello , logger )
323
323
if err != nil {
324
324
return Certificate {}, err
325
325
}
@@ -345,45 +345,45 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client
345
345
cacheAlmostFull := cacheCapacity > 0 && float64 (cacheSize ) >= cacheCapacity * .9
346
346
loadDynamically := cfg .OnDemand != nil || cacheAlmostFull
347
347
348
- if loadDynamically && loadIfNecessary {
348
+ if loadDynamically && loadOrObtainIfNecessary {
349
349
// Check to see if we have one on disk
350
- loadedCert , err := cfg .loadCertFromStorage (ctx , log , hello )
350
+ loadedCert , err := cfg .loadCertFromStorage (ctx , logger , hello )
351
351
if err == nil {
352
352
return loadedCert , nil
353
353
}
354
- log .Debug ("did not load cert from storage" ,
354
+ logger .Debug ("did not load cert from storage" ,
355
355
zap .String ("server_name" , hello .ServerName ),
356
356
zap .Error (err ))
357
357
if cfg .OnDemand != nil {
358
358
// By this point, we need to ask the CA for a certificate
359
359
return cfg .obtainOnDemandCertificate (ctx , hello )
360
360
}
361
+ return loadedCert , nil
361
362
}
362
363
363
364
// Fall back to another certificate if there is one (either DefaultServerName or FallbackServerName)
364
365
if defaulted {
365
- log .Debug ("fell back to other certificate" ,
366
+ logger .Debug ("fell back to default certificate" ,
366
367
zap .Strings ("subjects" , cert .Names ),
367
368
zap .Bool ("managed" , cert .managed ),
368
369
zap .Time ("expiration" , expiresAt (cert .Leaf )),
369
370
zap .String ("hash" , cert .hash ))
370
371
return cert , nil
371
372
}
372
373
373
- log .Debug ("no certificate matching TLS ClientHello" ,
374
+ logger .Debug ("no certificate matching TLS ClientHello" ,
374
375
zap .String ("server_name" , hello .ServerName ),
375
376
zap .String ("remote" , hello .Conn .RemoteAddr ().String ()),
376
377
zap .String ("identifier" , name ),
377
378
zap .Uint16s ("cipher_suites" , hello .CipherSuites ),
378
379
zap .Float64 ("cert_cache_fill" , float64 (cacheSize )/ cacheCapacity ), // may be approximate! because we are not within the lock
379
- zap .Bool ("load_if_necessary" , loadIfNecessary ),
380
- zap .Bool ("obtain_if_necessary" , obtainIfNecessary ),
380
+ zap .Bool ("load_or_obtain_if_necessary" , loadOrObtainIfNecessary ),
381
381
zap .Bool ("on_demand" , cfg .OnDemand != nil ))
382
382
383
383
return Certificate {}, fmt .Errorf ("no certificate available for '%s'" , name )
384
384
}
385
385
386
- func (cfg * Config ) loadCertFromStorage (ctx context.Context , log * zap.Logger , hello * tls.ClientHelloInfo ) (Certificate , error ) {
386
+ func (cfg * Config ) loadCertFromStorage (ctx context.Context , logger * zap.Logger , hello * tls.ClientHelloInfo ) (Certificate , error ) {
387
387
name := normalizedName (hello .ServerName )
388
388
loadedCert , err := cfg .CacheManagedCertificate (ctx , name )
389
389
if errors .Is (err , fs .ErrNotExist ) {
@@ -395,14 +395,14 @@ func (cfg *Config) loadCertFromStorage(ctx context.Context, log *zap.Logger, hel
395
395
if err != nil {
396
396
return Certificate {}, fmt .Errorf ("no matching certificate to load for %s: %w" , name , err )
397
397
}
398
- log .Debug ("loaded certificate from storage" ,
398
+ logger .Debug ("loaded certificate from storage" ,
399
399
zap .Strings ("subjects" , loadedCert .Names ),
400
400
zap .Bool ("managed" , loadedCert .managed ),
401
401
zap .Time ("expiration" , expiresAt (loadedCert .Leaf )),
402
402
zap .String ("hash" , loadedCert .hash ))
403
403
loadedCert , err = cfg .handshakeMaintenance (ctx , hello , loadedCert )
404
404
if err != nil {
405
- log .Error ("maintaining newly-loaded certificate" ,
405
+ logger .Error ("maintaining newly-loaded certificate" ,
406
406
zap .String ("server_name" , name ),
407
407
zap .Error (err ))
408
408
}
@@ -465,10 +465,6 @@ func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.Cli
465
465
466
466
name := cfg .getNameFromClientHello (hello )
467
467
468
- getCertWithoutReobtaining := func () (Certificate , error ) {
469
- return cfg .loadCertFromStorage (ctx , log , hello )
470
- }
471
-
472
468
// We must protect this process from happening concurrently, so synchronize.
473
469
obtainCertWaitChansMu .Lock ()
474
470
wait , ok := obtainCertWaitChans [name ]
@@ -486,7 +482,7 @@ func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.Cli
486
482
timeout .Stop ()
487
483
}
488
484
489
- return getCertWithoutReobtaining ( )
485
+ return cfg . loadCertFromStorage ( ctx , log , hello )
490
486
}
491
487
492
488
// looks like it's up to us to do all the work and obtain the cert.
@@ -525,7 +521,7 @@ func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.Cli
525
521
526
522
// success; certificate was just placed on disk, so
527
523
// we need only restart serving the certificate
528
- return getCertWithoutReobtaining ( )
524
+ return cfg . loadCertFromStorage ( ctx , log , hello )
529
525
}
530
526
531
527
// handshakeMaintenance performs a check on cert for expiration and OCSP validity.
@@ -613,10 +609,6 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
613
609
timeLeft := time .Until (expiresAt (currentCert .Leaf ))
614
610
revoked := currentCert .ocsp != nil && currentCert .ocsp .Status == ocsp .Revoked
615
611
616
- getCertWithoutReobtaining := func () (Certificate , error ) {
617
- return cfg .loadCertFromStorage (ctx , log , hello )
618
- }
619
-
620
612
// see if another goroutine is already working on this certificate
621
613
obtainCertWaitChansMu .Lock ()
622
614
wait , ok := obtainCertWaitChans [name ]
@@ -651,7 +643,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
651
643
timeout .Stop ()
652
644
}
653
645
654
- return getCertWithoutReobtaining ( )
646
+ return cfg . loadCertFromStorage ( ctx , log , hello )
655
647
}
656
648
657
649
// looks like it's up to us to do all the work and renew the cert
@@ -726,7 +718,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
726
718
return newCert , err
727
719
}
728
720
729
- return getCertWithoutReobtaining ( )
721
+ return cfg . loadCertFromStorage ( ctx , log , hello )
730
722
}
731
723
732
724
// if the certificate hasn't expired, we can serve what we have and renew in the background
@@ -744,20 +736,20 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
744
736
// getCertFromAnyCertManager gets a certificate from cfg's Managers. If there are no Managers defined, this is
745
737
// a no-op that returns empty values. Otherwise, it gets a certificate for hello from the first Manager that
746
738
// returns a certificate and no error.
747
- func (cfg * Config ) getCertFromAnyCertManager (ctx context.Context , hello * tls.ClientHelloInfo , log * zap.Logger ) (Certificate , error ) {
739
+ func (cfg * Config ) getCertFromAnyCertManager (ctx context.Context , hello * tls.ClientHelloInfo , logger * zap.Logger ) (Certificate , error ) {
748
740
// fast path if nothing to do
749
- if len (cfg .Managers ) == 0 {
741
+ if cfg . OnDemand == nil || len (cfg . OnDemand .Managers ) == 0 {
750
742
return Certificate {}, nil
751
743
}
752
744
753
745
var upstreamCert * tls.Certificate
754
746
755
747
// try all the GetCertificate methods on external managers; use first one that returns a certificate
756
- for i , certManager := range cfg .Managers {
748
+ for i , certManager := range cfg .OnDemand . Managers {
757
749
var err error
758
750
upstreamCert , err = certManager .GetCertificate (ctx , hello )
759
751
if err != nil {
760
- log .Error ("getting certificate from external certificate manager" ,
752
+ logger .Error ("getting certificate from external certificate manager" ,
761
753
zap .String ("sni" , hello .ServerName ),
762
754
zap .Int ("cert_manager" , i ),
763
755
zap .Error (err ))
@@ -768,7 +760,7 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli
768
760
}
769
761
}
770
762
if upstreamCert == nil {
771
- log .Debug ("all external certificate managers yielded no certificates and no errors" , zap .String ("sni" , hello .ServerName ))
763
+ logger .Debug ("all external certificate managers yielded no certificates and no errors" , zap .String ("sni" , hello .ServerName ))
772
764
return Certificate {}, nil
773
765
}
774
766
@@ -778,7 +770,7 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli
778
770
return Certificate {}, fmt .Errorf ("external certificate manager: %s: filling cert from leaf: %v" , hello .ServerName , err )
779
771
}
780
772
781
- log .Debug ("using externally-managed certificate" ,
773
+ logger .Debug ("using externally-managed certificate" ,
782
774
zap .String ("sni" , hello .ServerName ),
783
775
zap .Strings ("names" , cert .Names ),
784
776
zap .Time ("expiration" , expiresAt (cert .Leaf )))
0 commit comments