lnd/cert/selfsigned_test.go
2024-04-25 11:22:43 +02:00

262 lines
6.7 KiB
Go

package cert_test
import (
"os"
"path/filepath"
"testing"
"time"
"github.com/lightningnetwork/lnd/cert"
"github.com/stretchr/testify/require"
)
const (
testTLSCertDuration = 42 * time.Hour
)
var (
extraIPs = []string{"1.1.1.1", "123.123.123.1", "199.189.12.12"}
extraDomains = []string{"home", "and", "away"}
)
// TestIsOutdatedCert checks that we'll consider the TLS certificate outdated
// if the ip addresses or dns names don't match.
func TestIsOutdatedCert(t *testing.T) {
tempDir := t.TempDir()
certPath := tempDir + "/tls.cert"
keyPath := tempDir + "/tls.key"
// Generate TLS files with two extra IPs and domains.
certBytes, keyBytes, err := cert.GenCertPair(
"lnd autogenerated cert", extraIPs[:2], extraDomains[:2],
false, testTLSCertDuration,
)
if err != nil {
t.Fatal(err)
}
err = cert.WriteCertPair(certPath, keyPath, certBytes, keyBytes)
require.NoError(t, err)
// We'll attempt to check up-to-date status for all variants of 1-3
// number of IPs and domains.
for numIPs := 1; numIPs <= len(extraIPs); numIPs++ {
for numDomains := 1; numDomains <= len(extraDomains); numDomains++ {
certBytes, err := os.ReadFile(certPath)
require.NoError(t, err)
keyBytes, err := os.ReadFile(keyPath)
require.NoError(t, err)
_, parsedCert, err := cert.LoadCertFromBytes(
certBytes, keyBytes,
)
if err != nil {
t.Fatal(err)
}
// Using the test case's number of IPs and domains, get
// the outdated status of the certificate we created
// above.
outdated, err := cert.IsOutdated(
parsedCert, extraIPs[:numIPs],
extraDomains[:numDomains], false,
)
if err != nil {
t.Fatal(err)
}
// We expect it to be considered outdated if the IPs or
// domains don't match exactly what we created.
expected := numIPs != 2 || numDomains != 2
if outdated != expected {
t.Fatalf("expected certificate to be "+
"outdated=%v, got=%v", expected,
outdated)
}
}
}
}
// TestIsOutdatedPermutation tests that the order of listed IPs or DNS names,
// nor duplicates in the lists, matter for whether we consider the certificate
// outdated.
func TestIsOutdatedPermutation(t *testing.T) {
tempDir := t.TempDir()
certPath := tempDir + "/tls.cert"
keyPath := tempDir + "/tls.key"
// Generate TLS files from the IPs and domains.
certBytes, keyBytes, err := cert.GenCertPair(
"lnd autogenerated cert", extraIPs[:], extraDomains[:],
false, testTLSCertDuration,
)
if err != nil {
t.Fatal(err)
}
err = cert.WriteCertPair(certPath, keyPath, certBytes, keyBytes)
require.NoError(t, err)
certBytes, err = os.ReadFile(certPath)
require.NoError(t, err)
keyBytes, err = os.ReadFile(keyPath)
require.NoError(t, err)
_, parsedCert, err := cert.LoadCertFromBytes(certBytes, keyBytes)
require.NoError(t, err)
// If we have duplicate IPs or DNS names listed, that shouldn't matter.
dupIPs := make([]string, len(extraIPs)*2)
for i := range dupIPs {
dupIPs[i] = extraIPs[i/2]
}
dupDNS := make([]string, len(extraDomains)*2)
for i := range dupDNS {
dupDNS[i] = extraDomains[i/2]
}
outdated, err := cert.IsOutdated(parsedCert, dupIPs, dupDNS, false)
if err != nil {
t.Fatal(err)
}
if outdated {
t.Fatalf("did not expect duplicate IPs or DNS names be " +
"considered outdated")
}
// Similarly, the order of the lists shouldn't matter.
revIPs := make([]string, len(extraIPs))
for i := range revIPs {
revIPs[i] = extraIPs[len(extraIPs)-1-i]
}
revDNS := make([]string, len(extraDomains))
for i := range revDNS {
revDNS[i] = extraDomains[len(extraDomains)-1-i]
}
outdated, err = cert.IsOutdated(parsedCert, revIPs, revDNS, false)
if err != nil {
t.Fatal(err)
}
if outdated {
t.Fatalf("did not expect reversed IPs or DNS names be " +
"considered outdated")
}
}
// TestTLSDisableAutofill checks that setting the --tlsdisableautofill flag
// does not add interface ip addresses or hostnames to the cert.
func TestTLSDisableAutofill(t *testing.T) {
tempDir := t.TempDir()
certPath := tempDir + "/tls.cert"
keyPath := tempDir + "/tls.key"
// Generate TLS files with two extra IPs and domains and no interface IPs.
certBytes, keyBytes, err := cert.GenCertPair(
"lnd autogenerated cert", extraIPs[:2], extraDomains[:2],
true, testTLSCertDuration,
)
require.NoError(
t, err,
"unable to generate tls certificate pair",
)
err = cert.WriteCertPair(certPath, keyPath, certBytes, keyBytes)
require.NoError(t, err)
// Read certs from disk.
certBytes, err = os.ReadFile(certPath)
require.NoError(t, err)
keyBytes, err = os.ReadFile(keyPath)
require.NoError(t, err)
// Load the certificate.
_, parsedCert, err := cert.LoadCertFromBytes(
certBytes, keyBytes,
)
require.NoError(
t, err,
"unable to load tls certificate pair",
)
// Check if the TLS cert is outdated while still preventing
// interface IPs from being used. Should not be outdated.
shouldNotBeOutdated, err := cert.IsOutdated(
parsedCert, extraIPs[:2],
extraDomains[:2], true,
)
require.NoError(t, err)
require.Equal(
t, false, shouldNotBeOutdated,
"TLS Certificate was marked as outdated when it should not be",
)
// Check if the TLS cert is outdated while allowing for
// interface IPs to be used. Should report as outdated.
shouldBeOutdated, err := cert.IsOutdated(
parsedCert, extraIPs[:2],
extraDomains[:2], false,
)
require.NoError(t, err)
require.Equal(
t, true, shouldBeOutdated,
"TLS Certificate was not marked as outdated when it should be",
)
}
// TestTLSConfig tests to ensure we can generate a TLS Config from
// a tls cert and tls key.
func TestTLSConfig(t *testing.T) {
tempDir := t.TempDir()
certPath := filepath.Join(tempDir, "/tls.cert")
keyPath := filepath.Join(tempDir, "/tls.key")
// Generate TLS files with an extra IP and domain.
certBytes, keyBytes, err := cert.GenCertPair(
"lnd autogenerated cert", []string{extraIPs[0]},
[]string{extraDomains[0]}, false, testTLSCertDuration,
)
require.NoError(t, err)
err = cert.WriteCertPair(certPath, keyPath, certBytes, keyBytes)
require.NoError(t, err)
certBytes, err = os.ReadFile(certPath)
require.NoError(t, err)
keyBytes, err = os.ReadFile(keyPath)
require.NoError(t, err)
// Load the certificate.
certData, parsedCert, err := cert.LoadCertFromBytes(
certBytes, keyBytes,
)
require.NoError(t, err)
// Check to make sure the IP and domain are in the cert.
var foundIp bool
require.Contains(t, parsedCert.DNSNames, extraDomains[0])
for _, ip := range parsedCert.IPAddresses {
if ip.String() == extraIPs[0] {
foundIp = true
break
}
}
require.Equal(t, true, foundIp, "Did not find required ip inside of "+
"TLS Certificate.")
// Create TLS Config.
tlsCfg := cert.TLSConfFromCert(certData)
require.Equal(t, 1, len(tlsCfg.Certificates))
}