or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

challenge-response.mdconfiguration.mddevice-discovery.mddevice-interface.mdexceptions.mdindex.mdutilities.md

device-interface.mddocs/

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

```