/
yk_provider.go
101 lines (87 loc) · 2.16 KB
/
yk_provider.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
94
95
96
97
98
99
100
101
package yubiks
import (
"errors"
"fmt"
"github.com/bukodi/go-keystores"
"github.com/go-piv/piv-go/piv"
"strings"
)
type YkProvider struct {
}
// Check whether implements the keystores.Provider interface
var _ keystores.Provider = &YkProvider{}
func NewYkProvider() *YkProvider {
p := YkProvider{}
return &p
}
func (p *YkProvider) Open() error {
// List all smartcards connected to the system.
cards, err := piv.Cards()
if err != nil {
return keystores.ErrorHandler(err)
}
_ = cards
return nil
}
func (p *YkProvider) Close() error {
return nil
}
func (p *YkProvider) IsOpen() bool {
return true
}
func (p *YkProvider) KeyStores() ([]keystores.KeyStore, error) {
// List all smartcards connected to the system.
cards, err := piv.Cards() // TODO: convert this function to return []error
if err != nil {
return nil, keystores.ErrorHandler(err, p)
}
// Find a YubiKey and open the reader.
ksList := make([]keystores.KeyStore, 0)
var retErr error
for _, card := range cards {
if !(strings.Contains(strings.ToLower(card), "yubikey") || strings.Contains(strings.ToLower(card), "yubikey")) {
continue
}
pivYk, err := piv.Open(card)
if err != nil {
retErr = errors.Join(retErr, keystores.ErrorHandler(err, p))
continue
}
serialInt, err := pivYk.Serial()
if err != nil {
retErr = errors.Join(retErr, keystores.ErrorHandler(err, p))
continue
}
ks := YkKeyStore{
provider: p,
pivyk: pivYk,
serial: fmt.Sprintf("%d", serialInt),
cardName: card,
}
ksList = append(ksList, &ks)
}
return ksList, retErr
}
func (p *YkProvider) FindKeyStore(ykSerial string) (*YkKeyStore, error) {
ksList, errs := p.KeyStores()
var foundKs *YkKeyStore = nil
for _, ks := range ksList {
ykKs, ok := ks.(*YkKeyStore)
if !ok {
continue
}
if ykSerial != "" && ykKs.serial != ykSerial {
continue
}
if foundKs != nil {
return nil, keystores.ErrorHandler(
fmt.Errorf("more than one key store found with conditions: serial=%q", ykSerial), p)
}
foundKs = ykKs
}
if foundKs == nil {
return nil, keystores.ErrorHandler(
fmt.Errorf("key store not found with conditions: serial=%q", ykSerial), p, errs)
}
return foundKs, nil
}