generated from cunicu/skeleton
-
Notifications
You must be signed in to change notification settings - Fork 1
/
filter.go
137 lines (113 loc) · 3.53 KB
/
filter.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// SPDX-FileCopyrightText: 2023 Steffen Vogel <post@steffenvogel.de>
// SPDX-License-Identifier: Apache-2.0
package yubikey
import (
"fmt"
iso "cunicu.li/go-iso7816"
"cunicu.li/go-iso7816/filter"
)
func HasVersionStr(s string) filter.Filter {
if v, err := iso.ParseVersion(s); err == nil {
return HasVersion(v)
}
return filter.None
}
// HasVersion checks that the card has a firmware version equal or higher
// than the given one.
func HasVersion(v iso.Version) filter.Filter {
return withApplet(iso.AidYubicoOTP, func(c *iso.Card) (bool, error) {
if sts, err := GetStatus(c); err != nil {
return false, err
} else if !sts.Version.Less(v) {
return false, nil
}
return true, nil
})
}
func IsSerialNumber(sno uint32) filter.Filter {
return withDeviceInfo(func(di *DeviceInfo) bool {
return di.SerialNumber == sno
})
}
// HasFormFactor returns a filter which checks if the YubiKey
// has a given form factor.
func HasFormFactor(ff FormFactor) filter.Filter {
return withDeviceInfo(func(di *DeviceInfo) bool {
return di.FormFactor == ff
})
}
//nolint:gochecknoglobals
var (
IsFIPS = withDeviceInfo(func(di *DeviceInfo) bool {
return di.IsFIPS
})
IsLocked = withDeviceInfo(func(di *DeviceInfo) bool {
return di.IsLocked
})
)
// HasOTP is a filter which checks if the YubiKey has the OTP
// applet enabled.
func HasOTP(name string, card *iso.Card) (bool, error) {
return hasCapabilityEnabled(CapOTP)(name, card)
}
// HasU2F is a filter which checks if the YubiKey has the U2F
// applet enabled.
func HasU2F(name string, card *iso.Card) (bool, error) {
return hasCapabilityEnabled(CapU2F)(name, card)
}
// HasFIDO2 is a filter which checks if the YubiKey has the FIDO2
// applet enabled.
func HasFIDO2(name string, card *iso.Card) (bool, error) {
return hasCapabilityEnabled(CapFIDO2)(name, card)
}
// HasOATH is a filter which checks if the YubiKey has the OATH
// applet enabled.
func HasOATH(name string, card *iso.Card) (bool, error) {
return hasCapabilityEnabled(CapOATH)(name, card)
}
// HasPIV is a filter which checks if the YubiKey has the PIV
// applet enabled.
func HasPIV(name string, card *iso.Card) (bool, error) {
return hasCapabilityEnabled(CapPIV)(name, card)
}
// HasOpenPGP is a filter which checks if the YubiKey has the OpenPGP
// applet enabled.
func HasOpenPGP(name string, card *iso.Card) (bool, error) {
return hasCapabilityEnabled(CapOpenPGP)(name, card)
}
// HasHSMAuth is a filter which checks if the YubiKey has the HSM authentication
// applet enabled.
func HasHSMAuth(name string, card *iso.Card) (bool, error) {
return hasCapabilityEnabled(CapOpenPGP)(name, card)
}
func hasCapabilityEnabled(c Capability) filter.Filter {
return withDeviceInfo(func(di *DeviceInfo) bool {
return (di.CapsEnabledUSB|di.CapsEnabledNFC)&c != 0
})
}
func withDeviceInfo(cb func(di *DeviceInfo) bool) filter.Filter {
return withApplet(iso.AidYubicoManagement, func(c *iso.Card) (bool, error) {
di, err := GetDeviceInfo(c)
if err != nil {
return false, fmt.Errorf("failed to get device information: %w", err)
}
return cb(di), nil
})
}
func withApplet(aid []byte, cb func(c *iso.Card) (bool, error)) filter.Filter {
return func(name string, c *iso.Card) (bool, error) {
// Matching against the name first saves us from connecting to the card
if match, err := filter.IsYubiKey(name, c); err != nil {
return false, err
} else if !match {
return false, nil
}
if c == nil {
return false, filter.ErrOpen
}
if _, err := c.Select(aid); err != nil {
return false, nil //nolint:nilerr
}
return cb(c)
}
}