Merge pull request #10399 from mohamedawnallah/handle-partial-tls-files

tls_manager: Handle partial TLS files
This commit is contained in:
Yong authored and GitHub committed 2025-12-03 18:27:39 +08:00
commit 4b1c4998ad
3 files changed
+97 -2

No files matched your search

@@ -26,6 +26,11 @@
sub-server is still starting. This allows clients to reliably detect the
transient condition and retry without brittle string matching.
- [Fixed an issue](https://github.com/lightningnetwork/lnd/pull/10399) where the
TLS manager would fail to start if only one of the TLS pair files (certificate
or key) existed. The manager now correctly regenerates both files when either
is missing, preventing "file not found" errors on startup.
# New Features
- Basic Support for [onion messaging forwarding](https://github.com/lightningnetwork/lnd/pull/9868)
@@ -77,4 +82,5 @@
* Boris Nagaev
* Elle Mouton
* Mohamed Awnallah
* Nishant Bansal
+2 -2
View File
@@ -208,8 +208,8 @@ func (t *TLSManager) generateOrRenewCert() (*tls.Config, error) {
// is already written to disk, this function overwrites the plaintext key with
// the encrypted form.
func (t *TLSManager) generateCertPair(keyRing keychain.SecretKeyRing) error {
// Ensure we create TLS key and certificate if they don't exist.
if lnrpc.FileExists(t.cfg.TLSCertPath) ||
// Ensure we create TLS key and certificate if they don't both exist.
if lnrpc.FileExists(t.cfg.TLSCertPath) &&
lnrpc.FileExists(t.cfg.TLSKeyPath) {
// Handle discrepencies related to the TLSEncryptKey setting.
+89
View File
@@ -369,3 +369,92 @@ func newTestDirectory(t *testing.T) (string, string, string) {
return tempDir, certPath, keyPath
}
// TestGenerateCertPairWithPartialFiles tests that generateCertPair regenerates
// a cert/key pair when only one file exists.
func TestGenerateCertPairWithPartialFiles(t *testing.T) {
t.Parallel()
keyRing := &mock.SecretKeyRing{
RootKey: privKey,
}
testCases := []struct {
name string
setup func(t *testing.T, certPath, keyPath string)
}{
{
name: "only key exists",
setup: func(t *testing.T, certPath, keyPath string) {
// Create only a key file. It simulates leftover
// from previous run.
_, keyBytes := genCertPair(t, false)
keyBuf := &bytes.Buffer{}
err := pem.Encode(
keyBuf, &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: keyBytes,
},
)
require.NoError(t, err)
err = os.WriteFile(
keyPath, keyBuf.Bytes(), 0600,
)
require.NoError(t, err)
},
},
{
name: "only cert exists",
setup: func(t *testing.T, certPath, keyPath string) {
// Create only a cert file. It simulates
// leftover from previous run.
certBytes, _ := genCertPair(t, false)
certBuf := &bytes.Buffer{}
err := pem.Encode(
certBuf, &pem.Block{
Type: "CERTIFICATE",
Bytes: certBytes,
},
)
require.NoError(t, err)
err = os.WriteFile(
certPath, certBuf.Bytes(), 0644,
)
require.NoError(t, err)
},
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
tempDir := t.TempDir()
certPath := tempDir + "/tls.cert"
keyPath := tempDir + "/tls.key"
tc.setup(t, certPath, keyPath)
cfg := &TLSManagerCfg{
TLSCertPath: certPath,
TLSKeyPath: keyPath,
TLSCertDuration: testTLSCertDuration,
}
tlsManager := NewTLSManager(cfg)
err := tlsManager.generateCertPair(keyRing)
require.NoError(
t, err, "should generate new cert pair when %s",
tc.name,
)
_, _, err = cert.GetCertBytesFromPath(certPath, keyPath)
require.NoError(
t, err, "should be able to load cert pair",
)
})
}
}