|
1 | 1 | package session |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "bytes" |
5 | | - "context" |
6 | 4 | "encoding/binary" |
7 | | - "encoding/hex" |
8 | 5 | "fmt" |
9 | | - "strconv" |
10 | 6 |
|
11 | 7 | "github.com/btcsuite/btcd/btcec/v2" |
12 | | - "github.com/lightningnetwork/lnd/lnrpc" |
13 | | - "google.golang.org/protobuf/proto" |
14 | | - "gopkg.in/macaroon-bakery.v2/bakery" |
| 8 | + "github.com/lightninglabs/lightning-terminal/macaroons" |
15 | 9 | "gopkg.in/macaroon.v2" |
16 | 10 | ) |
17 | 11 |
|
18 | | -var ( |
19 | | - // SuperMacaroonRootKeyPrefix is the prefix we set on a super macaroon's |
20 | | - // root key to clearly mark it as such. |
21 | | - SuperMacaroonRootKeyPrefix = [4]byte{0xFF, 0xEE, 0xDD, 0xCC} |
22 | | -) |
23 | | - |
24 | 12 | // ID represents the id of a session. |
25 | 13 | type ID [4]byte |
26 | 14 |
|
27 | | -// SuperMacaroonValidator is a function type for validating a super macaroon. |
28 | | -type SuperMacaroonValidator func(ctx context.Context, |
29 | | - superMacaroon []byte, requiredPermissions []bakery.Op, |
30 | | - fullMethod string) error |
31 | | - |
32 | | -// NewSuperMacaroonRootKeyID returns a new macaroon root key ID that has the |
33 | | -// prefix to mark it as a super macaroon root key. |
34 | | -func NewSuperMacaroonRootKeyID(id [4]byte) uint64 { |
35 | | - rootKeyBytes := make([]byte, 8) |
36 | | - copy(rootKeyBytes[:], SuperMacaroonRootKeyPrefix[:]) |
37 | | - copy(rootKeyBytes[4:], id[:]) |
38 | | - return binary.BigEndian.Uint64(rootKeyBytes) |
39 | | -} |
40 | | - |
41 | | -// ParseMacaroon parses a hex encoded macaroon into its native struct. |
42 | | -func ParseMacaroon(macHex string) (*macaroon.Macaroon, error) { |
43 | | - macBytes, err := hex.DecodeString(macHex) |
44 | | - if err != nil { |
45 | | - return nil, err |
46 | | - } |
47 | | - |
48 | | - mac := &macaroon.Macaroon{} |
49 | | - if err := mac.UnmarshalBinary(macBytes); err != nil { |
50 | | - return nil, err |
51 | | - } |
52 | | - |
53 | | - return mac, nil |
54 | | -} |
55 | | - |
56 | | -// IsSuperMacaroon returns true if the given hex encoded macaroon is a super |
57 | | -// macaroon baked by LiT which can be identified by its root key ID. |
58 | | -func IsSuperMacaroon(macHex string) bool { |
59 | | - mac, err := ParseMacaroon(macHex) |
60 | | - if err != nil { |
61 | | - return false |
62 | | - } |
63 | | - |
64 | | - rootKeyID, err := RootKeyIDFromMacaroon(mac) |
65 | | - if err != nil { |
66 | | - return false |
67 | | - } |
68 | | - |
69 | | - return isSuperMacaroonRootKeyID(rootKeyID) |
70 | | -} |
71 | | - |
72 | | -// isSuperMacaroonRootKeyID returns true if the given macaroon root key ID (also |
73 | | -// known as storage ID) is a super macaroon, which can be identified by its |
74 | | -// first 4 bytes. |
75 | | -func isSuperMacaroonRootKeyID(rootKeyID uint64) bool { |
76 | | - rootKeyBytes := make([]byte, 8) |
77 | | - binary.BigEndian.PutUint64(rootKeyBytes, rootKeyID) |
78 | | - return bytes.HasPrefix(rootKeyBytes, SuperMacaroonRootKeyPrefix[:]) |
79 | | -} |
80 | | - |
81 | 15 | // IDFromMacaroon is a helper function that creates a session ID from |
82 | 16 | // a macaroon ID. |
83 | 17 | func IDFromMacaroon(mac *macaroon.Macaroon) (ID, error) { |
84 | | - rootKeyID, err := RootKeyIDFromMacaroon(mac) |
| 18 | + rootKeyID, err := macaroons.RootKeyIDFromMacaroon(mac) |
85 | 19 | if err != nil { |
86 | 20 | return ID{}, err |
87 | 21 | } |
@@ -110,25 +44,6 @@ func IDFromBytes(b []byte) (ID, error) { |
110 | 44 | return id, nil |
111 | 45 | } |
112 | 46 |
|
113 | | -// RootKeyIDFromMacaroon extracts the root key ID of the passed macaroon. |
114 | | -func RootKeyIDFromMacaroon(mac *macaroon.Macaroon) (uint64, error) { |
115 | | - rawID := mac.Id() |
116 | | - if rawID[0] != byte(bakery.LatestVersion) { |
117 | | - return 0, fmt.Errorf("mac id is not on the latest version") |
118 | | - } |
119 | | - |
120 | | - decodedID := &lnrpc.MacaroonId{} |
121 | | - idProto := rawID[1:] |
122 | | - err := proto.Unmarshal(idProto, decodedID) |
123 | | - if err != nil { |
124 | | - return 0, err |
125 | | - } |
126 | | - |
127 | | - // The storage ID is a string representation of a 64-bit unsigned |
128 | | - // number. |
129 | | - return strconv.ParseUint(string(decodedID.StorageId), 10, 64) |
130 | | -} |
131 | | - |
132 | 47 | // NewSessionPrivKeyAndID randomly derives a new private key and session ID |
133 | 48 | // pair. |
134 | 49 | func NewSessionPrivKeyAndID() (*btcec.PrivateKey, ID, error) { |
|
0 commit comments