Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tor] Add ability to encrypt the Tor private key on disk #6500

Merged
merged 5 commits into from
Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion chanbackup/backupfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"path/filepath"
"testing"

"github.com/lightningnetwork/lnd/lnencrypt"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -184,7 +185,7 @@ func assertMultiEqual(t *testing.T, a, b *Multi) {
func TestExtractMulti(t *testing.T) {
t.Parallel()

keyRing := &mockKeyRing{}
keyRing := &lnencrypt.MockKeyRing{}

// First, as prep, we'll create a single chan backup, then pack that
// fully into a multi backup.
Expand Down
140 changes: 0 additions & 140 deletions chanbackup/crypto.go

This file was deleted.

14 changes: 12 additions & 2 deletions chanbackup/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"

"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnencrypt"
"github.com/lightningnetwork/lnd/lnwire"
)

Expand Down Expand Up @@ -89,7 +90,12 @@ func (m Multi) PackToWriter(w io.Writer, keyRing keychain.KeyRing) error {

// With the plaintext multi backup assembled, we'll now encrypt it
// directly to the passed writer.
return encryptPayloadToWriter(multiBackupBuffer, w, keyRing)
e, err := lnencrypt.KeyRingEncrypter(keyRing)
if err != nil {
return fmt.Errorf("unable to generate encrypt key %v", err)
}
orbitalturtle marked this conversation as resolved.
Show resolved Hide resolved

return e.EncryptPayloadToWriter(multiBackupBuffer.Bytes(), w)
}

// UnpackFromReader attempts to unpack (decrypt+deserialize) a packed
Expand All @@ -99,7 +105,11 @@ func (m *Multi) UnpackFromReader(r io.Reader, keyRing keychain.KeyRing) error {
// We'll attempt to read the entire packed backup, and also decrypt it
// using the passed key ring which is expected to be able to derive the
// encryption keys.
plaintextBackup, err := decryptPayloadFromReader(r, keyRing)
e, err := lnencrypt.KeyRingEncrypter(keyRing)
if err != nil {
return fmt.Errorf("unable to generate encrypt key %v", err)
guggero marked this conversation as resolved.
Show resolved Hide resolved
}
plaintextBackup, err := e.DecryptPayloadFromReader(r)
if err != nil {
return err
}
Expand Down
12 changes: 8 additions & 4 deletions chanbackup/multi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net"
"testing"

"github.com/lightningnetwork/lnd/lnencrypt"
"github.com/stretchr/testify/require"
)

Expand All @@ -27,7 +28,7 @@ func TestMultiPackUnpack(t *testing.T) {
multi.StaticBackups = append(multi.StaticBackups, single)
}

keyRing := &mockKeyRing{}
keyRing := &lnencrypt.MockKeyRing{}

versionTestCases := []struct {
// version is the pack/unpack version that we should use to
Expand Down Expand Up @@ -93,14 +94,17 @@ func TestMultiPackUnpack(t *testing.T) {
)
}

encrypter, err := lnencrypt.KeyRingEncrypter(keyRing)
require.NoError(t, err)

// Next, we'll make a fake packed multi, it'll have an
// unknown version relative to what's implemented atm.
var fakePackedMulti bytes.Buffer
fakeRawMulti := bytes.NewBuffer(
bytes.Repeat([]byte{99}, 20),
)
err := encryptPayloadToWriter(
*fakeRawMulti, &fakePackedMulti, keyRing,
err = encrypter.EncryptPayloadToWriter(
fakeRawMulti.Bytes(), &fakePackedMulti,
)
if err != nil {
t.Fatalf("unable to pack fake multi; %v", err)
Expand All @@ -124,7 +128,7 @@ func TestMultiPackUnpack(t *testing.T) {
func TestPackedMultiUnpack(t *testing.T) {
t.Parallel()

keyRing := &mockKeyRing{}
keyRing := &lnencrypt.MockKeyRing{}

// First, we'll make a new unpacked multi with a random channel.
testChannel, err := genRandomOpenChannelShell()
Expand Down
7 changes: 4 additions & 3 deletions chanbackup/pubsub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnencrypt"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -80,7 +81,7 @@ func (m *mockChannelNotifier) SubscribeChans(chans map[wire.OutPoint]struct{}) (
func TestNewSubSwapperSubscribeFail(t *testing.T) {
t.Parallel()

keyRing := &mockKeyRing{}
keyRing := &lnencrypt.MockKeyRing{}

var swapper mockSwapper
chanNotifier := mockChannelNotifier{
Expand Down Expand Up @@ -152,7 +153,7 @@ func assertExpectedBackupSwap(t *testing.T, swapper *mockSwapper,
func TestSubSwapperIdempotentStartStop(t *testing.T) {
t.Parallel()

keyRing := &mockKeyRing{}
keyRing := &lnencrypt.MockKeyRing{}

var chanNotifier mockChannelNotifier

Expand Down Expand Up @@ -181,7 +182,7 @@ func TestSubSwapperIdempotentStartStop(t *testing.T) {
func TestSubSwapperUpdater(t *testing.T) {
t.Parallel()

keyRing := &mockKeyRing{}
keyRing := &lnencrypt.MockKeyRing{}
chanNotifier := newMockChannelNotifier()
swapper := newMockSwapper(keyRing)

Expand Down
9 changes: 5 additions & 4 deletions chanbackup/recover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/lightningnetwork/lnd/lnencrypt"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -49,7 +50,7 @@ func (m *mockPeerConnector) ConnectPeer(node *btcec.PublicKey,
func TestUnpackAndRecoverSingles(t *testing.T) {
t.Parallel()

keyRing := &mockKeyRing{}
keyRing := &lnencrypt.MockKeyRing{}

// First, we'll create a number of single chan backups that we'll
// shortly back to so we can begin our recovery attempt.
Expand Down Expand Up @@ -123,7 +124,7 @@ func TestUnpackAndRecoverSingles(t *testing.T) {
}

// If we modify the keyRing, then unpacking should fail.
keyRing.fail = true
keyRing.Fail = true
err = UnpackAndRecoverSingles(
packedBackups, keyRing, &chanRestorer, &peerConnector,
)
Expand All @@ -139,7 +140,7 @@ func TestUnpackAndRecoverSingles(t *testing.T) {
func TestUnpackAndRecoverMulti(t *testing.T) {
t.Parallel()

keyRing := &mockKeyRing{}
keyRing := &lnencrypt.MockKeyRing{}

// First, we'll create a number of single chan backups that we'll
// shortly back to so we can begin our recovery attempt.
Expand Down Expand Up @@ -217,7 +218,7 @@ func TestUnpackAndRecoverMulti(t *testing.T) {
}

// If we modify the keyRing, then unpacking should fail.
keyRing.fail = true
keyRing.Fail = true
err = UnpackAndRecoverMulti(
packedMulti, keyRing, &chanRestorer, &peerConnector,
)
Expand Down
21 changes: 15 additions & 6 deletions chanbackup/single.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnencrypt"
"github.com/lightningnetwork/lnd/lnwire"
)

Expand Down Expand Up @@ -333,10 +334,10 @@ func (s *Single) Serialize(w io.Writer) error {
// global counter to use as a sequence number for nonces, and want to ensure
// that we're able to decrypt these blobs without any additional context. We
// derive the key that we use for encryption via a SHA2 operation of the with
// the golden keychain.KeyFamilyStaticBackup base encryption key. We then take
// the serialized resulting shared secret point, and hash it using sha256 to
// obtain the key that we'll use for encryption. When using the AEAD, we pass
// the nonce as associated data such that we'll be able to package the two
// the golden keychain.KeyFamilyBaseEncryption base encryption key. We then
// take the serialized resulting shared secret point, and hash it using sha256
// to obtain the key that we'll use for encryption. When using the AEAD, we
// pass the nonce as associated data such that we'll be able to package the two
// together for storage. Before writing out the encrypted payload, we prepend
// the nonce to the final blob.
func (s *Single) PackToWriter(w io.Writer, keyRing keychain.KeyRing) error {
Expand All @@ -351,7 +352,11 @@ func (s *Single) PackToWriter(w io.Writer, keyRing keychain.KeyRing) error {
// Finally, we'll encrypt the raw serialized SCB (using the nonce as
// associated data), and write out the ciphertext prepend with the
// nonce that we used to the passed io.Reader.
return encryptPayloadToWriter(rawBytes, w, keyRing)
e, err := lnencrypt.KeyRingEncrypter(keyRing)
if err != nil {
return fmt.Errorf("unable to generate encrypt key %v", err)
}
return e.EncryptPayloadToWriter(rawBytes.Bytes(), w)
}

// readLocalKeyDesc reads a KeyDescriptor encoded within an unpacked Single.
Expand Down Expand Up @@ -528,7 +533,11 @@ func (s *Single) Deserialize(r io.Reader) error {
// payload for whatever reason (wrong key, wrong nonce, etc), then this method
// will return an error.
func (s *Single) UnpackFromReader(r io.Reader, keyRing keychain.KeyRing) error {
plaintext, err := decryptPayloadFromReader(r, keyRing)
e, err := lnencrypt.KeyRingEncrypter(keyRing)
if err != nil {
return fmt.Errorf("unable to generate key decrypter %v", err)
}
plaintext, err := e.DecryptPayloadFromReader(r)
if err != nil {
return err
}
Expand Down
Loading