or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

certificate-management.mdcertificate-verification.mdcryptographic-keys.mdindex.mdrand-module.mdssl-connections.md

certificate-verification.mddocs/

0

# Certificate Verification

1

2

Certificate trust store management and verification operations with support for certificate chains, CRL checking, and custom verification policies.

3

4

## Capabilities

5

6

### Certificate Trust Stores

7

8

Manage collections of trusted certificates and certificate revocation lists for verification operations.

9

10

```python { .api }

11

class X509Store:

12

def __init__(self):

13

"""Create new empty certificate store"""

14

15

def add_cert(self, cert: X509):

16

"""

17

Add trusted certificate to store.

18

19

Parameters:

20

- cert: X509 certificate to trust

21

"""

22

23

def add_crl(self, crl):

24

"""

25

Add certificate revocation list.

26

27

Parameters:

28

- crl: Certificate revocation list object

29

"""

30

31

def set_flags(self, flags: int):

32

"""

33

Set verification behavior flags.

34

35

Parameters:

36

- flags: Combination of X509StoreFlags constants

37

"""

38

39

def set_time(self, vfy_time):

40

"""

41

Set verification time for time-sensitive checks.

42

43

Parameters:

44

- vfy_time: datetime object for verification time

45

"""

46

47

def load_locations(self, cafile, capath=None):

48

"""

49

Load CA certificates from file or directory.

50

51

Parameters:

52

- cafile: Path to CA certificate file (PEM format)

53

- capath: Path to directory containing CA certificates

54

"""

55

```

56

57

### Certificate Verification Context

58

59

Perform actual certificate verification against trust stores with detailed error reporting.

60

61

```python { .api }

62

class X509StoreContext:

63

def __init__(self, store: X509Store, certificate: X509, chain=None):

64

"""

65

Create verification context.

66

67

Parameters:

68

- store: Trust store containing CA certificates

69

- certificate: Certificate to verify

70

- chain: Optional list of intermediate certificates

71

"""

72

73

def set_store(self, store: X509Store):

74

"""

75

Change the trust store.

76

77

Parameters:

78

- store: New trust store to use

79

"""

80

81

def verify_certificate(self):

82

"""

83

Verify certificate against store.

84

85

Raises:

86

X509StoreContextError: If verification fails

87

"""

88

89

def get_verified_chain(self) -> list:

90

"""

91

Get complete verified certificate chain.

92

93

Returns:

94

List of X509 certificates from end-entity to root

95

"""

96

```

97

98

### Verification Flags

99

100

Control certificate verification behavior with detailed policy options.

101

102

```python { .api }

103

class X509StoreFlags:

104

CRL_CHECK: int

105

CRL_CHECK_ALL: int

106

IGNORE_CRITICAL: int

107

X509_STRICT: int

108

ALLOW_PROXY_CERTS: int

109

POLICY_CHECK: int

110

EXPLICIT_POLICY: int

111

INHIBIT_MAP: int

112

CHECK_SS_SIGNATURE: int

113

PARTIAL_CHAIN: int

114

```

115

116

### Verification Exceptions

117

118

Detailed error reporting for certificate verification failures.

119

120

```python { .api }

121

class X509StoreContextError(Exception):

122

"""Exception raised when certificate verification fails"""

123

124

certificate: X509 # Certificate that caused the error

125

errors: list # List of detailed error information

126

```

127

128

### Verification Result Codes

129

130

Standard X.509 verification result codes for detailed error analysis.

131

132

```python { .api }

133

# Note: X509VerificationCodes is defined in the SSL module

134

from OpenSSL.SSL import X509VerificationCodes

135

136

class X509VerificationCodes:

137

OK: int

138

ERR_UNABLE_TO_GET_ISSUER_CERT: int

139

ERR_UNABLE_TO_GET_CRL: int

140

ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: int

141

ERR_CERT_SIGNATURE_FAILURE: int

142

ERR_CRL_SIGNATURE_FAILURE: int

143

ERR_CERT_NOT_YET_VALID: int

144

ERR_CERT_HAS_EXPIRED: int

145

ERR_CRL_NOT_YET_VALID: int

146

ERR_CRL_HAS_EXPIRED: int

147

ERR_DEPTH_ZERO_SELF_SIGNED_CERT: int

148

ERR_SELF_SIGNED_CERT_IN_CHAIN: int

149

ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: int

150

ERR_CERT_CHAIN_TOO_LONG: int

151

ERR_CERT_REVOKED: int

152

```

153

154

## Usage Examples

155

156

### Basic Certificate Verification

157

158

```python

159

from OpenSSL import crypto

160

161

# Load certificates

162

with open('ca.crt', 'rb') as f:

163

ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

164

165

with open('server.crt', 'rb') as f:

166

server_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

167

168

# Create trust store and add CA

169

store = crypto.X509Store()

170

store.add_cert(ca_cert)

171

172

# Create verification context

173

context = crypto.X509StoreContext(store, server_cert)

174

175

try:

176

# Verify certificate

177

context.verify_certificate()

178

print("Certificate verification successful")

179

180

# Get verified chain

181

chain = context.get_verified_chain()

182

print(f"Verified chain length: {len(chain)}")

183

184

except crypto.X509StoreContextError as e:

185

print(f"Verification failed: {e}")

186

print(f"Failed certificate: {e.certificate.get_subject().CN}")

187

```

188

189

### Verification with Intermediate Certificates

190

191

```python

192

from OpenSSL import crypto

193

194

# Load certificate chain

195

with open('ca.crt', 'rb') as f:

196

ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

197

198

with open('intermediate.crt', 'rb') as f:

199

intermediate_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

200

201

with open('server.crt', 'rb') as f:

202

server_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

203

204

# Create trust store with root CA

205

store = crypto.X509Store()

206

store.add_cert(ca_cert)

207

208

# Verify with intermediate certificate in chain

209

context = crypto.X509StoreContext(store, server_cert, [intermediate_cert])

210

211

try:

212

context.verify_certificate()

213

print("Chain verification successful")

214

215

# Print full chain

216

chain = context.get_verified_chain()

217

for i, cert in enumerate(chain):

218

print(f"Chain[{i}]: {cert.get_subject().CN}")

219

220

except crypto.X509StoreContextError as e:

221

print(f"Chain verification failed: {e}")

222

```

223

224

### Advanced Verification with Flags

225

226

```python

227

from OpenSSL import crypto

228

import datetime

229

230

# Create store with custom flags

231

store = crypto.X509Store()

232

233

# Enable strict checking and CRL validation

234

flags = (crypto.X509StoreFlags.X509_STRICT |

235

crypto.X509StoreFlags.CRL_CHECK_ALL)

236

store.set_flags(flags)

237

238

# Set specific verification time

239

verification_time = datetime.datetime(2023, 6, 1)

240

store.set_time(verification_time)

241

242

# Load CA certificates from directory

243

store.load_locations(None, '/etc/ssl/certs')

244

245

# Add specific trusted certificate

246

with open('trusted.crt', 'rb') as f:

247

trusted_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

248

store.add_cert(trusted_cert)

249

250

# Verify certificate with strict policies

251

with open('test.crt', 'rb') as f:

252

test_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

253

254

context = crypto.X509StoreContext(store, test_cert)

255

256

try:

257

context.verify_certificate()

258

print("Strict verification passed")

259

260

except crypto.X509StoreContextError as e:

261

print(f"Strict verification failed: {e}")

262

```

263

264

### Custom Verification Callback

265

266

```python

267

from OpenSSL import SSL, crypto

268

269

def verify_callback(conn, cert, errno, depth, ok):

270

"""

271

Custom certificate verification callback.

272

273

Parameters:

274

- conn: SSL connection object

275

- cert: Certificate being verified

276

- errno: Error number (0 if OK)

277

- depth: Chain depth (0 for end-entity)

278

- ok: OpenSSL's verification result

279

280

Returns:

281

True to accept, False to reject

282

"""

283

subject = cert.get_subject()

284

285

print(f"Verifying: {subject.CN} at depth {depth}")

286

287

if errno == 0:

288

print(" Certificate OK")

289

return True

290

291

# Custom logic for specific errors

292

if errno == crypto.X509VerificationCodes.ERR_CERT_HAS_EXPIRED:

293

print(" Certificate expired - checking grace period")

294

# Could implement grace period logic here

295

return False

296

297

if errno == crypto.X509VerificationCodes.ERR_SELF_SIGNED_CERT_IN_CHAIN:

298

print(" Self-signed certificate in chain")

299

# Could allow self-signed for development

300

return False

301

302

print(f" Verification error: {errno}")

303

return False

304

305

# Use callback in SSL context

306

context = SSL.Context(SSL.TLS_CLIENT_METHOD)

307

context.set_verify(SSL.VERIFY_PEER, verify_callback)

308

context.set_default_verify_paths()

309

```

310

311

### Loading System Certificate Stores

312

313

```python

314

from OpenSSL import crypto

315

import os

316

317

# Create store and load system CA certificates

318

store = crypto.X509Store()

319

320

# Method 1: Load default locations

321

store.load_locations('/etc/ssl/certs/ca-certificates.crt')

322

323

# Method 2: Load from CA bundle

324

ca_bundle_paths = [

325

'/etc/ssl/certs/ca-certificates.crt', # Debian/Ubuntu

326

'/etc/ssl/ca-bundle.pem', # Red Hat/CentOS

327

'/etc/ssl/certs/ca-bundle.crt', # SUSE

328

'/usr/local/share/ca-certificates/', # Local additions

329

]

330

331

for path in ca_bundle_paths:

332

if os.path.exists(path):

333

try:

334

store.load_locations(path)

335

print(f"Loaded CA certificates from {path}")

336

break

337

except Exception as e:

338

print(f"Failed to load from {path}: {e}")

339

340

# Add custom enterprise CA

341

try:

342

with open('/usr/local/share/ca-certificates/enterprise-ca.crt', 'rb') as f:

343

enterprise_ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

344

store.add_cert(enterprise_ca)

345

print("Added enterprise CA certificate")

346

except FileNotFoundError:

347

print("No enterprise CA found")

348

```

349

350

### Verification Error Handling

351

352

```python

353

from OpenSSL import crypto

354

355

def detailed_verification(store, cert, chain=None):

356

"""Perform certificate verification with detailed error reporting"""

357

358

context = crypto.X509StoreContext(store, cert, chain)

359

360

try:

361

context.verify_certificate()

362

print("✓ Certificate verification successful")

363

364

# Show verification details

365

verified_chain = context.get_verified_chain()

366

print(f"✓ Verified chain length: {len(verified_chain)}")

367

368

for i, cert in enumerate(verified_chain):

369

subject = cert.get_subject()

370

print(f" [{i}] {subject.CN}")

371

372

return True

373

374

except crypto.X509StoreContextError as e:

375

print("✗ Certificate verification failed")

376

print(f" Error: {e}")

377

378

if hasattr(e, 'certificate'):

379

failed_cert = e.certificate

380

print(f" Failed certificate: {failed_cert.get_subject().CN}")

381

382

# Provide helpful error messages

383

error_messages = {

384

crypto.X509VerificationCodes.ERR_CERT_HAS_EXPIRED:

385

"Certificate has expired - check validity dates",

386

crypto.X509VerificationCodes.ERR_CERT_NOT_YET_VALID:

387

"Certificate is not yet valid - check system time",

388

crypto.X509VerificationCodes.ERR_SELF_SIGNED_CERT_IN_CHAIN:

389

"Self-signed certificate in chain - add to trust store",

390

crypto.X509VerificationCodes.ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:

391

"Missing issuer certificate - add intermediate certificates",

392

}

393

394

# Check specific error codes in the errors list

395

if hasattr(e, 'errors'):

396

for error in e.errors:

397

if error in error_messages:

398

print(f" Suggestion: {error_messages[error]}")

399

400

return False

401

402

# Usage example

403

store = crypto.X509Store()

404

# ... configure store ...

405

406

with open('certificate.crt', 'rb') as f:

407

cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

408

409

detailed_verification(store, cert)

410

```