0
# Backend Configuration
1
2
Core system configuration for selecting cryptographic backends and FFI libraries. This allows forcing specific implementations when needed for testing, compatibility, or when custom OpenSSL/LibreSSL libraries are required.
3
4
## Capabilities
5
6
### Backend Detection
7
8
Query which cryptographic backend is currently active based on the operating system and configuration.
9
10
```python { .api }
11
def backend() -> str:
12
"""
13
Get the current cryptographic backend name.
14
15
Returns:
16
Backend name: 'openssl' (Linux/BSD), 'mac' (macOS), 'win' (Windows Vista+), 'winlegacy' (Windows XP)
17
"""
18
19
def ffi() -> str:
20
"""
21
Get the current FFI (Foreign Function Interface) library being used.
22
23
Returns:
24
FFI library name: 'cffi' or 'ctypes'
25
"""
26
```
27
28
### OpenSSL Configuration
29
30
Force the use of specific OpenSSL or LibreSSL dynamic libraries instead of system defaults.
31
32
```python { .api }
33
def use_openssl(libcrypto_path: str, libssl_path: str, trust_list_path: str = None) -> None:
34
"""
35
Force use of specific OpenSSL/LibreSSL libraries.
36
37
Parameters:
38
- libcrypto_path: str - Path to libcrypto dynamic library (.so/.dylib/.dll)
39
- libssl_path: str - Path to libssl dynamic library
40
- trust_list_path: str - Optional path to CA certificate bundle (PEM format)
41
42
Raises:
43
ValueError if paths are not unicode strings
44
LibraryNotFoundError if libraries don't exist
45
OSError if trust_list_path doesn't exist
46
RuntimeError if called after oscrypto modules are imported
47
48
Note:
49
Must be called before importing any other oscrypto modules
50
"""
51
```
52
53
### Windows Legacy Mode
54
55
Force the use of legacy Windows CryptoAPI instead of modern CNG on Windows systems.
56
57
```python { .api }
58
def use_winlegacy() -> None:
59
"""
60
Force use of legacy Windows CryptoAPI (Windows XP compatibility).
61
62
Raises:
63
EnvironmentError if called on non-Windows systems
64
RuntimeError if called after oscrypto modules are imported
65
66
Note:
67
Only use for Windows XP support or testing. CNG is preferred on Vista+.
68
Must be called before importing any other oscrypto modules.
69
"""
70
```
71
72
### FFI Configuration
73
74
Force the use of ctypes instead of cffi for the foreign function interface.
75
76
```python { .api }
77
def use_ctypes() -> None:
78
"""
79
Force use of ctypes instead of cffi for FFI operations.
80
81
Raises:
82
RuntimeError if called after oscrypto modules are imported
83
84
Note:
85
Must be called before importing any other oscrypto modules
86
"""
87
```
88
89
### Module Load Order
90
91
Get the dependency order for live code reloading scenarios.
92
93
```python { .api }
94
def load_order() -> List[str]:
95
"""
96
Get the module load order for oscrypto components.
97
98
Returns:
99
List of module names in dependency order for reloading
100
"""
101
```
102
103
## Usage Examples
104
105
### Basic Backend Detection
106
107
```python
108
import oscrypto
109
110
# Check which backend is active
111
backend_name = oscrypto.backend()
112
ffi_name = oscrypto.ffi()
113
114
print(f"Cryptographic backend: {backend_name}")
115
print(f"FFI library: {ffi_name}")
116
117
# Platform-specific behavior
118
if backend_name == 'openssl':
119
print("Using OpenSSL/LibreSSL on Linux/BSD")
120
elif backend_name == 'mac':
121
print("Using Security.framework on macOS")
122
elif backend_name == 'win':
123
print("Using CNG on Windows Vista+")
124
elif backend_name == 'winlegacy':
125
print("Using legacy CryptoAPI on Windows XP")
126
```
127
128
### Custom OpenSSL Configuration
129
130
```python
131
import oscrypto
132
import os
133
134
# Must configure before importing other modules
135
if not any('oscrypto.' in module for module in sys.modules if module.startswith('oscrypto.')):
136
137
# Paths to custom OpenSSL libraries
138
libcrypto_path = "/opt/openssl-3.0/lib/libcrypto.so.3"
139
libssl_path = "/opt/openssl-3.0/lib/libssl.so.3"
140
ca_bundle_path = "/opt/openssl-3.0/certs/ca-bundle.pem"
141
142
# Verify libraries exist
143
if os.path.exists(libcrypto_path) and os.path.exists(libssl_path):
144
# Force specific OpenSSL version
145
oscrypto.use_openssl(libcrypto_path, libssl_path, ca_bundle_path)
146
print(f"Configured to use custom OpenSSL: {libcrypto_path}")
147
else:
148
print("Custom OpenSSL libraries not found, using system default")
149
150
# Now safe to import other modules
151
from oscrypto import asymmetric, tls
152
153
print(f"Backend: {oscrypto.backend()}")
154
```
155
156
### Windows Legacy Mode
157
158
```python
159
import sys
160
import oscrypto
161
162
# Force Windows XP compatibility mode
163
if sys.platform == 'win32':
164
try:
165
# Must be called before other imports
166
oscrypto.use_winlegacy()
167
print("Configured for Windows legacy CryptoAPI mode")
168
except EnvironmentError as e:
169
print(f"Cannot use legacy mode: {e}")
170
except RuntimeError as e:
171
print(f"Too late to configure legacy mode: {e}")
172
173
from oscrypto import asymmetric
174
175
print(f"Backend: {oscrypto.backend()}")
176
```
177
178
### FFI Configuration
179
180
```python
181
import oscrypto
182
183
# Force ctypes usage (useful if cffi has issues)
184
try:
185
oscrypto.use_ctypes()
186
print("Configured to use ctypes for FFI")
187
except RuntimeError as e:
188
print(f"Cannot configure ctypes: {e}")
189
190
from oscrypto import symmetric
191
192
print(f"FFI library: {oscrypto.ffi()}")
193
```
194
195
### Live Reloading Setup
196
197
```python
198
import sys
199
import oscrypto
200
201
def reload_oscrypto():
202
"""Reload oscrypto modules in dependency order."""
203
load_order = oscrypto.load_order()
204
205
# Remove modules in reverse order
206
for module_name in reversed(load_order):
207
if module_name in sys.modules:
208
del sys.modules[module_name]
209
210
# Reimport in correct order
211
for module_name in load_order:
212
try:
213
__import__(module_name)
214
print(f"Reloaded: {module_name}")
215
except ImportError as e:
216
print(f"Failed to reload {module_name}: {e}")
217
218
# Example usage for development
219
if __name__ == "__main__":
220
print("Initial load order:")
221
for module in oscrypto.load_order():
222
print(f" {module}")
223
224
# Perform reload
225
reload_oscrypto()
226
```
227
228
### Configuration Validation
229
230
```python
231
import oscrypto
232
from oscrypto.errors import LibraryNotFoundError
233
234
def validate_configuration():
235
"""Validate current oscrypto configuration."""
236
try:
237
backend = oscrypto.backend()
238
ffi = oscrypto.ffi()
239
240
print(f"✓ Backend: {backend}")
241
print(f"✓ FFI: {ffi}")
242
243
# Test basic functionality
244
from oscrypto.util import rand_bytes
245
test_bytes = rand_bytes(16)
246
print(f"✓ Random generation: {len(test_bytes)} bytes")
247
248
# Test asymmetric operations
249
from oscrypto import asymmetric
250
pub_key, priv_key = asymmetric.generate_pair('rsa', bit_size=1024)
251
print("✓ RSA key generation")
252
253
# Test symmetric operations
254
from oscrypto.symmetric import aes_cbc_pkcs7_encrypt
255
ciphertext = aes_cbc_pkcs7_encrypt(test_bytes, b"test message")
256
print("✓ AES encryption")
257
258
print("Configuration validation successful!")
259
return True
260
261
except LibraryNotFoundError as e:
262
print(f"✗ Library not found: {e}")
263
return False
264
except Exception as e:
265
print(f"✗ Configuration error: {e}")
266
return False
267
268
# Run validation
269
validate_configuration()
270
```