generated from cunicu/skeleton
-
Notifications
You must be signed in to change notification settings - Fork 1
/
otp.go
88 lines (72 loc) · 1.57 KB
/
otp.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
// SPDX-FileCopyrightText: 2023 Steffen Vogel <post@steffenvogel.de>
// SPDX-License-Identifier: Apache-2.0
package yubikey
import (
"encoding/binary"
"errors"
iso "cunicu.li/go-iso7816"
)
type Status struct {
Version iso.Version
Sequence uint8
TouchLevel uint16
}
func (s *Status) Unmarshal(b []byte) error {
if len(b) != 6 {
return ErrInvalidResponseLength
}
s.Version = iso.Version{
Major: int(b[0]),
Minor: int(b[1]),
Patch: int(b[2]),
}
s.Sequence = b[3]
s.TouchLevel = binary.BigEndian.Uint16(b[4:])
return nil
}
// GetStatus returns the status of the YubiKey token.
func GetStatus(c *iso.Card) (*Status, error) {
resp, err := c.Send(&iso.CAPDU{
Ins: InsReadStatus,
P1: 0x00,
P2: 0x00,
})
if err != nil {
return nil, err
}
sts := &Status{}
if err := sts.Unmarshal(resp); err != nil {
return nil, err
}
return sts, nil
}
// GetSerialNumber returns the serial number of the YubiKey token.
func GetSerialNumber(c *iso.Card) (uint32, error) {
resp, err := c.Send(&iso.CAPDU{
Ins: InsOTP,
P1: 0x10,
P2: 0x00,
})
if err != nil {
return 0, err
}
if len(resp) != 4 {
return 0, ErrInvalidResponseLength
}
return binary.BigEndian.Uint32(resp), nil
}
// GetFIPSMode returns returns the FIPS compliancy state of the YubiKey token.
func GetFIPSMode(c *iso.Card) (bool, error) {
resp, err := c.Send(&iso.CAPDU{
Ins: InsOTP,
P1: 0x14,
P2: 0x00,
})
if err != nil {
if errors.Is(err, iso.ErrIncorrectParams) || errors.Is(err, iso.ErrWrongParams) {
return false, nil
}
return false, err
}
return resp[0] != 0, nil
}