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

lightningnetwork / lnd / 13236757158

10 Feb 2025 08:39AM UTC coverage: 57.649% (-1.2%) from 58.815%
13236757158

Pull #9493

github

ziggie1984
lncli: for some cmds we don't replace the data of the response.

For some cmds it is not very practical to replace the json output
because we might pipe it into other commands. For example when
creating the route we want to pipe it into sendtoRoute.
Pull Request #9493: For some lncli cmds we should not replace the content with other data

0 of 9 new or added lines in 2 files covered. (0.0%)

19535 existing lines in 252 files now uncovered.

103517 of 179563 relevant lines covered (57.65%)

24878.49 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