Combined ykdef with yubikey_defs.
Dain Nilsson
8 years ago
0 | """ | |
1 | Module for YubiKey related constants | |
2 | ||
3 | These are taken from ykdef.h | |
4 | """ | |
5 | ||
6 | # Copyright (c) 2015 Yubico AB | |
7 | # See the file COPYING for licence statement. | |
8 | ||
9 | __all__ = [ | |
10 | # constants | |
11 | 'YUBICO_VID' | |
12 | # functions | |
13 | # classes | |
14 | 'SLOT', | |
15 | 'MODE', | |
16 | 'PID', | |
17 | 'YK4_CAPA' | |
18 | ] | |
19 | ||
20 | ||
21 | class SLOT(object): | |
22 | """Slot entries""" | |
23 | CONFIG = 0x01 # First (default / V1) configuration | |
24 | CONFIG2 = 0x03 # Second (V2) configuration | |
25 | ||
26 | UPDATE1 = 0x04 # Update slot 1 | |
27 | UPDATE2 = 0x05 # Update slot 2 | |
28 | SWAP = 0x06 # Swap slot 1 and 2 | |
29 | ||
30 | NDEF = 0x08 # Write NDEF record | |
31 | NDEF2 = 0x09 # Write NDEF record for slot 2 | |
32 | ||
33 | DEVICE_SERIAL = 0x10 # Device serial number | |
34 | DEVICE_CONFIG = 0x11 # Write device configuration record | |
35 | SCAN_MAP = 0x12 # Write scancode map | |
36 | YK4_CAPABILITIES = 0x13 # Read YK4 capabilities list | |
37 | ||
38 | CHAL_OTP1 = 0x20 # Write 6 byte challenge to slot 1, get Yubico OTP response | |
39 | CHAL_OTP2 = 0x28 # Write 6 byte challenge to slot 2, get Yubico OTP response | |
40 | ||
41 | CHAL_HMAC1 = 0x30 # Write 64 byte challenge to slot 1, get HMAC-SHA1 response | |
42 | CHAL_HMAC2 = 0x38 # Write 64 byte challenge to slot 2, get HMAC-SHA1 response | |
43 | ||
44 | ||
45 | class MODE(object): | |
46 | """USB modes""" | |
47 | OTP = 0x00 # OTP only | |
48 | CCID = 0x01 # CCID only, no eject | |
49 | OTP_CCID = 0x02 # OTP + CCID composite | |
50 | U2F = 0x03 # U2F mode | |
51 | OTP_U2F = 0x04 # OTP + U2F composite | |
52 | U2F_CCID = 0x05 # U2F + U2F composite | |
53 | OTP_U2F_CCID = 0x06 # OTP + U2F + CCID composite | |
54 | MASK = 0x07 # Mask for mode bits | |
55 | FLAG_EJECT = 0x80 # CCID device supports eject (CCID) / OTP force eject (CCID composite) | |
56 | ||
57 | @classmethod | |
58 | def all(cls, otp=False, ccid=False, u2f=False): | |
59 | """Returns a set of all USB modes, with optional filtering""" | |
60 | modes = { | |
61 | cls.OTP, | |
62 | cls.CCID, | |
63 | cls.OTP_CCID, | |
64 | cls.U2F, | |
65 | cls.OTP_U2F, | |
66 | cls.U2F_CCID, | |
67 | cls.OTP_U2F_CCID | |
68 | } | |
69 | ||
70 | if otp: | |
71 | modes.difference_update({ | |
72 | cls.CCID, | |
73 | cls.U2F, | |
74 | cls.U2F_CCID | |
75 | }) | |
76 | ||
77 | if ccid: | |
78 | modes.difference_update({ | |
79 | cls.OTP, | |
80 | cls.U2F, | |
81 | cls.OTP_U2F | |
82 | }) | |
83 | ||
84 | if u2f: | |
85 | modes.difference_update({ | |
86 | cls.OTP, | |
87 | cls.CCID, | |
88 | cls.OTP_CCID | |
89 | }) | |
90 | ||
91 | return modes | |
92 | ||
93 | ||
94 | YUBICO_VID = 0x1050 # Global vendor ID | |
95 | ||
96 | ||
97 | class PID(object): | |
98 | """USB Product IDs""" | |
99 | YUBIKEY = 0x0010 # Yubikey (version 1 and 2) | |
100 | ||
101 | NEO_OTP = 0x0110 # Yubikey NEO - OTP only | |
102 | NEO_OTP_CCID = 0x0111 # Yubikey NEO - OTP and CCID | |
103 | NEO_CCID = 0x0112 # Yubikey NEO - CCID only | |
104 | NEO_U2F = 0x0113 # Yubikey NEO - U2F only | |
105 | NEO_OTP_U2F = 0x0114 # Yubikey NEO - OTP and U2F | |
106 | NEO_U2F_CCID = 0x0115 # Yubikey NEO - U2F and CCID | |
107 | NEO_OTP_U2F_CCID = 0x0116 # Yubikey NEO - OTP, U2F and CCID | |
108 | ||
109 | NEO_SKY = 0x0120 # Security Key by Yubico | |
110 | ||
111 | YK4_OTP = 0x0401 # Yubikey 4 - OTP only | |
112 | YK4_U2F = 0x0402 # Yubikey 4 - U2F only | |
113 | YK4_OTP_U2F = 0x0403 # Yubikey 4 - OTP and U2F | |
114 | YK4_CCID = 0x0404 # Yubikey 4 - CCID only | |
115 | YK4_OTP_CCID = 0x0405 # Yubikey 4 - OTP and CCID | |
116 | YK4_U2F_CCID = 0x0406 # Yubikey 4 - U2F and CCID | |
117 | YK4_OTP_U2F_CCID = 0x0407 # Yubikey 4 - OTP, U2F and CCID | |
118 | ||
119 | PLUS_U2F_OTP = 0x0410 # Yubikey plus - OTP+U2F | |
120 | ||
121 | @classmethod | |
122 | def all(cls, otp=False, ccid=False, u2f=False): | |
123 | """Returns a set of all PIDs, with optional filtering""" | |
124 | pids = { | |
125 | cls.YUBIKEY, | |
126 | cls.NEO_OTP, | |
127 | cls.NEO_OTP_CCID, | |
128 | cls.NEO_CCID, | |
129 | cls.NEO_U2F, | |
130 | cls.NEO_OTP_U2F, | |
131 | cls.NEO_U2F_CCID, | |
132 | cls.NEO_OTP_U2F_CCID, | |
133 | cls.NEO_SKY, | |
134 | cls.YK4_OTP, | |
135 | cls.YK4_U2F, | |
136 | cls.YK4_OTP_U2F, | |
137 | cls.YK4_CCID, | |
138 | cls.YK4_OTP_CCID, | |
139 | cls.YK4_U2F_CCID, | |
140 | cls.YK4_OTP_U2F_CCID, | |
141 | cls.PLUS_U2F_OTP | |
142 | } | |
143 | ||
144 | if otp: | |
145 | pids.difference_update({ | |
146 | cls.NEO_CCID, | |
147 | cls.NEO_U2F, | |
148 | cls.NEO_U2F_CCID, | |
149 | cls.NEO_SKY, | |
150 | cls.YK4_U2F, | |
151 | cls.YK4_CCID, | |
152 | cls.YK4_U2F_CCID | |
153 | }) | |
154 | ||
155 | if ccid: | |
156 | pids.difference_update({ | |
157 | cls.YUBIKEY, | |
158 | cls.NEO_OTP, | |
159 | cls.NEO_U2F, | |
160 | cls.NEO_OTP_U2F, | |
161 | cls.NEO_SKY, | |
162 | cls.YK4_OTP, | |
163 | cls.YK4_U2F, | |
164 | cls.YK4_OTP_U2F, | |
165 | cls.PLUS_U2F_OTP | |
166 | }) | |
167 | ||
168 | if u2f: | |
169 | pids.difference_update({ | |
170 | cls.YUBIKEY, | |
171 | cls.NEO_OTP, | |
172 | cls.NEO_OTP_CCID, | |
173 | cls.NEO_CCID, | |
174 | cls.YK4_OTP, | |
175 | cls.YK4_CCID, | |
176 | cls.YK4_OTP_CCID | |
177 | }) | |
178 | ||
179 | return pids | |
180 | ||
181 | ||
182 | class YK4_CAPA(object): | |
183 | """Capability bits in the YK4_CAPA field""" | |
184 | OTP = 0x01 # OTP functionality | |
185 | U2F = 0x02 # U2F functionality | |
186 | CCID = 0x04 # CCID functionality | |
187 | ||
188 | class TAG(object): | |
189 | """Tags for TLV data read from the YK4_CAPABILITIES slot""" | |
190 | CAPA = 0x01 # capabilities | |
191 | SERIAL = 0x02 # serial number |
12 | 12 | 'YubiKey4_USBHIDError' |
13 | 13 | ] |
14 | 14 | |
15 | from .ykdef import SLOT, MODE, YK4_CAPA | |
15 | from .yubikey_defs import SLOT, MODE, YK4_CAPA | |
16 | 16 | from . import yubikey_frame |
17 | 17 | from . import yubikey_base |
18 | 18 | from . import yubico_exception |
28 | 28 | from . import yubikey_base |
29 | 29 | |
30 | 30 | # these used to be defined here; import them for backwards compatibility |
31 | from .yubikey_defs import SLOT_CONFIG, SLOT_CONFIG2, SLOT_UPDATE1, SLOT_UPDATE2, SLOT_SWAP, command2str | |
31 | from .yubikey_defs import SLOT, command2str | |
32 | 32 | |
33 | 33 | |
34 | 34 | TicketFlags = [ |
460 | 460 | payload = data.ljust(64, yubico_util.chr_byte(0x0)) |
461 | 461 | if slot is 1: |
462 | 462 | if self._update_config: |
463 | command = SLOT_UPDATE1 | |
463 | command = SLOT.UPDATE1 | |
464 | 464 | else: |
465 | command = SLOT_CONFIG | |
465 | command = SLOT.CONFIG | |
466 | 466 | elif slot is 2: |
467 | 467 | if self._update_config: |
468 | command = SLOT_UPDATE2 | |
468 | command = SLOT.UPDATE2 | |
469 | 469 | else: |
470 | command = SLOT_CONFIG2 | |
470 | command = SLOT.CONFIG2 | |
471 | 471 | else: |
472 | 472 | assert() |
473 | 473 | |
474 | 474 | if self._swap_slots: |
475 | command = SLOT_SWAP | |
475 | command = SLOT.SWAP | |
476 | 476 | |
477 | 477 | if self._zap: |
478 | 478 | payload = b'' |
13 | 13 | 'SHA1_DIGEST_SIZE', |
14 | 14 | 'OTP_CHALRESP_SIZE', |
15 | 15 | 'UID_SIZE', |
16 | 'YUBICO_VID', | |
16 | 17 | # functions |
17 | 18 | # classes |
19 | 'SLOT', | |
20 | 'MODE', | |
21 | 'PID', | |
22 | 'YK4_CAPA' | |
18 | 23 | ] |
19 | 24 | |
20 | 25 | from .yubico_version import __version__ |
31 | 36 | |
32 | 37 | UID_SIZE = 6 # Size of secret ID field |
33 | 38 | |
34 | SLOT_CONFIG = 0x01 # First (default / V1) configuration | |
35 | SLOT_CONFIG2 = 0x03 # Second (V2) configuration | |
36 | SLOT_UPDATE1 = 0x04 # Update slot 1 | |
37 | SLOT_UPDATE2 = 0x05 # Update slot 2 | |
38 | SLOT_SWAP = 0x06 # Swap slot 1 and 2 | |
39 | 39 | |
40 | 40 | def command2str(num): |
41 | 41 | """ Turn command number into name """ |
48 | 48 | if num in known: |
49 | 49 | return known[num] |
50 | 50 | return "0x%02x" % (num) |
51 | ||
52 | ||
53 | class SLOT(object): | |
54 | """Slot entries""" | |
55 | CONFIG = 0x01 # First (default / V1) configuration | |
56 | CONFIG2 = 0x03 # Second (V2) configuration | |
57 | ||
58 | UPDATE1 = 0x04 # Update slot 1 | |
59 | UPDATE2 = 0x05 # Update slot 2 | |
60 | SWAP = 0x06 # Swap slot 1 and 2 | |
61 | ||
62 | NDEF = 0x08 # Write NDEF record | |
63 | NDEF2 = 0x09 # Write NDEF record for slot 2 | |
64 | ||
65 | DEVICE_SERIAL = 0x10 # Device serial number | |
66 | DEVICE_CONFIG = 0x11 # Write device configuration record | |
67 | SCAN_MAP = 0x12 # Write scancode map | |
68 | YK4_CAPABILITIES = 0x13 # Read YK4 capabilities list | |
69 | ||
70 | CHAL_OTP1 = 0x20 # Write 6 byte challenge to slot 1, get Yubico OTP response | |
71 | CHAL_OTP2 = 0x28 # Write 6 byte challenge to slot 2, get Yubico OTP response | |
72 | ||
73 | CHAL_HMAC1 = 0x30 # Write 64 byte challenge to slot 1, get HMAC-SHA1 response | |
74 | CHAL_HMAC2 = 0x38 # Write 64 byte challenge to slot 2, get HMAC-SHA1 response | |
75 | ||
76 | ||
77 | class MODE(object): | |
78 | """USB modes""" | |
79 | OTP = 0x00 # OTP only | |
80 | CCID = 0x01 # CCID only, no eject | |
81 | OTP_CCID = 0x02 # OTP + CCID composite | |
82 | U2F = 0x03 # U2F mode | |
83 | OTP_U2F = 0x04 # OTP + U2F composite | |
84 | U2F_CCID = 0x05 # U2F + U2F composite | |
85 | OTP_U2F_CCID = 0x06 # OTP + U2F + CCID composite | |
86 | MASK = 0x07 # Mask for mode bits | |
87 | FLAG_EJECT = 0x80 # CCID device supports eject (CCID) / OTP force eject (CCID composite) | |
88 | ||
89 | @classmethod | |
90 | def all(cls, otp=False, ccid=False, u2f=False): | |
91 | """Returns a set of all USB modes, with optional filtering""" | |
92 | modes = { | |
93 | cls.OTP, | |
94 | cls.CCID, | |
95 | cls.OTP_CCID, | |
96 | cls.U2F, | |
97 | cls.OTP_U2F, | |
98 | cls.U2F_CCID, | |
99 | cls.OTP_U2F_CCID | |
100 | } | |
101 | ||
102 | if otp: | |
103 | modes.difference_update({ | |
104 | cls.CCID, | |
105 | cls.U2F, | |
106 | cls.U2F_CCID | |
107 | }) | |
108 | ||
109 | if ccid: | |
110 | modes.difference_update({ | |
111 | cls.OTP, | |
112 | cls.U2F, | |
113 | cls.OTP_U2F | |
114 | }) | |
115 | ||
116 | if u2f: | |
117 | modes.difference_update({ | |
118 | cls.OTP, | |
119 | cls.CCID, | |
120 | cls.OTP_CCID | |
121 | }) | |
122 | ||
123 | return modes | |
124 | ||
125 | ||
126 | YUBICO_VID = 0x1050 # Global vendor ID | |
127 | ||
128 | ||
129 | class PID(object): | |
130 | """USB Product IDs""" | |
131 | YUBIKEY = 0x0010 # Yubikey (version 1 and 2) | |
132 | ||
133 | NEO_OTP = 0x0110 # Yubikey NEO - OTP only | |
134 | NEO_OTP_CCID = 0x0111 # Yubikey NEO - OTP and CCID | |
135 | NEO_CCID = 0x0112 # Yubikey NEO - CCID only | |
136 | NEO_U2F = 0x0113 # Yubikey NEO - U2F only | |
137 | NEO_OTP_U2F = 0x0114 # Yubikey NEO - OTP and U2F | |
138 | NEO_U2F_CCID = 0x0115 # Yubikey NEO - U2F and CCID | |
139 | NEO_OTP_U2F_CCID = 0x0116 # Yubikey NEO - OTP, U2F and CCID | |
140 | ||
141 | NEO_SKY = 0x0120 # Security Key by Yubico | |
142 | ||
143 | YK4_OTP = 0x0401 # Yubikey 4 - OTP only | |
144 | YK4_U2F = 0x0402 # Yubikey 4 - U2F only | |
145 | YK4_OTP_U2F = 0x0403 # Yubikey 4 - OTP and U2F | |
146 | YK4_CCID = 0x0404 # Yubikey 4 - CCID only | |
147 | YK4_OTP_CCID = 0x0405 # Yubikey 4 - OTP and CCID | |
148 | YK4_U2F_CCID = 0x0406 # Yubikey 4 - U2F and CCID | |
149 | YK4_OTP_U2F_CCID = 0x0407 # Yubikey 4 - OTP, U2F and CCID | |
150 | ||
151 | PLUS_U2F_OTP = 0x0410 # Yubikey plus - OTP+U2F | |
152 | ||
153 | @classmethod | |
154 | def all(cls, otp=False, ccid=False, u2f=False): | |
155 | """Returns a set of all PIDs, with optional filtering""" | |
156 | pids = { | |
157 | cls.YUBIKEY, | |
158 | cls.NEO_OTP, | |
159 | cls.NEO_OTP_CCID, | |
160 | cls.NEO_CCID, | |
161 | cls.NEO_U2F, | |
162 | cls.NEO_OTP_U2F, | |
163 | cls.NEO_U2F_CCID, | |
164 | cls.NEO_OTP_U2F_CCID, | |
165 | cls.NEO_SKY, | |
166 | cls.YK4_OTP, | |
167 | cls.YK4_U2F, | |
168 | cls.YK4_OTP_U2F, | |
169 | cls.YK4_CCID, | |
170 | cls.YK4_OTP_CCID, | |
171 | cls.YK4_U2F_CCID, | |
172 | cls.YK4_OTP_U2F_CCID, | |
173 | cls.PLUS_U2F_OTP | |
174 | } | |
175 | ||
176 | if otp: | |
177 | pids.difference_update({ | |
178 | cls.NEO_CCID, | |
179 | cls.NEO_U2F, | |
180 | cls.NEO_U2F_CCID, | |
181 | cls.NEO_SKY, | |
182 | cls.YK4_U2F, | |
183 | cls.YK4_CCID, | |
184 | cls.YK4_U2F_CCID | |
185 | }) | |
186 | ||
187 | if ccid: | |
188 | pids.difference_update({ | |
189 | cls.YUBIKEY, | |
190 | cls.NEO_OTP, | |
191 | cls.NEO_U2F, | |
192 | cls.NEO_OTP_U2F, | |
193 | cls.NEO_SKY, | |
194 | cls.YK4_OTP, | |
195 | cls.YK4_U2F, | |
196 | cls.YK4_OTP_U2F, | |
197 | cls.PLUS_U2F_OTP | |
198 | }) | |
199 | ||
200 | if u2f: | |
201 | pids.difference_update({ | |
202 | cls.YUBIKEY, | |
203 | cls.NEO_OTP, | |
204 | cls.NEO_OTP_CCID, | |
205 | cls.NEO_CCID, | |
206 | cls.YK4_OTP, | |
207 | cls.YK4_CCID, | |
208 | cls.YK4_OTP_CCID | |
209 | }) | |
210 | ||
211 | return pids | |
212 | ||
213 | ||
214 | class YK4_CAPA(object): | |
215 | """Capability bits in the YK4_CAPA field""" | |
216 | OTP = 0x01 # OTP functionality | |
217 | U2F = 0x02 # U2F functionality | |
218 | CCID = 0x04 # CCID functionality | |
219 | ||
220 | class TAG(object): | |
221 | """Tags for TLV data read from the YK4_CAPABILITIES slot""" | |
222 | CAPA = 0x01 # capabilities | |
223 | SERIAL = 0x02 # serial number |
16 | 16 | from . import yubikey_defs |
17 | 17 | from . import yubico_exception |
18 | 18 | from .yubico_version import __version__ |
19 | ||
20 | from .yubikey_defs import SLOT | |
19 | 21 | |
20 | 22 | class YubiKeyFrame: |
21 | 23 | """ |
93 | 95 | """ |
94 | 96 | if not debug: |
95 | 97 | return data |
96 | if self.command in [yubikey_defs.SLOT_CONFIG, | |
97 | yubikey_defs.SLOT_CONFIG2, | |
98 | yubikey_defs.SLOT_UPDATE1, | |
99 | yubikey_defs.SLOT_UPDATE2, | |
100 | yubikey_defs.SLOT_SWAP, | |
101 | ]: | |
98 | if self.command in [ | |
99 | SLOT.CONFIG, | |
100 | SLOT.CONFIG2, | |
101 | SLOT.UPDATE1, | |
102 | SLOT.UPDATE2, | |
103 | SLOT.SWAP, | |
104 | ]: | |
102 | 105 | # annotate according to config_st (see yubikey_defs.to_string()) |
103 | 106 | if yubico_util.ord_byte(data[-1]) == 0x80: |
104 | 107 | return (data, "FFFFFFF") |
17 | 17 | import binascii |
18 | 18 | |
19 | 19 | from .yubico_version import __version__ |
20 | from .ykdef import SLOT, MODE | |
20 | from .yubikey_defs import SLOT, MODE | |
21 | 21 | from . import yubikey_usb_hid |
22 | 22 | from . import yubikey_frame |
23 | 23 | from . import yubico_exception |