forked from grantae/certinfo
-
Notifications
You must be signed in to change notification settings - Fork 9
/
yubico.go
109 lines (103 loc) · 2.77 KB
/
yubico.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
package certinfo
import (
"encoding/asn1"
"fmt"
"strconv"
)
// Yubico PIV attestation OIDs from
// https://developers.yubico.com/PIV/Introduction/PIV_attestation.html
var (
// Firmware version, encoded as 3 bytes, like: 040300 for 4.3.0
oidYubicoFirmwareVersion = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 41482, 3, 3}
// Serial number of the YubiKey, encoded as an integer.
oidYubicoSerialNumber = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 41482, 3, 7}
// Two bytes, the first encoding pin policy and the second touch policy:
//
// - Pin policy: 01 - never, 02 - once per session, 03 - always
// - Touch policy: 01 - never, 02 - always, 03 - cached for 15s
oidYubicoPolicy = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 41482, 3, 8}
// Formfactor, encoded as one byte:
//
// - USB-A Keychain: 01 (81 for FIPS Devices)
// - USB-A Nano: 02 (82 for FIPS Devices)
// - USB-C Keychain: 03 (83 for FIPS Devices)
// - USB-C Nano: 04 (84 for FIPS Devices)
// - Lightning and USB-C: 05 (85 for FIPS Devices)
oidYubicoFormfactor = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 41482, 3, 9}
// FIPS Certified YubiKey.
oidYubicoFipsCertified = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 41482, 3, 10}
// CSPN Certified YubiKey.
oidYubicoCspnCertified = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 41482, 3, 11}
)
func yubicoVersion(v []byte) string {
if len(v) == 0 {
return "unknown"
}
var version string
for i, b := range v {
if i < len(v)-1 {
version += strconv.Itoa(int(b)) + "."
} else {
version += strconv.Itoa(int(b))
}
}
return version
}
func yubicoPolicies(v []byte) []string {
if len(v) == 0 {
return []string{"unknown"}
}
policies := make([]string, 0, 2)
for i, b := range v {
switch i {
case 0:
switch b {
case 1:
policies = append(policies, "PIN policy: never")
case 2:
policies = append(policies, "PIN policy: once per session")
case 3:
policies = append(policies, "PIN policy: always")
default:
policies = append(policies, fmt.Sprintf("PIN policy: unknown (0x%02x)", b))
}
case 1:
switch b {
case 1:
policies = append(policies, "Touch policy: never")
case 2:
policies = append(policies, "Touch policy: always")
case 3:
policies = append(policies, "Touch policy: once per session")
default:
policies = append(policies, fmt.Sprintf("Touch policy: unknown (0x%02x)", b))
}
default:
return policies
}
}
return policies
}
func yubicoFormfactor(v []byte) (s string) {
if len(v) == 0 {
return "unknown"
}
switch v[0] {
case 1, 81:
s = "USB-A Keychain"
case 2, 82:
s = "USB-A Nano"
case 3, 83:
s = "USB-C Keychain"
case 4, 84:
s = "USB-C Nano"
case 5, 85:
s = "Lightning or USB-C"
default:
return fmt.Sprintf("unknown (0x%02x)", v[0])
}
if v[0] > 80 {
s += " (FIPS)"
}
return
}