Lines 35-40
Link Here
|
35 |
*/ |
35 |
*/ |
36 |
|
36 |
|
37 |
|
37 |
|
|
|
38 |
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) |
39 |
static void ssl_ossle_child_init(apr_pool_t *p, server_rec *base_server); |
40 |
#endif |
41 |
|
38 |
static void ssl_add_version_components(apr_pool_t *p, |
42 |
static void ssl_add_version_components(apr_pool_t *p, |
39 |
server_rec *s) |
43 |
server_rec *s) |
40 |
{ |
44 |
{ |
Lines 51-57
Link Here
|
51 |
modver, AP_SERVER_BASEVERSION, incver); |
55 |
modver, AP_SERVER_BASEVERSION, incver); |
52 |
} |
56 |
} |
53 |
|
57 |
|
|
|
58 |
/* |
59 |
* centralized engine loading & configuration |
60 |
*/ |
61 |
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) |
62 |
void ssl_ossle_release_engine(server_rec *s) |
63 |
{ |
64 |
SSLModConfigRec *mc = myModConfig(s); |
65 |
if (!mc->engine) |
66 |
return; |
54 |
|
67 |
|
|
|
68 |
/* unload any dynamic engines pulled in by CONF_modules_load_file, |
69 |
* but don't unload the built in engines */ |
70 |
CONF_modules_unload(0); |
71 |
|
72 |
/* Releases all the references retained via ssl_ossl_get_engine */ |
73 |
ENGINE_finish(mc->engine); |
74 |
|
75 |
mc->engine = 0; |
76 |
} |
77 |
|
78 |
ENGINE * ssl_ossle_get_engine( |
79 |
server_rec *s, |
80 |
const char* enginename, |
81 |
const char* opensslcnf, |
82 |
int disablecnf) |
83 |
{ |
84 |
SSLModConfigRec *mc = myModConfig(s); |
85 |
ENGINE *e = 0; |
86 |
int conf_modules = 0; |
87 |
int funct_ref = 0; |
88 |
|
89 |
if (mc->engine) { |
90 |
return mc->engine; |
91 |
} |
92 |
|
93 |
/* CONF_modules_load_file allows for the declaration of engine names, and |
94 |
* associated parameters, in an openssl formated configuration file. |
95 |
* opensslcnf may be NULL, in which case openssl's default cofniguration |
96 |
* file is used automaticaly. (Eg, "/etc/ssl/openssl.cnf"). |
97 |
* |
98 |
* To completely disable openssl config processing pass NULL for |
99 |
* `opensslcnf' and set `disablecnf' to any non zero value. */ |
100 |
|
101 |
if (!disablecnf && CONF_modules_load_file(opensslcnf, 0, 0) <= 0) |
102 |
{ |
103 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
104 |
"Init: Failed to load openssl config file `%s'", |
105 |
opensslcnf |
106 |
); |
107 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); |
108 |
goto x_fail; |
109 |
} |
110 |
if (!disablecnf) |
111 |
conf_modules = 1; |
112 |
|
113 |
/* side effect: aquires an additional `structure ref' */ |
114 |
e = ENGINE_by_id(enginename); |
115 |
if (!e) |
116 |
goto x_fail; |
117 |
ENGINE_free(e); /* drop the struct_ref taken out by ENGINE_by_id */ |
118 |
|
119 |
/* Take out a functional reference, all user configuration is handled in |
120 |
* openssl.cnf and is now complete, so ENGINE_init can succede if the |
121 |
* chosen engine has been configured appropriately. */ |
122 |
if (!(funct_ref = ENGINE_init(e))) |
123 |
goto x_fail; |
124 |
|
125 |
/* Remove our engine from openssl's internal list and drop the associated |
126 |
* reference. This means ENGINE_by_id will no longer succede and hence |
127 |
* can't cause further reference counting hell. */ |
128 |
if (!ENGINE_remove(e)) { |
129 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
130 |
"Init: Failed to apply engine configuration `%s' `%s'", |
131 |
enginename, opensslcnf |
132 |
); |
133 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); |
134 |
goto x_fail; |
135 |
} |
136 |
|
137 |
mc->engine = e; |
138 |
|
139 |
return mc->engine; |
140 |
|
141 |
x_fail: |
142 |
if (e) { |
143 |
if (funct_ref) |
144 |
ENGINE_finish(e); |
145 |
} |
146 |
if (conf_modules) { |
147 |
/* unload any dynamic engines pulled in by CONF_modules_load_file, |
148 |
* but don't unload the built in engines. */ |
149 |
CONF_modules_unload(0); |
150 |
} |
151 |
|
152 |
return NULL; |
153 |
} |
154 |
|
155 |
/* ssl_ossle_load_cert_engine_pkcs11 |
156 |
* |
157 |
* This is specific to the engine_pkcs11 wrapper provided by the opensc |
158 |
* project. more general support *is* possible but lets get some feed back |
159 |
* before writing a tone of code. |
160 |
*/ |
161 |
X509* ssl_ossle_load_cert_engine_pkcs11(server_rec *s, const char *identifier) |
162 |
{ |
163 |
int cmdno; |
164 |
struct { |
165 |
const char *identifier; |
166 |
void *cert; |
167 |
} param = {identifier, 0}; |
168 |
|
169 |
SSLModConfigRec *mc = myModConfig(s); |
170 |
if (!mc->engine) |
171 |
return NULL; |
172 |
|
173 |
cmdno = ENGINE_ctrl(mc->engine, |
174 |
ENGINE_CTRL_GET_CMD_FROM_NAME, -1, "LOAD_CERT_CTRL", 0); |
175 |
/* XXX: check the value of cmdno */ |
176 |
ENGINE_ctrl(mc->engine, cmdno, -1, ¶m, 0); |
177 |
|
178 |
return (X509*)param.cert; |
179 |
} |
180 |
#endif |
181 |
|
55 |
/* |
182 |
/* |
56 |
* Handle the Temporary RSA Keys and DH Params |
183 |
* Handle the Temporary RSA Keys and DH Params |
57 |
*/ |
184 |
*/ |
Lines 210-249
Link Here
|
210 |
|
337 |
|
211 |
} |
338 |
} |
212 |
|
339 |
|
|
|
340 |
/* XXX: This part of the engine_managed_keys patch is *very* much |
341 |
* in need of an additional config directive. Not all engine |
342 |
* implementations are sensitive to the process context issues |
343 |
* described in "Applications and processes" at p17 v2.20 6.6.1 |
344 |
* of the PKCS #11 standard. |
345 |
* |
346 |
* In the interests of distilling the patch to its essentials whilst |
347 |
* clearly highlighting the issues I have simply deleted the |
348 |
* initialisation steps that have been moved to ssl_init_Child. The |
349 |
* negative diffs in this function are those things that should be gated |
350 |
* on SSLPKCS11ProcessModel or some equivalent. BUT NOTE that |
351 |
* ssl_mutex_init has *not* been removed. It now comes just after |
352 |
* ssl_util_thread_setup. |
353 |
* |
354 |
* The calls that have been moved are (in order): |
355 |
* ssl_init_Engine |
356 |
* ssl_rand_seed |
357 |
* ssl_pphrase_Handle |
358 |
* ssl_tmp_keys_init |
359 |
* ssl_init_ConfigureServer (The whole "initialize servers" loop) |
360 |
*/ |
361 |
|
213 |
#if APR_HAS_THREADS |
362 |
#if APR_HAS_THREADS |
214 |
ssl_util_thread_setup(p); |
363 |
ssl_util_thread_setup(p); |
215 |
#endif |
364 |
#endif |
216 |
|
365 |
|
217 |
/* |
366 |
/* |
218 |
* SSL external crypto device ("engine") support |
|
|
219 |
*/ |
220 |
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) |
221 |
ssl_init_Engine(base_server, p); |
222 |
#endif |
223 |
|
224 |
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, |
225 |
"Init: Initialized %s library", SSL_LIBRARY_NAME); |
226 |
|
227 |
/* |
228 |
* Seed the Pseudo Random Number Generator (PRNG) |
229 |
* only need ptemp here; nothing inside allocated from the pool |
230 |
* needs to live once we return from ssl_rand_seed(). |
231 |
*/ |
232 |
ssl_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init: "); |
233 |
|
234 |
/* |
235 |
* read server private keys/public certs into memory. |
236 |
* decrypting any encrypted keys via configured SSLPassPhraseDialogs |
237 |
* anything that needs to live longer than ptemp needs to also survive |
238 |
* restarts, in which case they'll live inside s->process->pool. |
239 |
*/ |
240 |
ssl_pphrase_Handle(base_server, ptemp); |
241 |
|
242 |
if (ssl_tmp_keys_init(base_server)) { |
243 |
return !OK; |
244 |
} |
245 |
|
246 |
/* |
247 |
* initialize the mutex handling |
367 |
* initialize the mutex handling |
248 |
*/ |
368 |
*/ |
249 |
if (!ssl_mutex_init(base_server, p)) { |
369 |
if (!ssl_mutex_init(base_server, p)) { |
Lines 256-281
Link Here
|
256 |
ssl_scache_init(base_server, p); |
376 |
ssl_scache_init(base_server, p); |
257 |
|
377 |
|
258 |
/* |
378 |
/* |
259 |
* initialize servers |
|
|
260 |
*/ |
261 |
ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, |
262 |
"Init: Initializing (virtual) servers for SSL"); |
263 |
|
264 |
for (s = base_server; s; s = s->next) { |
265 |
sc = mySrvConfig(s); |
266 |
/* |
267 |
* Either now skip this server when SSL is disabled for |
268 |
* it or give out some information about what we're |
269 |
* configuring. |
270 |
*/ |
271 |
|
272 |
/* |
273 |
* Read the server certificate and key |
274 |
*/ |
275 |
ssl_init_ConfigureServer(s, p, ptemp, sc); |
276 |
} |
277 |
|
278 |
/* |
279 |
* Configuration consistency checks |
379 |
* Configuration consistency checks |
280 |
*/ |
380 |
*/ |
281 |
ssl_init_CheckServers(base_server, ptemp); |
381 |
ssl_init_CheckServers(base_server, ptemp); |
Lines 286-291
Link Here
|
286 |
*/ |
386 |
*/ |
287 |
ssl_add_version_components(p, base_server); |
387 |
ssl_add_version_components(p, base_server); |
288 |
|
388 |
|
|
|
389 |
|
390 |
/* WRT engine_managed_keys: I'm not certain what to do about this |
391 |
* particular piece of openssl nastiness. Ignoring it seems to works in |
392 |
* my case. Thoughts anyone ? |
393 |
*/ |
289 |
SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */ |
394 |
SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */ |
290 |
|
395 |
|
291 |
return OK; |
396 |
return OK; |
Lines 302-308
Link Here
|
302 |
ENGINE *e; |
407 |
ENGINE *e; |
303 |
|
408 |
|
304 |
if (mc->szCryptoDevice) { |
409 |
if (mc->szCryptoDevice) { |
305 |
if (!(e = ENGINE_by_id(mc->szCryptoDevice))) { |
410 |
if (!(e = ssl_ossle_get_engine(s, mc->szCryptoDevice, NULL, 0))) { |
306 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
411 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
307 |
"Init: Failed to load Crypto Device API `%s'", |
412 |
"Init: Failed to load Crypto Device API `%s'", |
308 |
mc->szCryptoDevice); |
413 |
mc->szCryptoDevice); |
Lines 321-328
Link Here
|
321 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); |
426 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); |
322 |
ssl_die(); |
427 |
ssl_die(); |
323 |
} |
428 |
} |
324 |
|
|
|
325 |
ENGINE_free(e); |
326 |
} |
429 |
} |
327 |
} |
430 |
} |
328 |
#endif |
431 |
#endif |
Lines 772-784
Link Here
|
772 |
"Configuring %s server private key", type); |
875 |
"Configuring %s server private key", type); |
773 |
|
876 |
|
774 |
ptr = asn1->cpData; |
877 |
ptr = asn1->cpData; |
775 |
if (!(pkey = d2i_PrivateKey(pkey_type, NULL, &ptr, asn1->nData))) |
878 |
if (!mc->engine) { |
776 |
{ |
879 |
if (!(pkey = d2i_PrivateKey(pkey_type, NULL, &ptr, asn1->nData))) |
777 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
880 |
{ |
778 |
"Unable to import %s server private key", type); |
881 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
779 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); |
882 |
"Unable to import %s server private key", type); |
780 |
ssl_die(); |
883 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); |
|
|
884 |
ssl_die(); |
885 |
} |
781 |
} |
886 |
} |
|
|
887 |
else { |
888 |
/* cpData is a null terminated character string */ |
889 |
if(!(pkey = ENGINE_load_private_key( |
890 |
mc->engine, (char*)asn1->cpData, 0 /*ui_method*/, 0 /*cbdata*/))) { |
891 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
892 |
"Unable to import (ENGINE) %s server private key", type); |
893 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); |
894 |
ssl_die(); |
895 |
} |
896 |
} |
782 |
|
897 |
|
783 |
if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) { |
898 |
if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) { |
784 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
899 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
Lines 1202-1207
Link Here
|
1202 |
|
1317 |
|
1203 |
/* open the mutex lockfile */ |
1318 |
/* open the mutex lockfile */ |
1204 |
ssl_mutex_reinit(s, p); |
1319 |
ssl_mutex_reinit(s, p); |
|
|
1320 |
|
1321 |
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) |
1322 |
ssl_ossle_child_init(p, s); |
1323 |
#endif /*if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)*/ |
1205 |
} |
1324 |
} |
1206 |
|
1325 |
|
1207 |
#define MODSSL_CFG_ITEM_FREE(func, item) \ |
1326 |
#define MODSSL_CFG_ITEM_FREE(func, item) \ |
Lines 1242-1275
Link Here
|
1242 |
} |
1361 |
} |
1243 |
} |
1362 |
} |
1244 |
|
1363 |
|
1245 |
apr_status_t ssl_init_ModuleKill(void *data) |
1364 |
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) |
|
|
1365 |
static apr_status_t ssl_ossle_child_exit(server_rec* s) |
1246 |
{ |
1366 |
{ |
1247 |
SSLSrvConfigRec *sc; |
1367 |
SSLSrvConfigRec *sc = mySrvConfig(s); |
1248 |
server_rec *base_server = (server_rec *)data; |
1368 |
SSLModConfigRec *mc = myModConfig(s); |
|
|
1369 |
|
1370 |
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, |
1371 |
"Begin child process engine cleanup: pid=`%d' engine=`%s'", |
1372 |
mc->pid, mc->szCryptoDevice); |
1373 |
ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, s); |
1374 |
|
1375 |
ssl_tmp_keys_free(s); |
1376 |
ssl_init_ctx_cleanup_proxy(sc->proxy); |
1377 |
ssl_init_ctx_cleanup_server(sc->server); |
1378 |
EVP_cleanup(); |
1379 |
|
1380 |
ssl_ossle_release_engine(s); |
1381 |
|
1382 |
CRYPTO_cleanup_all_ex_data(); |
1383 |
|
1384 |
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, |
1385 |
"Completed child process engine cleanup: pid=`%d' engine=`%s'", |
1386 |
mc->pid, mc->szCryptoDevice); |
1387 |
ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, s); |
1388 |
|
1389 |
return APR_SUCCESS; |
1390 |
} |
1391 |
|
1392 |
static apr_status_t ssl_child_exit(void *data) |
1393 |
{ |
1394 |
return ssl_ossle_child_exit((server_rec *)data); |
1395 |
} |
1396 |
|
1397 |
static void ssl_ossle_child_init(apr_pool_t *p, server_rec *base_server) |
1398 |
{ |
1249 |
server_rec *s; |
1399 |
server_rec *s; |
|
|
1400 |
SSLSrvConfigRec *sc = mySrvConfig(base_server); |
1401 |
SSLModConfigRec *mc = myModConfig(base_server); |
1402 |
ENGINE *e; |
1403 |
apr_pool_t *ptemp; |
1250 |
|
1404 |
|
1251 |
/* |
1405 |
/* XXX: TODO: some means to apply the pkcs11 rules only to those |
1252 |
* Drop the session cache and mutex |
1406 |
* engine implementations that care. */ |
1253 |
*/ |
1407 |
if (!mc->szCryptoDevice) |
1254 |
ssl_scache_kill(base_server); |
1408 |
return; |
1255 |
|
1409 |
|
1256 |
/* |
1410 |
if (mc->engine) { |
1257 |
* Destroy the temporary keys and params |
1411 |
/* Complain loudly, but don't die, if the parent process has |
|
|
1412 |
* initialized the engine. */ |
1413 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, |
1414 |
"Init(child): Crypto Device API `%s' loaded by parent " |
1415 |
"process. This breaks pkcs11 rules (v 2.20 6.6.1). " |
1416 |
"Expect problems if your engine is wrapping a pkcs11 " |
1417 |
"implementation.", |
1418 |
mc->szCryptoDevice); |
1419 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, base_server); |
1420 |
return; |
1421 |
} |
1422 |
|
1423 |
ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, |
1424 |
"Begin child process engine initialization: pid=`%d' engine=`%s'", |
1425 |
mc->pid, mc->szCryptoDevice); |
1426 |
ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, base_server); |
1427 |
|
1428 |
|
1429 |
apr_pool_create(&ptemp, p); |
1430 |
apr_pool_tag(ptemp, "ptemp"); |
1431 |
|
1432 |
if (!(e = ssl_ossle_get_engine(base_server, mc->szCryptoDevice, |
1433 |
NULL, 0))) { |
1434 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, |
1435 |
"Init(child): Failed to load Crypto Device API `%s'", |
1436 |
mc->szCryptoDevice); |
1437 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, base_server); |
1438 |
ssl_die(); |
1439 |
} |
1440 |
if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { |
1441 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, |
1442 |
"Init(child): Failed to enable Crypto Device API `%s'", |
1443 |
mc->szCryptoDevice); |
1444 |
ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, base_server); |
1445 |
ssl_die(); |
1446 |
} |
1447 |
|
1448 |
ssl_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init(child): "); |
1449 |
|
1450 |
/* XXX: This assumes the backend supporting the engine can deal sensibly |
1451 |
* with key import on behalf of a multi-process application. Ie, that |
1452 |
* it *won't* block the server to perform interactive auth each time |
1453 |
* a new child process goes through the ssl_pphrase_Handle dance. |
1258 |
*/ |
1454 |
*/ |
1259 |
ssl_tmp_keys_free(base_server); |
1455 |
ssl_pphrase_Handle(base_server, ptemp); |
1260 |
|
1456 |
|
1261 |
/* |
1457 |
ssl_tmp_keys_init(base_server); |
1262 |
* Free the non-pool allocated structures |
1458 |
|
1263 |
* in the per-server configurations |
|
|
1264 |
*/ |
1265 |
for (s = base_server; s; s = s->next) { |
1459 |
for (s = base_server; s; s = s->next) { |
1266 |
sc = mySrvConfig(s); |
1460 |
sc = mySrvConfig(s); |
|
|
1461 |
ssl_init_ConfigureServer(s, p, ptemp, sc); |
1462 |
} |
1463 |
sc = mySrvConfig(base_server); |
1464 |
apr_pool_destroy(ptemp); |
1267 |
|
1465 |
|
1268 |
ssl_init_ctx_cleanup_proxy(sc->proxy); |
1466 |
/* ssl_child_exit handler to handle pkcs11 semantics for |
|
|
1467 |
* C_Initialize/C_Finalize */ |
1468 |
apr_pool_cleanup_register(p, base_server, ssl_child_exit, ssl_child_exit); |
1269 |
|
1469 |
|
1270 |
ssl_init_ctx_cleanup_server(sc->server); |
1470 |
ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, |
1271 |
} |
1471 |
"Completed child process engine initialization: pid=`%d' engine=`%s'", |
|
|
1472 |
mc->pid, mc->szCryptoDevice); |
1473 |
ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, base_server); |
1474 |
} |
1475 |
#endif /*if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)*/ |
1272 |
|
1476 |
|
|
|
1477 |
apr_status_t ssl_init_ModuleKill(void *data) |
1478 |
{ |
1479 |
server_rec *base_server = (server_rec *)data; |
1480 |
|
1481 |
/* XXX: engine_managed_keys patch: The deletions in this function |
1482 |
* correspond to the similar deletions in ssl_init_Module and are subject |
1483 |
* to the same comments. |
1484 |
* |
1485 |
* The calls that have moved to the corresponding child cleanup are (in order): |
1486 |
* ssl_tmp_keys_free |
1487 |
* FOR EACH server, including the base_server: |
1488 |
* ssl_init_ctx_cleaup_proxy |
1489 |
* ssl_init_ctx_cleanup_server |
1490 |
*/ |
1491 |
|
1492 |
/* |
1493 |
* Drop the session cache and mutex |
1494 |
*/ |
1495 |
ssl_scache_kill(base_server); |
1496 |
|
1273 |
return APR_SUCCESS; |
1497 |
return APR_SUCCESS; |
1274 |
} |
1498 |
} |
1275 |
|
1499 |
|