lnd.xprv/cmd/lncli/macaroon_jar_test.go
Oliver Gugger c34732af3d
lncli: add encrypted macaroon jar
With this commit we add a simple macaroon jar that can encrypt its
content with a user-provided password when being serialized to JSON.
2020-09-07 15:23:12 +02:00

103 lines
3.1 KiB
Go

package main
import (
"encoding/hex"
"testing"
"github.com/stretchr/testify/require"
"gopkg.in/macaroon.v2"
)
var (
dummyMacStr = "0201047465737402067788991234560000062052d26ed139ea5af8" +
"3e675500c4ccb2471f62191b745bab820f129e5588a255d2"
dummyMac, _ = hex.DecodeString(dummyMacStr)
encryptedEntry = &macaroonEntry{
Name: "encryptedMac",
Data: "snacl:exX8xbUOb6Gih88ybL2jZGo+DBDPU2tYKkvo0eVVmbDGDoFP" +
"zlv5xvqNK5eml0LKLcB8LdZRw43qXK1W2OLs/gBAAAAAAAAACAAA" +
"AAAAAAABAAAAAAAAAA==:C8TN/aDOvSLiBCX+IdoPTx+UUWhVdGj" +
"NQvbcaWp+KXQWqPfpRZpjJQ6B2PDx5mJxImcezJGPx8ShAqMdxWe" +
"l2precU+1cOjk7HQFkYuu943eJ00s6JerAY+ssg==",
}
plaintextEntry = &macaroonEntry{
Name: "plaintextMac",
Data: dummyMacStr,
}
testPassword = []byte("S3curePazzw0rd")
pwCallback = func(string) ([]byte, error) {
return testPassword, nil
}
noPwCallback = func(string) ([]byte, error) {
return nil, nil
}
)
// TestMacaroonJarEncrypted tests that a macaroon can be stored and retrieved
// safely by encrypting/decrypting it with a password.
func TestMacaroonJarEncrypted(t *testing.T) {
// Create a new macaroon entry from the dummy macaroon and encrypt it
// with the test password.
newEntry := &macaroonEntry{
Name: "encryptedMac",
}
err := newEntry.storeMacaroon(toMacaroon(t, dummyMac), testPassword)
require.NoError(t, err)
// Now decrypt it again and make sure we get the same content back.
mac, err := newEntry.loadMacaroon(pwCallback)
require.NoError(t, err)
macBytes, err := mac.MarshalBinary()
require.NoError(t, err)
require.Equal(t, dummyMac, macBytes)
// The encrypted data of the entry we just created shouldn't be the
// same as our test entry because of the salt snacl uses.
require.NotEqual(t, encryptedEntry.Data, newEntry.Data)
// Decrypt the hard coded test entry and make sure the decrypted content
// matches our created entry.
mac, err = encryptedEntry.loadMacaroon(pwCallback)
require.NoError(t, err)
macBytes, err = mac.MarshalBinary()
require.NoError(t, err)
require.Equal(t, dummyMac, macBytes)
}
// TestMacaroonJarPlaintext tests that a macaroon can be stored and retrieved
// as plaintext as well.
func TestMacaroonJarPlaintext(t *testing.T) {
// Create a new macaroon entry from the dummy macaroon and encrypt it
// with the test password.
newEntry := &macaroonEntry{
Name: "plaintextMac",
}
err := newEntry.storeMacaroon(toMacaroon(t, dummyMac), nil)
require.NoError(t, err)
// Now decrypt it again and make sure we get the same content back.
mac, err := newEntry.loadMacaroon(noPwCallback)
require.NoError(t, err)
macBytes, err := mac.MarshalBinary()
require.NoError(t, err)
require.Equal(t, dummyMac, macBytes)
require.Equal(t, plaintextEntry.Data, newEntry.Data)
// Load the hard coded plaintext test entry and make sure the loaded
// content matches our created entry.
mac, err = plaintextEntry.loadMacaroon(noPwCallback)
require.NoError(t, err)
macBytes, err = mac.MarshalBinary()
require.NoError(t, err)
require.Equal(t, dummyMac, macBytes)
}
func toMacaroon(t *testing.T, macData []byte) *macaroon.Macaroon {
mac := &macaroon.Macaroon{}
err := mac.UnmarshalBinary(macData)
require.NoError(t, err)
return mac
}