-
-
Notifications
You must be signed in to change notification settings - Fork 501
/
Copy pathrecipients.go
93 lines (80 loc) · 2.29 KB
/
recipients.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package age
import (
"context"
"strings"
"filippo.io/age"
"filippo.io/age/agessh"
"github.com/gopasspw/gopass/pkg/debug"
)
// FindRecipients returns all list of usable recipient key IDs matching the search strings.
// For native age keys this is a no-op since they are self-contained (i.e. the ID is the full key already).
// But for SSH keys, especially GitHub indirections, an extra step is necessary.
func (a *Age) FindRecipients(ctx context.Context, search ...string) ([]string, error) {
remote := make([]string, 0, len(search))
local := make([]string, 0, len(search))
for _, key := range search {
if !strings.HasPrefix(key, "github:") {
local = append(local, key)
continue
}
pks, err := a.ghCache.ListKeys(ctx, strings.TrimPrefix(key, "github:"))
if err != nil {
debug.Log("Failed to get key %s from github: %s", key, err)
continue
}
remote = append(remote, pks...)
}
recps, err := a.IdentityRecipients(ctx)
if err != nil {
return nil, err
}
ids := make([]string, 0, len(remote)+len(local)+len(recps))
for _, r := range recipientsToBech32(recps) {
for _, l := range local {
if r == l {
ids = append(ids, r)
}
}
}
recp := append(ids, remote...)
debug.Log("found usable keys for %q: %q (all: %q)", search, recp, append(ids, remote...))
return recp, nil
}
func (a *Age) parseRecipients(ctx context.Context, recipients []string) ([]age.Recipient, error) {
out := make([]age.Recipient, 0, len(recipients))
for _, r := range recipients {
if strings.HasPrefix(r, "age1") {
id, err := age.ParseX25519Recipient(r)
if err != nil {
debug.Log("Failed to parse recipient %q as X25519: %s", r, err)
continue
}
out = append(out, id)
continue
}
if strings.HasPrefix(r, "ssh-") {
id, err := agessh.ParseRecipient(r)
if err != nil {
debug.Log("Failed to parse recipient %q as SSH: %s", r, err)
continue
}
out = append(out, id)
continue
}
if strings.HasPrefix(r, "github:") {
pks, err := a.ghCache.ListKeys(ctx, strings.TrimPrefix(r, "github:"))
if err != nil {
return out, err
}
for _, pk := range pks {
id, err := agessh.ParseRecipient(r)
if err != nil {
debug.Log("Failed to parse GitHub recipient %q: %q: %s", r, pk, err)
continue
}
out = append(out, id)
}
}
}
return out, nil
}