Skip to content

Commit 4b1c499

Browse files
authored
Merge pull request #10399 from mohamedawnallah/handle-partial-tls-files
tls_manager: Handle partial TLS files
2 parents 140248b + 0a6f69d commit 4b1c499

File tree

3 files changed

+97
-2
lines changed

3 files changed

+97
-2
lines changed

docs/release-notes/release-notes-0.21.0.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
sub-server is still starting. This allows clients to reliably detect the
2727
transient condition and retry without brittle string matching.
2828

29+
- [Fixed an issue](https://github.com/lightningnetwork/lnd/pull/10399) where the
30+
TLS manager would fail to start if only one of the TLS pair files (certificate
31+
or key) existed. The manager now correctly regenerates both files when either
32+
is missing, preventing "file not found" errors on startup.
33+
2934
# New Features
3035

3136
- Basic Support for [onion messaging forwarding](https://github.com/lightningnetwork/lnd/pull/9868)
@@ -77,4 +82,5 @@
7782

7883
* Boris Nagaev
7984
* Elle Mouton
85+
* Mohamed Awnallah
8086
* Nishant Bansal

tls_manager.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ func (t *TLSManager) generateOrRenewCert() (*tls.Config, error) {
208208
// is already written to disk, this function overwrites the plaintext key with
209209
// the encrypted form.
210210
func (t *TLSManager) generateCertPair(keyRing keychain.SecretKeyRing) error {
211-
// Ensure we create TLS key and certificate if they don't exist.
212-
if lnrpc.FileExists(t.cfg.TLSCertPath) ||
211+
// Ensure we create TLS key and certificate if they don't both exist.
212+
if lnrpc.FileExists(t.cfg.TLSCertPath) &&
213213
lnrpc.FileExists(t.cfg.TLSKeyPath) {
214214

215215
// Handle discrepencies related to the TLSEncryptKey setting.

tls_manager_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,92 @@ func newTestDirectory(t *testing.T) (string, string, string) {
369369

370370
return tempDir, certPath, keyPath
371371
}
372+
373+
// TestGenerateCertPairWithPartialFiles tests that generateCertPair regenerates
374+
// a cert/key pair when only one file exists.
375+
func TestGenerateCertPairWithPartialFiles(t *testing.T) {
376+
t.Parallel()
377+
378+
keyRing := &mock.SecretKeyRing{
379+
RootKey: privKey,
380+
}
381+
382+
testCases := []struct {
383+
name string
384+
setup func(t *testing.T, certPath, keyPath string)
385+
}{
386+
{
387+
name: "only key exists",
388+
setup: func(t *testing.T, certPath, keyPath string) {
389+
// Create only a key file. It simulates leftover
390+
// from previous run.
391+
_, keyBytes := genCertPair(t, false)
392+
keyBuf := &bytes.Buffer{}
393+
err := pem.Encode(
394+
keyBuf, &pem.Block{
395+
Type: "EC PRIVATE KEY",
396+
Bytes: keyBytes,
397+
},
398+
)
399+
require.NoError(t, err)
400+
401+
err = os.WriteFile(
402+
keyPath, keyBuf.Bytes(), 0600,
403+
)
404+
require.NoError(t, err)
405+
},
406+
},
407+
{
408+
name: "only cert exists",
409+
setup: func(t *testing.T, certPath, keyPath string) {
410+
// Create only a cert file. It simulates
411+
// leftover from previous run.
412+
certBytes, _ := genCertPair(t, false)
413+
certBuf := &bytes.Buffer{}
414+
err := pem.Encode(
415+
certBuf, &pem.Block{
416+
Type: "CERTIFICATE",
417+
Bytes: certBytes,
418+
},
419+
)
420+
require.NoError(t, err)
421+
422+
err = os.WriteFile(
423+
certPath, certBuf.Bytes(), 0644,
424+
)
425+
require.NoError(t, err)
426+
},
427+
},
428+
}
429+
430+
for _, tc := range testCases {
431+
tc := tc
432+
t.Run(tc.name, func(t *testing.T) {
433+
t.Parallel()
434+
435+
tempDir := t.TempDir()
436+
certPath := tempDir + "/tls.cert"
437+
keyPath := tempDir + "/tls.key"
438+
439+
tc.setup(t, certPath, keyPath)
440+
441+
cfg := &TLSManagerCfg{
442+
TLSCertPath: certPath,
443+
TLSKeyPath: keyPath,
444+
TLSCertDuration: testTLSCertDuration,
445+
}
446+
tlsManager := NewTLSManager(cfg)
447+
448+
err := tlsManager.generateCertPair(keyRing)
449+
require.NoError(
450+
t, err, "should generate new cert pair when %s",
451+
tc.name,
452+
)
453+
454+
_, _, err = cert.GetCertBytesFromPath(certPath, keyPath)
455+
require.NoError(
456+
t, err, "should be able to load cert pair",
457+
)
458+
})
459+
}
460+
}

0 commit comments

Comments
 (0)