Skip to content

Commit d5acf4b

Browse files
authored
Update ed25519keys.go
1 parent af8723a commit d5acf4b

1 file changed

Lines changed: 66 additions & 11 deletions

File tree

internal/crypto/ed25519keys.go

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import (
88
"strings"
99
)
1010

11+
type ResolvePublicKeyOptions struct {
12+
KeyID string
13+
PublicKeyPath string
14+
SearchDirs []string
15+
}
16+
1117
func LoadEd25519PrivateKeyFromSeedFile(path string) (ed25519.PrivateKey, error) {
1218
b, err := readB64URLFile(path)
1319
if err != nil {
@@ -35,20 +41,21 @@ func LoadEd25519PublicKeyFile(path string) (ed25519.PublicKey, error) {
3541
return ed25519.PublicKey(b), nil
3642
}
3743

38-
// ResolvePublicKeyByID searches for:
39-
// - keys/<keyID>.pub
40-
// - keys/dev/<keyID>.pub
41-
func ResolvePublicKeyByID(keyID string) (ed25519.PublicKey, string, error) {
42-
keyID = strings.TrimSpace(keyID)
43-
if keyID == "" {
44-
return nil, "", fmt.Errorf("key_id is empty")
44+
func ResolveEd25519PublicKey(opts ResolvePublicKeyOptions) (ed25519.PublicKey, string, error) {
45+
if path := strings.TrimSpace(opts.PublicKeyPath); path != "" {
46+
pub, err := LoadEd25519PublicKeyFile(path)
47+
if err != nil {
48+
return nil, "", err
49+
}
50+
return pub, path, nil
4551
}
4652

47-
candidates := []string{
48-
filepath.Join("keys", keyID+".pub"),
49-
filepath.Join("keys", "dev", keyID+".pub"),
53+
keyID := strings.TrimSpace(opts.KeyID)
54+
if keyID == "" {
55+
return nil, "", fmt.Errorf("key_id is empty")
5056
}
5157

58+
candidates := publicKeyCandidates(keyID, opts.SearchDirs)
5259
for _, p := range candidates {
5360
if _, err := os.Stat(p); err == nil {
5461
pub, err := LoadEd25519PublicKeyFile(p)
@@ -59,7 +66,55 @@ func ResolvePublicKeyByID(keyID string) (ed25519.PublicKey, string, error) {
5966
}
6067
}
6168

62-
return nil, "", fmt.Errorf("could not resolve public key for key_id %q (looked in keys/ and keys/dev/)", keyID)
69+
return nil, "", fmt.Errorf("could not resolve public key for key_id %q (looked in %s)", keyID, strings.Join(candidates, ", "))
70+
}
71+
72+
func ResolvePublicKeyByID(keyID string) (ed25519.PublicKey, string, error) {
73+
return ResolveEd25519PublicKey(ResolvePublicKeyOptions{KeyID: keyID})
74+
}
75+
76+
func DefaultPublicKeySearchDirs() []string {
77+
return []string{
78+
filepath.Join("keys"),
79+
filepath.Join("keys", "dev"),
80+
}
81+
}
82+
83+
func publicKeyCandidates(keyID string, searchDirs []string) []string {
84+
dirs := normalizeSearchDirs(searchDirs)
85+
out := make([]string, 0, len(dirs))
86+
for _, dir := range dirs {
87+
out = append(out, filepath.Join(dir, keyID+".pub"))
88+
}
89+
return out
90+
}
91+
92+
func normalizeSearchDirs(searchDirs []string) []string {
93+
if len(searchDirs) == 0 {
94+
return DefaultPublicKeySearchDirs()
95+
}
96+
97+
seen := map[string]struct{}{}
98+
out := make([]string, 0, len(searchDirs))
99+
100+
for _, dir := range searchDirs {
101+
dir = strings.TrimSpace(dir)
102+
if dir == "" {
103+
continue
104+
}
105+
dir = filepath.Clean(dir)
106+
if _, ok := seen[dir]; ok {
107+
continue
108+
}
109+
seen[dir] = struct{}{}
110+
out = append(out, dir)
111+
}
112+
113+
if len(out) == 0 {
114+
return DefaultPublicKeySearchDirs()
115+
}
116+
117+
return out
63118
}
64119

65120
func readB64URLFile(path string) ([]byte, error) {

0 commit comments

Comments
 (0)