Lines 220-232
Link Here
|
220 |
} else { |
220 |
} else { |
221 |
apr_cpystrn(szPath, sc->server->pks->cert_files[i], |
221 |
apr_cpystrn(szPath, sc->server->pks->cert_files[i], |
222 |
sizeof(szPath)); |
222 |
sizeof(szPath)); |
223 |
if ((rv = exists_and_readable(szPath, p, NULL)) |
223 |
if (!mc->engine) { |
224 |
!= APR_SUCCESS) { |
224 |
if ((rv = exists_and_readable(szPath, p, NULL)) |
|
|
225 |
!= APR_SUCCESS) { |
225 |
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02201) |
226 |
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02201) |
226 |
"Init: Can't open server certificate file %s", |
227 |
"Init: Can't open server certificate file %s", |
227 |
szPath); |
228 |
szPath); |
228 |
ssl_die(); |
229 |
ssl_die(); |
229 |
} |
230 |
} |
230 |
if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) { |
231 |
if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) { |
231 |
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02241) |
232 |
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02241) |
232 |
"Init: Unable to read server certificate from" |
233 |
"Init: Unable to read server certificate from" |
Lines 237-243
Link Here
|
237 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02202) |
238 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02202) |
238 |
"Init: Read server certificate from '%s'", |
239 |
"Init: Read server certificate from '%s'", |
239 |
szPath); |
240 |
szPath); |
240 |
} |
241 |
} |
|
|
242 |
else { |
243 |
/* For backwards compat, and convenience for engine |
244 |
* implementors, we should probably have a configurable |
245 |
* means to say: "for these named engines, use apaches |
246 |
* existing pem file support to load server keys and |
247 |
* certificates", this patch treats all engines the same |
248 |
* TODO: |
249 |
* 1. explicit support for passing UI callbacks and |
250 |
* data necessary for hardware that needs password entry, |
251 |
* or other interactions, in order to load keys. It's a can |
252 |
* of worms so I'm leaving it out for now. |
253 |
* 2. Add at least "SSLCryptoDeviceLoadCertCmd" in order to |
254 |
* enable a more general purpose implementation of engine |
255 |
* based certificate loading. */ |
256 |
pX509Cert = ssl_ossle_load_cert_engine_pkcs11(s, szPath); |
257 |
if (!pX509Cert) { |
258 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
259 |
"Init: Unable to server certificate `%s' using " |
260 |
"engine `%s'", szPath, mc->szCryptoDevice); |
261 |
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); |
262 |
ssl_die(); |
263 |
} |
264 |
} |
265 |
} |
266 |
|
241 |
/* |
267 |
/* |
242 |
* check algorithm type of certificate and make |
268 |
* check algorithm type of certificate and make |
243 |
* sure only one certificate per type is used. |
269 |
* sure only one certificate per type is used. |
Lines 323-329
Link Here
|
323 |
* the callback function which serves the pass |
349 |
* the callback function which serves the pass |
324 |
* phrases to OpenSSL |
350 |
* phrases to OpenSSL |
325 |
*/ |
351 |
*/ |
326 |
if ((rv = exists_and_readable(szPath, p, |
352 |
if (!mc->engine && (rv = exists_and_readable(szPath, p, |
327 |
&pkey_mtime)) != APR_SUCCESS ) { |
353 |
&pkey_mtime)) != APR_SUCCESS ) { |
328 |
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02243) |
354 |
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02243) |
329 |
"Init: Can't open server private key file " |
355 |
"Init: Can't open server private key file " |
Lines 373-381
Link Here
|
373 |
* functions will fail spuriously if the error stack |
399 |
* functions will fail spuriously if the error stack |
374 |
* is not empty. */ |
400 |
* is not empty. */ |
375 |
ERR_clear_error(); |
401 |
ERR_clear_error(); |
376 |
|
402 |
|
377 |
bReadable = ((pPrivateKey = SSL_read_PrivateKey(szPath, NULL, |
403 |
if (!mc->engine) { |
378 |
ssl_pphrase_Handle_CB, s)) != NULL ? TRUE : FALSE); |
404 |
bReadable = ((pPrivateKey = SSL_read_PrivateKey(szPath, |
|
|
405 |
NULL, ssl_pphrase_Handle_CB, s)) |
406 |
!= NULL ? TRUE : FALSE); |
407 |
} |
408 |
else { |
409 |
pPrivateKey = ENGINE_load_private_key(mc->engine, szPath, |
410 |
UI_OpenSSL() |
411 |
/*ui_method*/, |
412 |
0 /*cbdata*/); |
413 |
bReadable = pPrivateKey != NULL ? TRUE : FALSE; |
414 |
} |
379 |
|
415 |
|
380 |
/* |
416 |
/* |
381 |
* when the private key file now was readable, |
417 |
* when the private key file now was readable, |
Lines 474-485
Link Here
|
474 |
continue; |
510 |
continue; |
475 |
|
511 |
|
476 |
if (pPrivateKey == NULL) { |
512 |
if (pPrivateKey == NULL) { |
477 |
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02247) |
513 |
if (!mc->engine) { |
478 |
"Init: Unable to read server private key from " |
514 |
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02247) |
479 |
"file %s [Hint: Perhaps it is in a separate file? " |
515 |
"Init: Unable to read server private key from " |
480 |
" See SSLCertificateKeyFile]", szPath); |
516 |
"file %s [Hint: Perhaps it is in a separate file? " |
481 |
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); |
517 |
" See SSLCertificateKeyFile]", szPath); |
482 |
ssl_die(); |
518 |
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); |
|
|
519 |
ssl_die(); |
520 |
} |
521 |
else { |
522 |
/* log the error with clear indication that engine format |
523 |
* keys are in play. */ |
524 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
525 |
"Init: Unable to load server private key " |
526 |
"using the identifier `%s' and engine `%s'", |
527 |
szPath, mc->szCryptoDevice); |
528 |
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); |
529 |
} |
483 |
} |
530 |
} |
484 |
|
531 |
|
485 |
/* |
532 |
/* |
Lines 535-548
Link Here
|
535 |
* because the SSL library uses static variables inside a |
582 |
* because the SSL library uses static variables inside a |
536 |
* RSA structure which do not survive DSO reloads!) |
583 |
* RSA structure which do not survive DSO reloads!) |
537 |
*/ |
584 |
*/ |
538 |
length = i2d_PrivateKey(pPrivateKey, NULL); |
585 |
if (!mc->engine){ |
539 |
ucp = ssl_asn1_table_set(mc->tPrivateKey, key_id, length); |
586 |
length = i2d_PrivateKey(pPrivateKey, NULL); |
540 |
(void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */ |
587 |
ucp = ssl_asn1_table_set(mc->tPrivateKey, key_id, length); |
541 |
|
588 |
(void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */ |
542 |
if (nPassPhraseDialogCur != 0) { |
589 |
|
543 |
/* remember mtime of encrypted keys */ |
590 |
if (nPassPhraseDialogCur != 0) { |
544 |
asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id); |
591 |
/* remember mtime of encrypted keys */ |
545 |
asn1->source_mtime = pkey_mtime; |
592 |
asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id); |
|
|
593 |
asn1->source_mtime = pkey_mtime; |
594 |
} |
595 |
} |
596 |
else { |
597 |
/* the asn1 trick does not play well with hardware hosted |
598 |
keys. */ |
599 |
length = strlen(szPath) + 1; |
600 |
/* cpData is the key_id */ |
601 |
ucp = ssl_asn1_table_set(mc->tPrivateKey, key_id, length); |
602 |
memcpy(ucp, szPath, length); |
603 |
/* un-necessary, given we will reload, but retained for |
604 |
* consistency. */ |
605 |
if (nPassPhraseDialogCur != 0) { |
606 |
/* remember mtime of encrypted keys */ |
607 |
asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id); |
608 |
asn1->source_mtime = pkey_mtime; |
609 |
} |
546 |
} |
610 |
} |
547 |
|
611 |
|
548 |
/* |
612 |
/* |