0
# YubiKey Device Interface
1
2
Core YubiKey device operations including version detection, serial number retrieval, device status queries, and basic device communication available across all YubiKey models.
3
4
## Capabilities
5
6
### Device Information
7
8
Methods for retrieving basic device information and capabilities.
9
10
```python { .api }
11
class YubiKey:
12
def version(self):
13
"""
14
Get YubiKey firmware version as string.
15
16
Returns:
17
str: Version string (e.g., "1.3.0", "2.3.1", "4.3.7")
18
"""
19
20
def version_num(self):
21
"""
22
Get YubiKey firmware version as tuple.
23
24
Available on USB HID implementations.
25
26
Returns:
27
tuple: Version tuple (major, minor, build)
28
"""
29
30
def serial(self, may_block=True):
31
"""
32
Get YubiKey serial number.
33
34
Available on YubiKey 2.2 and later. May block waiting for user touch
35
on some YubiKey models.
36
37
Parameters:
38
- may_block (bool): Allow blocking operations that may require user interaction
39
40
Returns:
41
int: Device serial number
42
43
Raises:
44
YubiKeyVersionError: If device doesn't support serial number reading
45
YubiKeyTimeout: If operation times out waiting for user interaction
46
"""
47
```
48
49
Usage examples:
50
51
```python
52
import yubico
53
54
yk = yubico.find_yubikey()
55
56
# Get version information
57
print("Version string:", yk.version())
58
if hasattr(yk, 'version_num'):
59
print("Version tuple:", yk.version_num())
60
61
# Get serial number (may require user touch)
62
try:
63
serial = yk.serial()
64
print("Serial number:", serial)
65
except yubico.yubikey_base.YubiKeyVersionError:
66
print("This YubiKey doesn't support serial number reading")
67
except yubico.yubikey_base.YubiKeyTimeout:
68
print("Timeout waiting for user interaction")
69
```
70
71
### Device Status
72
73
Retrieve detailed device status information including configuration state and capabilities.
74
75
```python { .api }
76
class YubiKeyUSBHID(YubiKey):
77
def status(self):
78
"""
79
Poll YubiKey for status information.
80
81
Returns:
82
YubiKeyUSBHIDStatus: Status object with device information
83
"""
84
85
class YubiKeyUSBHIDStatus:
86
def __init__(self, data):
87
"""
88
Initialize status object from raw device data.
89
90
Parameters:
91
- data (bytes): Raw status data from device
92
"""
93
94
def ykver(self):
95
"""
96
Get YubiKey firmware version as tuple.
97
98
Returns:
99
tuple: Version tuple (major, minor, build)
100
"""
101
102
def version(self):
103
"""
104
Get YubiKey firmware version as string.
105
106
Returns:
107
str: Version string
108
"""
109
110
def valid_configs(self):
111
"""
112
Get list of configuration slots that have valid configurations.
113
114
Returns:
115
list: List of slot numbers with valid configurations
116
"""
117
```
118
119
Status usage example:
120
121
```python
122
import yubico
123
124
yk = yubico.find_yubikey()
125
status = yk.status()
126
127
print("Firmware version:", status.version())
128
print("Version tuple:", status.ykver())
129
print("Valid config slots:", status.valid_configs())
130
```
131
132
### Challenge-Response Operations
133
134
Perform challenge-response authentication using HMAC-SHA1 or Yubico protocols.
135
136
```python { .api }
137
def challenge_response(challenge, mode='HMAC', slot=1, variable=True, may_block=True):
138
"""
139
Issue challenge to YubiKey and return response.
140
141
Available on YubiKey 2.2 and later for challenge-response configurations.
142
143
Parameters:
144
- challenge (bytes): Challenge data (up to 64 bytes for HMAC, 6 bytes for OTP)
145
- mode (str): Challenge mode - 'HMAC' for HMAC-SHA1 or 'OTP' for Yubico
146
- slot (int): Configuration slot number (1 or 2)
147
- variable (bool): Variable length response (HMAC mode only)
148
- may_block (bool): Allow operations that may require user interaction
149
150
Returns:
151
bytes: Response data (20 bytes for HMAC, 16 bytes for OTP)
152
153
Raises:
154
YubiKeyVersionError: If device doesn't support challenge-response
155
YubiKeyTimeout: If operation times out
156
InputError: If challenge data is invalid
157
"""
158
```
159
160
Challenge-response usage example:
161
162
```python
163
import yubico
164
import binascii
165
166
yk = yubico.find_yubikey()
167
168
# HMAC-SHA1 challenge-response
169
challenge = b"test challenge data"
170
try:
171
response = yk.challenge_response(challenge, mode='HMAC', slot=1)
172
print("HMAC response:", binascii.hexlify(response).decode())
173
except yubico.yubikey_base.YubiKeyVersionError:
174
print("Device doesn't support challenge-response")
175
176
# Yubico OTP challenge-response (6-byte challenge)
177
otp_challenge = b"123456"
178
try:
179
otp_response = yk.challenge_response(otp_challenge, mode='OTP', slot=2)
180
print("OTP response:", binascii.hexlify(otp_response).decode())
181
except yubico.yubikey_base.YubiKeyVersionError:
182
print("OTP challenge-response not configured")
183
```
184
185
### Configuration Management
186
187
Write configuration objects to YubiKey slots.
188
189
```python { .api }
190
def write_config(cfg, slot):
191
"""
192
Write configuration to YubiKey slot.
193
194
Parameters:
195
- cfg (YubiKeyConfig): Configuration object to write
196
- slot (int): Target configuration slot (1 or 2, or use SLOT constants)
197
198
Raises:
199
YubiKeyError: If configuration write fails
200
YubiKeyVersionError: If device doesn't support the configuration
201
"""
202
203
def init_config(self, **kwargs):
204
"""
205
Initialize configuration object for this YubiKey type.
206
207
Parameters:
208
- **kwargs: Configuration parameters passed to YubiKeyConfig constructor
209
210
Returns:
211
YubiKeyConfig: Configuration object compatible with this device
212
"""
213
```
214
215
Configuration usage example:
216
217
```python
218
import yubico
219
from yubico.yubikey_config import YubiKeyConfig
220
221
yk = yubico.find_yubikey()
222
223
# Create and write configuration
224
cfg = yk.init_config()
225
cfg.mode_challenge_response(
226
secret=b"0123456789abcdef0123456789abcdef",
227
type='HMAC',
228
variable=True
229
)
230
231
try:
232
yk.write_config(cfg, slot=1)
233
print("Configuration written successfully")
234
except yubico.yubikey_base.YubiKeyError as e:
235
print(f"Configuration failed: {e.reason}")
236
```
237
238
### Device-Specific Features
239
240
Additional features available on specific YubiKey models.
241
242
#### YubiKey NEO Features
243
244
```python { .api }
245
class YubiKeyNEO_USBHID(YubiKeyUSBHID):
246
def write_ndef(self, ndef, slot=1):
247
"""
248
Write NDEF tag configuration to YubiKey NEO.
249
250
Parameters:
251
- ndef (YubiKeyNEO_NDEF): NDEF configuration object
252
- slot (int): Configuration slot
253
"""
254
255
def write_device_config(self, device_config):
256
"""
257
Write device configuration to YubiKey NEO.
258
259
Parameters:
260
- device_config (YubiKeyNEO_DEVICE_CONFIG): Device configuration object
261
"""
262
263
def write_scan_map(self, scanmap=None):
264
"""
265
Write scancode map to YubiKey NEO.
266
267
Parameters:
268
- scanmap (YubiKeyNEO_SCAN_MAP): Scancode map configuration
269
"""
270
```
271
272
NEO-specific usage example:
273
274
```python
275
import yubico
276
from yubico.yubikey_neo_usb_hid import YubiKeyNEO_NDEF, YubiKeyNEO_DEVICE_CONFIG
277
278
yk = yubico.find_yubikey()
279
280
# Check if this is a NEO device
281
if isinstance(yk, yubico.yubikey_neo_usb_hid.YubiKeyNEO_USBHID):
282
# Configure NDEF tag
283
ndef = YubiKeyNEO_NDEF("https://example.com/auth")
284
ndef.type(url=True)
285
yk.write_ndef(ndef)
286
287
# Configure device settings
288
device_config = YubiKeyNEO_DEVICE_CONFIG()
289
device_config.cr_timeout(60) # 60 second timeout
290
yk.write_device_config(device_config)
291
```
292
293
## Device Capabilities
294
295
Query device capabilities to determine supported features.
296
297
```python { .api }
298
class YubiKeyCapabilities:
299
def have_yubico_OTP(self):
300
"""Check if device supports Yubico OTP mode."""
301
302
def have_OATH(self, mode):
303
"""Check if device supports OATH mode."""
304
305
def have_challenge_response(self, mode):
306
"""Check if device supports challenge-response mode."""
307
308
def have_serial_number(self):
309
"""Check if device supports serial number reading."""
310
311
def have_ticket_flag(self, flag):
312
"""Check if device supports specific ticket flag."""
313
314
def have_config_flag(self, flag):
315
"""Check if device supports specific config flag."""
316
317
def have_extended_flag(self, flag):
318
"""Check if device supports specific extended flag."""
319
```
320
321
Capabilities usage example:
322
323
```python
324
import yubico
325
326
yk = yubico.find_yubikey()
327
caps = yk.capabilities if hasattr(yk, 'capabilities') else None
328
329
if caps:
330
if caps.have_challenge_response('HMAC'):
331
print("Device supports HMAC challenge-response")
332
if caps.have_serial_number():
333
print("Device supports serial number reading")
334
if caps.have_OATH('HOTP'):
335
print("Device supports OATH-HOTP")
336
```