• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 13536249039

26 Feb 2025 03:42AM UTC coverage: 57.462% (-1.4%) from 58.835%
13536249039

Pull #8453

github

Roasbeef
peer: update chooseDeliveryScript to gen script if needed

In this commit, we update `chooseDeliveryScript` to generate a new
script if needed. This allows us to fold in a few other lines that
always followed this function into this expanded function.

The tests have been updated accordingly.
Pull Request #8453: [4/4] - multi: integrate new rbf coop close FSM into the existing peer flow

275 of 1318 new or added lines in 22 files covered. (20.86%)

19521 existing lines in 257 files now uncovered.

103858 of 180741 relevant lines covered (57.46%)

24750.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.2
/tls_manager.go
1
package lnd
2

3
import (
4
        "bytes"
5
        "context"
6
        "crypto/tls"
7
        "crypto/x509"
8
        "errors"
9
        "fmt"
10
        "net"
11
        "net/http"
12
        "os"
13
        "time"
14

15
        "github.com/lightningnetwork/lnd/cert"
16
        "github.com/lightningnetwork/lnd/keychain"
17
        "github.com/lightningnetwork/lnd/lncfg"
18
        "github.com/lightningnetwork/lnd/lnencrypt"
19
        "github.com/lightningnetwork/lnd/lnrpc"
20
        "golang.org/x/crypto/acme/autocert"
21
        "google.golang.org/grpc"
22
        "google.golang.org/grpc/credentials"
23
)
24

25
const (
26
        // modifyFilePermissons is the file permission used for writing
27
        // encrypted tls files.
28
        modifyFilePermissions = 0600
29

30
        // validityHours is the number of hours the ephemeral tls certificate
31
        // will be valid, if encrypting tls certificates is turned on.
32
        validityHours = 24
33
)
34

35
var (
36
        // privateKeyPrefix is the prefix to a plaintext TLS key.
37
        // It should match these two key formats:
38
        // - `-----BEGIN PRIVATE KEY-----`    (PKCS8).
39
        // - `-----BEGIN EC PRIVATE KEY-----` (SEC1/rfc5915, the legacy format).
40
        privateKeyPrefix = []byte("-----BEGIN ")
41
)
42

43
// TLSManagerCfg houses a set of values and methods that is passed to the
44
// TLSManager for it to properly manage LND's TLS options.
45
type TLSManagerCfg struct {
46
        TLSCertPath        string
47
        TLSKeyPath         string
48
        TLSEncryptKey      bool
49
        TLSExtraIPs        []string
50
        TLSExtraDomains    []string
51
        TLSAutoRefresh     bool
52
        TLSDisableAutofill bool
53
        TLSCertDuration    time.Duration
54

55
        LetsEncryptDir    string
56
        LetsEncryptDomain string
57
        LetsEncryptListen string
58

59
        DisableRestTLS bool
60

61
        HTTPHeaderTimeout time.Duration
62
}
63

64
// TLSManager generates/renews a TLS cert/key pair when needed. When required,
65
// it encrypts the TLS key. It also returns the certificate configuration
66
// options needed for gRPC and REST.
67
type TLSManager struct {
68
        cfg *TLSManagerCfg
69

70
        // tlsReloader is able to reload the certificate with the
71
        // GetCertificate function. In getConfig, tlsCfg.GetCertificate is
72
        // pointed towards t.tlsReloader.GetCertificateFunc(). When
73
        // TLSReloader's AttemptReload is called, the cert that tlsReloader
74
        // holds is changed, in turn changing the cert data
75
        // tlsCfg.GetCertificate will return.
76
        tlsReloader *cert.TLSReloader
77

78
        // These options are only used if we're currently using an ephemeral
79
        // TLS certificate, used when we're encrypting the TLS key.
80
        ephemeralKey      []byte
81
        ephemeralCert     []byte
82
        ephemeralCertPath string
83
}
84

85
// NewTLSManager returns a reference to a new TLSManager.
86
func NewTLSManager(cfg *TLSManagerCfg) *TLSManager {
5✔
87
        return &TLSManager{
5✔
88
                cfg: cfg,
5✔
89
        }
5✔
90
}
5✔
91

92
// getConfig returns a TLS configuration for the gRPC server and credentials
93
// and a proxy destination for the REST reverse proxy.
94
func (t *TLSManager) getConfig() ([]grpc.ServerOption, []grpc.DialOption,
95
        func(net.Addr) (net.Listener, error), func(), error) {
1✔
96

1✔
97
        var (
1✔
98
                keyBytes, certBytes []byte
1✔
99
                err                 error
1✔
100
        )
1✔
101
        if t.ephemeralKey != nil {
1✔
102
                keyBytes = t.ephemeralKey
×
103
                certBytes = t.ephemeralCert
×
104
        } else {
1✔
105
                certBytes, keyBytes, err = cert.GetCertBytesFromPath(
1✔
106
                        t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
1✔
107
                )
1✔
108
                if err != nil {
1✔
109
                        return nil, nil, nil, nil, err
×
110
                }
×
111
        }
112

113
        certData, _, err := cert.LoadCertFromBytes(certBytes, keyBytes)
1✔
114
        if err != nil {
1✔
115
                return nil, nil, nil, nil, err
×
116
        }
×
117

118
        if t.tlsReloader == nil {
2✔
119
                tlsr, err := cert.NewTLSReloader(certBytes, keyBytes)
1✔
120
                if err != nil {
1✔
121
                        return nil, nil, nil, nil, err
×
122
                }
×
123
                t.tlsReloader = tlsr
1✔
124
        }
125

126
        tlsCfg := cert.TLSConfFromCert(certData)
1✔
127
        tlsCfg.GetCertificate = t.tlsReloader.GetCertificateFunc()
1✔
128

1✔
129
        // If Let's Encrypt is enabled, we need to set up the autocert manager
1✔
130
        // and override the TLS config's GetCertificate function.
1✔
131
        cleanUp := t.setUpLetsEncrypt(&certData, tlsCfg)
1✔
132

1✔
133
        // Now that we know that we have a certificate, let's generate the
1✔
134
        // required config options.
1✔
135
        serverCreds := credentials.NewTLS(tlsCfg)
1✔
136
        serverOpts := []grpc.ServerOption{grpc.Creds(serverCreds)}
1✔
137

1✔
138
        // For our REST dial options, we skip TLS verification, and we also
1✔
139
        // increase the max message size that we'll decode to allow clients to
1✔
140
        // hit endpoints which return more data such as the DescribeGraph call.
1✔
141
        // We set this to 200MiB atm. Should be the same value as maxMsgRecvSize
1✔
142
        // in cmd/lncli/main.go.
1✔
143
        restDialOpts := []grpc.DialOption{
1✔
144
                // We are forwarding the requests directly to the address of our
1✔
145
                // own local listener. To not need to mess with the TLS
1✔
146
                // certificate (which might be tricky if we're using Let's
1✔
147
                // Encrypt or if the ephemeral tls cert is being used), we just
1✔
148
                // skip the certificate verification. Injecting a malicious
1✔
149
                // hostname into the listener address will result in an error
1✔
150
                // on startup so this should be quite safe.
1✔
151
                grpc.WithTransportCredentials(credentials.NewTLS(
1✔
152
                        &tls.Config{InsecureSkipVerify: true},
1✔
153
                )),
1✔
154
                grpc.WithDefaultCallOptions(
1✔
155
                        grpc.MaxCallRecvMsgSize(lnrpc.MaxGrpcMsgSize),
1✔
156
                ),
1✔
157
        }
1✔
158

1✔
159
        // Return a function closure that can be used to listen on a given
1✔
160
        // address with the current TLS config.
1✔
161
        restListen := func(addr net.Addr) (net.Listener, error) {
1✔
UNCOV
162
                // For restListen we will call ListenOnAddress if TLS is
×
UNCOV
163
                // disabled.
×
UNCOV
164
                if t.cfg.DisableRestTLS {
×
165
                        return lncfg.ListenOnAddress(addr)
×
166
                }
×
167

UNCOV
168
                return lncfg.TLSListenOnAddress(addr, tlsCfg)
×
169
        }
170

171
        return serverOpts, restDialOpts, restListen, cleanUp, nil
1✔
172
}
173

174
// generateOrRenewCert generates a new TLS certificate if we're not using one
175
// yet or renews it if it's outdated.
176
func (t *TLSManager) generateOrRenewCert() (*tls.Config, error) {
2✔
177
        // Generete a TLS pair if we don't have one yet.
2✔
178
        var emptyKeyRing keychain.SecretKeyRing
2✔
179
        err := t.generateCertPair(emptyKeyRing)
2✔
180
        if err != nil {
2✔
181
                return nil, err
×
182
        }
×
183

184
        certData, parsedCert, err := cert.LoadCert(
2✔
185
                t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
2✔
186
        )
2✔
187
        if err != nil {
2✔
188
                return nil, err
×
189
        }
×
190

191
        // Check to see if the certificate needs to be renewed. If it does, we
192
        // return the newly generated certificate data instead.
193
        reloadedCertData, err := t.maintainCert(parsedCert)
2✔
194
        if err != nil {
2✔
195
                return nil, err
×
196
        }
×
197
        if reloadedCertData != nil {
4✔
198
                certData = *reloadedCertData
2✔
199
        }
2✔
200

201
        tlsCfg := cert.TLSConfFromCert(certData)
2✔
202

2✔
203
        return tlsCfg, nil
2✔
204
}
205

206
// generateCertPair creates and writes a TLS pair to disk if the pair
207
// doesn't exist yet. If the TLSEncryptKey setting is on, and a plaintext key
208
// is already written to disk, this function overwrites the plaintext key with
209
// the encrypted form.
210
func (t *TLSManager) generateCertPair(keyRing keychain.SecretKeyRing) error {
4✔
211
        // Ensure we create TLS key and certificate if they don't exist.
4✔
212
        if lnrpc.FileExists(t.cfg.TLSCertPath) ||
4✔
213
                lnrpc.FileExists(t.cfg.TLSKeyPath) {
5✔
214

1✔
215
                // Handle discrepencies related to the TLSEncryptKey setting.
1✔
216
                return t.ensureEncryption(keyRing)
1✔
217
        }
1✔
218

219
        rpcsLog.Infof("Generating TLS certificates...")
3✔
220
        certBytes, keyBytes, err := cert.GenCertPair(
3✔
221
                "lnd autogenerated cert", t.cfg.TLSExtraIPs,
3✔
222
                t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill,
3✔
223
                t.cfg.TLSCertDuration,
3✔
224
        )
3✔
225
        if err != nil {
3✔
226
                return err
×
227
        }
×
228

229
        if t.cfg.TLSEncryptKey {
5✔
230
                var b bytes.Buffer
2✔
231
                e, err := lnencrypt.KeyRingEncrypter(keyRing)
2✔
232
                if err != nil {
2✔
233
                        return fmt.Errorf("unable to create "+
×
234
                                "encrypt key %v", err)
×
235
                }
×
236

237
                err = e.EncryptPayloadToWriter(
2✔
238
                        keyBytes, &b,
2✔
239
                )
2✔
240
                if err != nil {
2✔
241
                        return err
×
242
                }
×
243

244
                keyBytes = b.Bytes()
2✔
245
        }
246

247
        err = cert.WriteCertPair(
3✔
248
                t.cfg.TLSCertPath, t.cfg.TLSKeyPath, certBytes, keyBytes,
3✔
249
        )
3✔
250

3✔
251
        rpcsLog.Infof("Done generating TLS certificates")
3✔
252

3✔
253
        return err
3✔
254
}
255

256
// ensureEncryption takes a look at a couple of things:
257
// 1) If the TLS key is in plaintext, but TLSEncryptKey is set, we need to
258
// encrypt the file and rewrite it to disk.
259
// 2) On the flip side, if TLSEncryptKey is not set, but the key on disk
260
// is encrypted, we need to error out and warn the user.
261
func (t *TLSManager) ensureEncryption(keyRing keychain.SecretKeyRing) error {
3✔
262
        _, keyBytes, err := cert.GetCertBytesFromPath(
3✔
263
                t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
3✔
264
        )
3✔
265
        if err != nil {
3✔
266
                return err
×
267
        }
×
268

269
        if t.cfg.TLSEncryptKey && bytes.HasPrefix(keyBytes, privateKeyPrefix) {
4✔
270
                var b bytes.Buffer
1✔
271
                e, err := lnencrypt.KeyRingEncrypter(keyRing)
1✔
272
                if err != nil {
1✔
273
                        return fmt.Errorf("unable to generate encrypt key %w",
×
274
                                err)
×
275
                }
×
276

277
                err = e.EncryptPayloadToWriter(keyBytes, &b)
1✔
278
                if err != nil {
1✔
279
                        return err
×
280
                }
×
281
                err = os.WriteFile(
1✔
282
                        t.cfg.TLSKeyPath, b.Bytes(), modifyFilePermissions,
1✔
283
                )
1✔
284
                if err != nil {
1✔
285
                        return err
×
286
                }
×
287
        }
288

289
        // If the private key is encrypted but the user didn't pass
290
        // --tlsencryptkey we error out. This is because the wallet is not
291
        // unlocked yet and we don't have access to the keys yet for decryption.
292
        if !t.cfg.TLSEncryptKey && !bytes.HasPrefix(keyBytes,
3✔
293
                privateKeyPrefix) {
4✔
294

1✔
295
                ltndLog.Errorf("The TLS private key is encrypted on disk.")
1✔
296

1✔
297
                return errors.New("the TLS key is encrypted but the " +
1✔
298
                        "--tlsencryptkey flag is not passed. Please either " +
1✔
299
                        "restart lnd with the --tlsencryptkey flag or delete " +
1✔
300
                        "the TLS files for regeneration")
1✔
301
        }
1✔
302

303
        return nil
2✔
304
}
305

306
// decryptTLSKeyBytes decrypts the TLS key.
307
func decryptTLSKeyBytes(keyRing keychain.SecretKeyRing,
308
        encryptedData []byte) ([]byte, error) {
×
309

×
310
        reader := bytes.NewReader(encryptedData)
×
311
        encrypter, err := lnencrypt.KeyRingEncrypter(keyRing)
×
312
        if err != nil {
×
313
                return nil, err
×
314
        }
×
315

316
        plaintext, err := encrypter.DecryptPayloadFromReader(
×
317
                reader,
×
318
        )
×
319
        if err != nil {
×
320
                return nil, err
×
321
        }
×
322

323
        return plaintext, nil
×
324
}
325

326
// maintainCert checks if the certificate IP and domains matches the config,
327
// and renews the certificate if either this data is outdated or the
328
// certificate is expired.
329
func (t *TLSManager) maintainCert(
330
        parsedCert *x509.Certificate) (*tls.Certificate, error) {
2✔
331

2✔
332
        // We check whether the certificate we have on disk match the IPs and
2✔
333
        // domains specified by the config. If the extra IPs or domains have
2✔
334
        // changed from when the certificate was created, we will refresh the
2✔
335
        // certificate if auto refresh is active.
2✔
336
        refresh := false
2✔
337
        var err error
2✔
338
        if t.cfg.TLSAutoRefresh {
2✔
339
                refresh, err = cert.IsOutdated(
×
340
                        parsedCert, t.cfg.TLSExtraIPs,
×
341
                        t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill,
×
342
                )
×
343
                if err != nil {
×
344
                        return nil, err
×
345
                }
×
346
        }
347

348
        // If the certificate expired or it was outdated, delete it and the TLS
349
        // key and generate a new pair.
350
        if !time.Now().After(parsedCert.NotAfter) && !refresh {
2✔
UNCOV
351
                return nil, nil
×
UNCOV
352
        }
×
353

354
        ltndLog.Info("TLS certificate is expired or outdated, " +
2✔
355
                "generating a new one")
2✔
356

2✔
357
        err = os.Remove(t.cfg.TLSCertPath)
2✔
358
        if err != nil {
2✔
359
                return nil, err
×
360
        }
×
361

362
        err = os.Remove(t.cfg.TLSKeyPath)
2✔
363
        if err != nil {
2✔
364
                return nil, err
×
365
        }
×
366

367
        rpcsLog.Infof("Renewing TLS certificates...")
2✔
368
        certBytes, keyBytes, err := cert.GenCertPair(
2✔
369
                "lnd autogenerated cert", t.cfg.TLSExtraIPs,
2✔
370
                t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill,
2✔
371
                t.cfg.TLSCertDuration,
2✔
372
        )
2✔
373
        if err != nil {
2✔
374
                return nil, err
×
375
        }
×
376

377
        err = cert.WriteCertPair(
2✔
378
                t.cfg.TLSCertPath, t.cfg.TLSKeyPath, certBytes, keyBytes,
2✔
379
        )
2✔
380
        if err != nil {
2✔
381
                return nil, err
×
382
        }
×
383

384
        rpcsLog.Infof("Done renewing TLS certificates")
2✔
385

2✔
386
        // Reload the certificate data.
2✔
387
        reloadedCertData, _, err := cert.LoadCert(
2✔
388
                t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
2✔
389
        )
2✔
390

2✔
391
        return &reloadedCertData, err
2✔
392
}
393

394
// setUpLetsEncrypt automatically generates a Let's Encrypt certificate if the
395
// option is set.
396
func (t *TLSManager) setUpLetsEncrypt(certData *tls.Certificate,
397
        tlsCfg *tls.Config) func() {
1✔
398

1✔
399
        // If Let's Encrypt is enabled, instantiate autocert to request/renew
1✔
400
        // the certificates.
1✔
401
        cleanUp := func() {}
2✔
402
        if t.cfg.LetsEncryptDomain == "" {
2✔
403
                return cleanUp
1✔
404
        }
1✔
405

406
        ltndLog.Infof("Using Let's Encrypt certificate for domain %v",
×
407
                t.cfg.LetsEncryptDomain)
×
408

×
409
        manager := autocert.Manager{
×
410
                Cache:  autocert.DirCache(t.cfg.LetsEncryptDir),
×
411
                Prompt: autocert.AcceptTOS,
×
412
                HostPolicy: autocert.HostWhitelist(
×
413
                        t.cfg.LetsEncryptDomain,
×
414
                ),
×
415
        }
×
416

×
417
        srv := &http.Server{
×
418
                Addr:              t.cfg.LetsEncryptListen,
×
419
                Handler:           manager.HTTPHandler(nil),
×
420
                ReadHeaderTimeout: t.cfg.HTTPHeaderTimeout,
×
421
        }
×
422
        shutdownCompleted := make(chan struct{})
×
423
        cleanUp = func() {
×
424
                err := srv.Shutdown(context.Background())
×
425
                if err != nil {
×
426
                        ltndLog.Errorf("Autocert listener shutdown "+
×
427
                                " error: %v", err)
×
428

×
429
                        return
×
430
                }
×
431
                <-shutdownCompleted
×
432
                ltndLog.Infof("Autocert challenge listener stopped")
×
433
        }
434

435
        go func() {
×
436
                ltndLog.Infof("Autocert challenge listener started "+
×
437
                        "at %v", t.cfg.LetsEncryptListen)
×
438

×
439
                err := srv.ListenAndServe()
×
440
                if err != http.ErrServerClosed {
×
441
                        ltndLog.Errorf("autocert http: %v", err)
×
442
                }
×
443
                close(shutdownCompleted)
×
444
        }()
445

446
        getCertificate := func(h *tls.ClientHelloInfo) (
×
447
                *tls.Certificate, error) {
×
448

×
449
                lecert, err := manager.GetCertificate(h)
×
450
                if err != nil {
×
451
                        ltndLog.Errorf("GetCertificate: %v", err)
×
452
                        return certData, nil
×
453
                }
×
454

455
                return lecert, err
×
456
        }
457

458
        // The self-signed tls.cert remains available as fallback.
459
        tlsCfg.GetCertificate = getCertificate
×
460

×
461
        return cleanUp
×
462
}
463

464
// SetCertificateBeforeUnlock takes care of loading the certificate before
465
// the wallet is unlocked. If the TLSEncryptKey setting is on, we need to
466
// generate an ephemeral certificate we're able to use until the wallet is
467
// unlocked and a new TLS pair can be encrypted to disk. Otherwise we can
468
// process the certificate normally.
469
func (t *TLSManager) SetCertificateBeforeUnlock() ([]grpc.ServerOption,
470
        []grpc.DialOption, func(net.Addr) (net.Listener, error), func(),
UNCOV
471
        error) {
×
UNCOV
472

×
UNCOV
473
        if t.cfg.TLSEncryptKey {
×
474
                _, err := t.loadEphemeralCertificate()
×
475
                if err != nil {
×
476
                        return nil, nil, nil, nil, fmt.Errorf("unable to load "+
×
477
                                "ephemeral certificate: %v", err)
×
478
                }
×
UNCOV
479
        } else {
×
UNCOV
480
                _, err := t.generateOrRenewCert()
×
UNCOV
481
                if err != nil {
×
482
                        return nil, nil, nil, nil, fmt.Errorf("unable to "+
×
483
                                "generate or renew TLS certificate: %v", err)
×
484
                }
×
485
        }
486

UNCOV
487
        serverOpts, restDialOpts, restListen, cleanUp, err := t.getConfig()
×
UNCOV
488
        if err != nil {
×
489
                return nil, nil, nil, nil, fmt.Errorf("unable to load TLS "+
×
490
                        "credentials: %v", err)
×
491
        }
×
492

UNCOV
493
        return serverOpts, restDialOpts, restListen, cleanUp, nil
×
494
}
495

496
// loadEphemeralCertificate creates and loads the ephemeral certificate which
497
// is used temporarily for secure communications before the wallet is unlocked.
498
func (t *TLSManager) loadEphemeralCertificate() ([]byte, error) {
1✔
499
        rpcsLog.Infof("Generating ephemeral TLS certificates...")
1✔
500

1✔
501
        tmpValidity := validityHours * time.Hour
1✔
502
        // Append .tmp to the end of the cert for differentiation.
1✔
503
        tmpCertPath := t.cfg.TLSCertPath + ".tmp"
1✔
504

1✔
505
        // Pass in a blank string for the key path so the
1✔
506
        // function doesn't write them to disk.
1✔
507
        certBytes, keyBytes, err := cert.GenCertPair(
1✔
508
                "lnd ephemeral autogenerated cert", t.cfg.TLSExtraIPs,
1✔
509
                t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill, tmpValidity,
1✔
510
        )
1✔
511
        if err != nil {
1✔
512
                return nil, err
×
513
        }
×
514
        t.setEphemeralSettings(keyBytes, certBytes)
1✔
515

1✔
516
        err = cert.WriteCertPair(tmpCertPath, "", certBytes, keyBytes)
1✔
517
        if err != nil {
1✔
518
                return nil, err
×
519
        }
×
520

521
        rpcsLog.Infof("Done generating ephemeral TLS certificates")
1✔
522

1✔
523
        return keyBytes, nil
1✔
524
}
525

526
// LoadPermanentCertificate deletes the ephemeral certificate file and
527
// generates a new one with the real keyring.
528
func (t *TLSManager) LoadPermanentCertificate(
529
        keyRing keychain.SecretKeyRing) error {
1✔
530

1✔
531
        if !t.cfg.TLSEncryptKey {
1✔
UNCOV
532
                return nil
×
UNCOV
533
        }
×
534

535
        tmpCertPath := t.cfg.TLSCertPath + ".tmp"
1✔
536
        err := os.Remove(tmpCertPath)
1✔
537
        if err != nil {
1✔
538
                ltndLog.Warn("Unable to delete temp cert at %v",
×
539
                        tmpCertPath)
×
540
        }
×
541

542
        err = t.generateCertPair(keyRing)
1✔
543
        if err != nil {
1✔
544
                return err
×
545
        }
×
546

547
        certBytes, encryptedKeyBytes, err := cert.GetCertBytesFromPath(
1✔
548
                t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
1✔
549
        )
1✔
550
        if err != nil {
1✔
551
                return err
×
552
        }
×
553

554
        reader := bytes.NewReader(encryptedKeyBytes)
1✔
555
        e, err := lnencrypt.KeyRingEncrypter(keyRing)
1✔
556
        if err != nil {
1✔
557
                return fmt.Errorf("unable to generate encrypt key %w",
×
558
                        err)
×
559
        }
×
560

561
        keyBytes, err := e.DecryptPayloadFromReader(reader)
1✔
562
        if err != nil {
1✔
563
                return err
×
564
        }
×
565

566
        // Switch the server's TLS certificate to the persistent one. By
567
        // changing the cert data the TLSReloader points to,
568
        err = t.tlsReloader.AttemptReload(certBytes, keyBytes)
1✔
569
        if err != nil {
1✔
570
                return err
×
571
        }
×
572

573
        t.deleteEphemeralSettings()
1✔
574

1✔
575
        return nil
1✔
576
}
577

578
// setEphemeralSettings sets the TLSManager settings needed when an ephemeral
579
// certificate is created.
580
func (t *TLSManager) setEphemeralSettings(keyBytes, certBytes []byte) {
1✔
581
        t.ephemeralKey = keyBytes
1✔
582
        t.ephemeralCert = certBytes
1✔
583
        t.ephemeralCertPath = t.cfg.TLSCertPath + ".tmp"
1✔
584
}
1✔
585

586
// deleteEphemeralSettings deletes the TLSManager ephemeral settings that are
587
// no longer needed when the ephemeral certificate is deleted so the Manager
588
// knows we're no longer using it.
589
func (t *TLSManager) deleteEphemeralSettings() {
1✔
590
        t.ephemeralKey = nil
1✔
591
        t.ephemeralCert = nil
1✔
592
        t.ephemeralCertPath = ""
1✔
593
}
1✔
594

595
// IsCertExpired checks if the current TLS certificate is expired.
596
func (t *TLSManager) IsCertExpired(keyRing keychain.SecretKeyRing) (bool,
597
        time.Time, error) {
×
598

×
599
        certBytes, keyBytes, err := cert.GetCertBytesFromPath(
×
600
                t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
×
601
        )
×
602
        if err != nil {
×
603
                return false, time.Time{}, err
×
604
        }
×
605

606
        // If TLSEncryptKey is set, there are two states the
607
        // certificate can be in: ephemeral or permanent.
608
        // Retrieve the key depending on which state it is in.
609
        if t.ephemeralKey != nil {
×
610
                keyBytes = t.ephemeralKey
×
611
        } else if t.cfg.TLSEncryptKey {
×
612
                keyBytes, err = decryptTLSKeyBytes(keyRing, keyBytes)
×
613
                if err != nil {
×
614
                        return false, time.Time{}, err
×
615
                }
×
616
        }
617

618
        _, parsedCert, err := cert.LoadCertFromBytes(
×
619
                certBytes, keyBytes,
×
620
        )
×
621
        if err != nil {
×
622
                return false, time.Time{}, err
×
623
        }
×
624

625
        // If the current time is passed the certificate's
626
        // expiry time, then it is considered expired
627
        if time.Now().After(parsedCert.NotAfter) {
×
628
                return true, parsedCert.NotAfter, nil
×
629
        }
×
630

631
        return false, parsedCert.NotAfter, nil
×
632
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc