or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

asymmetric.mdbackend.mdindex.mdkdf.mdkeys.mdsymmetric.mdtls.mdtrust-store.mdutility.md

trust-store.mddocs/

0

# Trust Store Management

1

2

Access and export operating system trust store certificates for use with OpenSSL-based code. Provides CA certificate bundles in PEM format, enabling applications to use OS-managed trust roots with custom TLS implementations.

3

4

```python

5

from oscrypto import trust_list

6

from oscrypto.errors import CACertsError

7

```

8

9

## Capabilities

10

11

### Trust List Access

12

13

Retrieve CA certificates from the operating system's trust store.

14

15

```python { .api }

16

def get_list() -> List[Certificate]:

17

"""

18

Get list of CA certificates from the OS trust store.

19

20

Returns:

21

List of Certificate objects representing trusted CA certificates

22

23

Raises:

24

CACertsError if unable to export certificates from OS trust store

25

"""

26

27

def get_path() -> str:

28

"""

29

Get path to a CA certificate bundle file in PEM format.

30

31

Returns:

32

String path to a temporary PEM file containing CA certificates

33

34

Note:

35

The returned file is cached and may be automatically cleaned up.

36

Copy the file if you need persistent access.

37

"""

38

39

def clear_cache() -> None:

40

"""

41

Clear cached CA certificate data and temporary files.

42

43

Note:

44

Forces regeneration of CA bundle on next access.

45

"""

46

```

47

48

## Usage Examples

49

50

### Basic Trust Store Access

51

52

```python

53

from oscrypto import trust_list

54

55

# Get CA certificates as Certificate objects

56

ca_certs = trust_list.get_list()

57

print(f"Found {len(ca_certs)} CA certificates in OS trust store")

58

59

# Examine a few certificates

60

for i, cert in enumerate(ca_certs[:3]):

61

print(f"CA {i+1}: {cert.subject}")

62

print(f" Issuer: {cert.issuer}")

63

print(f" Valid until: {cert.not_valid_after}")

64

print()

65

```

66

67

### PEM Bundle for OpenSSL

68

69

```python

70

from oscrypto import trust_list

71

import shutil

72

73

# Get path to PEM bundle file

74

pem_path = trust_list.get_path()

75

print(f"CA bundle available at: {pem_path}")

76

77

# Copy to persistent location

78

persistent_path = "/etc/ssl/oscrypto-ca-bundle.pem"

79

try:

80

shutil.copy2(pem_path, persistent_path)

81

print(f"CA bundle copied to: {persistent_path}")

82

except PermissionError:

83

print("Permission denied - run as administrator/root")

84

85

# Read PEM content

86

with open(pem_path, 'r') as f:

87

pem_data = f.read()

88

cert_count = pem_data.count('-----BEGIN CERTIFICATE-----')

89

print(f"PEM bundle contains {cert_count} certificates")

90

```

91

92

### OpenSSL Integration

93

94

```python

95

from oscrypto import trust_list

96

import ssl

97

import socket

98

99

# Get CA bundle path for use with Python's ssl module

100

ca_bundle_path = trust_list.get_path()

101

102

# Create SSL context with OS trust roots

103

context = ssl.create_default_context(cafile=ca_bundle_path)

104

105

# Use with HTTPS connections

106

with socket.create_connection(('www.example.com', 443)) as sock:

107

with context.wrap_socket(sock, server_hostname='www.example.com') as ssock:

108

print(f"SSL version: {ssock.version()}")

109

print(f"Cipher: {ssock.cipher()}")

110

111

# Send HTTP request

112

ssock.send(b'GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n')

113

response = ssock.recv(1024)

114

print(f"Response: {response[:100]}...")

115

```

116

117

### Certificate Analysis

118

119

```python

120

from oscrypto import trust_list

121

from collections import defaultdict

122

import datetime

123

124

def analyze_trust_store():

125

"""Analyze CA certificates in the trust store."""

126

ca_certs = trust_list.get_list()

127

128

# Group by issuer

129

issuers = defaultdict(int)

130

key_sizes = defaultdict(int)

131

expiring_soon = []

132

133

now = datetime.datetime.now()

134

one_year = datetime.timedelta(days=365)

135

136

for cert in ca_certs:

137

# Count by issuer

138

issuer_cn = cert.issuer.get('common_name', 'Unknown')

139

issuers[issuer_cn] += 1

140

141

# Analyze key sizes

142

if hasattr(cert.public_key, 'bit_size'):

143

key_sizes[cert.public_key.bit_size] += 1

144

145

# Check expiration

146

if cert.not_valid_after and cert.not_valid_after < now + one_year:

147

expiring_soon.append((cert.subject.get('common_name', 'Unknown'), cert.not_valid_after))

148

149

print(f"Trust Store Analysis ({len(ca_certs)} certificates)")

150

print("=" * 50)

151

152

print("Top 10 Certificate Issuers:")

153

for issuer, count in sorted(issuers.items(), key=lambda x: x[1], reverse=True)[:10]:

154

print(f" {issuer}: {count} certificates")

155

156

print("\nKey Size Distribution:")

157

for size, count in sorted(key_sizes.items()):

158

print(f" {size}-bit: {count} certificates")

159

160

if expiring_soon:

161

print(f"\nCertificates expiring within 1 year ({len(expiring_soon)}):")

162

for name, expiry in sorted(expiring_soon, key=lambda x: x[1])[:5]:

163

print(f" {name}: expires {expiry.strftime('%Y-%m-%d')}")

164

165

# Run analysis

166

analyze_trust_store()

167

```

168

169

### Custom Trust Root Management

170

171

```python

172

from oscrypto import trust_list, asymmetric

173

import tempfile

174

import os

175

176

def create_custom_ca_bundle(extra_certs_paths: list) -> str:

177

"""Create a custom CA bundle combining OS certs with additional ones."""

178

179

# Get OS CA certificates

180

os_ca_path = trust_list.get_path()

181

182

# Read OS CA bundle

183

with open(os_ca_path, 'r') as f:

184

ca_bundle_content = f.read()

185

186

# Add custom certificates

187

for cert_path in extra_certs_paths:

188

if os.path.exists(cert_path):

189

with open(cert_path, 'rb') as f:

190

cert_data = f.read()

191

192

# Load and validate certificate

193

try:

194

cert = asymmetric.load_certificate(cert_data)

195

print(f"Adding custom CA: {cert.subject}")

196

197

# Convert to PEM if needed

198

if cert_data.startswith(b'-----BEGIN'):

199

ca_bundle_content += "\n" + cert_data.decode('utf-8')

200

else:

201

# Convert DER to PEM

202

pem_cert = asymmetric.dump_certificate(cert)

203

pem_lines = [

204

"-----BEGIN CERTIFICATE-----",

205

pem_cert.b64encode().decode('ascii'),

206

"-----END CERTIFICATE-----"

207

]

208

ca_bundle_content += "\n" + "\n".join(pem_lines) + "\n"

209

210

except Exception as e:

211

print(f"Failed to load certificate {cert_path}: {e}")

212

213

# Write combined bundle to temporary file

214

with tempfile.NamedTemporaryFile(mode='w', suffix='.pem', delete=False) as f:

215

f.write(ca_bundle_content)

216

custom_bundle_path = f.name

217

218

print(f"Custom CA bundle created: {custom_bundle_path}")

219

return custom_bundle_path

220

221

# Example usage

222

custom_certs = [

223

'/path/to/internal-ca.pem',

224

'/path/to/test-ca.crt'

225

]

226

227

custom_bundle = create_custom_ca_bundle(custom_certs)

228

```

229

230

### Cache Management

231

232

```python

233

from oscrypto import trust_list

234

import time

235

import os

236

237

def demonstrate_caching():

238

"""Demonstrate trust store caching behavior."""

239

240

print("Initial trust store access...")

241

start_time = time.time()

242

ca_path1 = trust_list.get_path()

243

initial_time = time.time() - start_time

244

print(f"First access took {initial_time:.3f} seconds")

245

print(f"Bundle path: {ca_path1}")

246

print(f"Bundle size: {os.path.getsize(ca_path1)} bytes")

247

248

print("\nSecond access (cached)...")

249

start_time = time.time()

250

ca_path2 = trust_list.get_path()

251

cached_time = time.time() - start_time

252

print(f"Cached access took {cached_time:.3f} seconds")

253

print(f"Same path: {ca_path1 == ca_path2}")

254

255

print(f"\nCaching speedup: {initial_time / cached_time:.1f}x faster")

256

257

print("\nClearing cache...")

258

trust_list.clear_cache()

259

260

print("Post-clear access...")

261

start_time = time.time()

262

ca_path3 = trust_list.get_path()

263

refresh_time = time.time() - start_time

264

print(f"Post-clear access took {refresh_time:.3f} seconds")

265

print(f"New path: {ca_path3}")

266

267

# Run caching demonstration

268

demonstrate_caching()

269

```