Ok solved also the last problem! I've discovered that the problem was in
the fork() that is performed in the ocspd.c main() code. The way to fix this
is to move the engine initialization and private key loading after the
fork(), straight before the start_threaded_server() call. So now I can state
that the OCSP responder works very well as a daemon with an Eracom
ProtectServer Orange (network attached) HSM dynamically loaded through the
Engine PKCS#11 + LibP11 + OpenSSL 0.9.8g combination ;-)
I think Massimiliano can include this change in the next version.
On Wed, Aug 27, 2008 at 20:32, Diego de Felice <[EMAIL PROTECTED]>wrote:
> Ok, resolved this problem. There is a bug in Engine PKCS#11 version
> 0.1.4 (and today I've discovered there is a 0.1.5 version...). With this
> bug, the engine_pkcs11 didn't perform login on the token when reading
> private objects. But now another problem arises: OCSPd works very well when
> launched in standard way, it doesn't work well when launched in daemon way
> (with -d option).
>
> The problem is always related to signature, but this time the OCSP
> certificate appears, the signature algorithm appears, instead the
> signature doesn't appear! (an empty array). I've read the source code and
> the only difference is that with daemon mode there is a fork(). Could be
> this ?
>
> p.s. there is a bug in the ocspd script, the if test of the ps -p on the
> pid misses the " around the ' characters.
>
>
>
> --
> Diego
>
/*
* OCSP responder
* by Massimiliano Pala ([EMAIL PROTECTED])
* OpenCA project 2001
*
* Copyright (c) 2001 The OpenCA Project. All rights reserved.
*
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* ([EMAIL PROTECTED]). This product includes software written by Tim
* Hudson ([EMAIL PROTECTED]).
*
*/
/* NOTICE:
*
* All the db stuff now are obsolete as the version now uses the
* crl to check the certificate(s). The TXT_DB file will be
* used in future for the suspended certificate(s) list (not
* yet revoked but not to be considered valid
*
*/
#include "general.h"
#ifdef HAVE_ENGINE
#include <openssl/engine.h>
#endif
#include <time.h>
#include <sys/wait.h>
#include "support.h"
#include "ocsp_db.h"
#include "ocspd.h"
#include "core.h"
#include "configuration.h"
#include "ocspd_engine.h"
#include <sys/types.h>
#include <unistd.h>
static char *ocspd_warning =
"\n"
"OpenCA's OCSP Responder - v%s\n"
"(c) 2002-2006 by Massimiliano Pala and OpenCA Project\n"
" OpenCA licensed software\n"
"\n";
static char *ocspd_usage[] = {
"OCSPd - OpenCA OCSP responder daemon\n",
"(c) 2002-2006 by Massimiliano Pala and OpenCA Project\n",
"\n",
" USAGE: ocspd args\n",
"\n",
" -d - Daemon, detach from current console\n",
" -r dir - Directory where to jail the running process (chroot)\n",
" -p n - Start listening on port n [2560]\n",
" -b addr - Binds to ip <addr> [*]\n",
" -c file - A config file\n",
" -md digest - Set digest to be used [md5]\n",
" -k pwd - Password protecting the private key (if any)\n",
" -i passin - Passin arg\n",
#ifdef _OLD_HAVE_ENGINE
" -e engine - use engine e, possibly a hardware device.\n",
#endif
" -debug - Debug mode (exit after the first request)\n",
" -v - Talk alot while doing things\n",
NULL
};
/* Staic variables */
char *prgname = "ocspd";
char *version = VERSION;
OCSPD_CONFIG *ocspd_conf = NULL;
/* Local functions prototypes */
int writePid ( int pid, char *pidfile );
/* Main */
int main ( int argc, char *argv[] ) {
char *port_s = NULL;
char *bind_s = NULL;
char *child_s = NULL;
char *maxrs_s = NULL;
char *max_timeout_s = NULL;
int child_num = 5;
int verbose = 0;
int debug = 0;
int daemon = 0;
int badops = 0;
int ret = 0;
BIO *keyf = NULL;
BIO *certf = NULL;
char *keyfile = NULL;
char *configfile = NULL;
char *cert = NULL;
char *cacert = NULL;
char **pp = NULL;
char *key = NULL;
char *passargin = NULL;
char *section = NULL;
char *resp_section = NULL;
char *dbms_section = NULL;
char *pidfile = NULL;
char *chroot_dir = NULL;
char *tmp_s = NULL;
int keyform = FORMAT_PEM;
/* ADD ENGINE SUPPORT */
#ifdef HAVE_ENGINE
char *engine=NULL;
#endif
int i = 0;
pid_t pid = 0;
pid_t ppid = 0;
char *ocsp_digest_name = NULL;
/* What are really needed here ?? Please help... */
X509V3_add_standard_extensions();
OpenSSL_add_all_algorithms();
OpenSSL_add_all_digests();
OpenSSL_add_all_ciphers();
argv++;
argc--;
openlog( prgname, LOG_PID, LOG_DAEMON);
syslog(LOG_ERR,"OpenCA OCSPD v%s - starting.",
VERSION );
while (argc >= 1)
{
/* Debuggin options */
#ifdef DEBUG
syslog(LOG_ERR,"Parsing (%s)\n", *argv);
#endif
if (strcmp(*argv,"-c") == 0)
{
if (--argc < 1) goto bad;
configfile= *(++argv);
}
else if (strcmp(*argv,"-k") == 0)
{
if (--argc < 1) goto bad;
key= *(++argv);
}
else if (strcmp(*argv,"-i") == 0)
{
if (--argc < 1) goto bad;
passargin= *(++argv);
}
else if (strcmp(*argv,"-md") == 0)
{
if (--argc < 1) goto bad;
ocsp_digest_name = *(++argv);
}
#ifdef HAVE_ENGINE
else if (strcmp(*argv,"-e") == 0)
{
if (--argc < 1) goto bad;
engine = *(++argv);
}
#endif
else if (strcmp(*argv,"-p") == 0)
{
if (--argc < 1) goto bad;
port_s = *(++argv);
}
else if (strcmp(*argv,"-r") == 0)
{
if (--argc < 1) goto bad;
chroot_dir = *(++argv);
}
else if (strcmp(*argv,"-b") == 0)
{
if (--argc < 1) goto bad;
bind_s = *(++argv);
}
else if (strcmp(*argv,"-v") == 0)
verbose=1;
else if (strcmp(*argv,"-debug") == 0)
debug=1;
else if (strcmp(*argv,"-d") == 0)
daemon=1;
else badops = 1;
argc--;
argv++;
}
bad:
if (badops) {
for (pp=ocspd_usage; (*pp != NULL); pp++)
printf(*pp);
goto err;
}
if( daemon == 0 ) {
printf(ocspd_warning, VERSION);
// for (pp=ocspd_warning; (*pp != NULL); pp++)
// printf(*pp);
}
ERR_load_crypto_strings();
if(( ocspd_conf = (OCSPD_CONFIG *)
OPENSSL_malloc ( sizeof(OCSPD_CONFIG))) == NULL ) {
syslog(LOG_ERR, "Memory Allocation error");
exit(-1);
}
/* Zeroise it for Solaris... */
memset( ocspd_conf, '\x0', sizeof(OCSPD_CONFIG));
/* load configuration file */
if( configfile == NULL )
configfile = OCSPD_DEF_CONFIG;
if( (ocspd_conf->conf = load_config( configfile, §ion )) == NULL ) {
syslog( LOG_ERR,"can not load configuration file %s",
configfile );
exit(-1);
}
/* Copy the conf filename so that it could be re-loaded on SIGHUP */
if( (ocspd_conf->cnf_filename =
(char *) OPENSSL_malloc(strlen(configfile) + 1)) == NULL ) {
syslog( LOG_ERR,"memory allocation error (%d)", __LINE__ );
goto err;
}
/* Set the group and user string to NULL */
ocspd_conf->user = NULL;
ocspd_conf->group = NULL;
/* Set the OCSPD verbose status */
ocspd_conf->verbose = verbose;
ocspd_conf->debug = debug;
ocspd_conf->max_timeout_secs = 5;
/* Copy the db filename so that it could be re-loaded on SIGHUP */
strcpy( ocspd_conf->cnf_filename, configfile);
/* Set the CRL checking variables */
ocspd_conf->crl_check_validity = 0;
/* Passin support */
if(!key && !app_passwd(passargin, NULL, &key, NULL)) {
syslog(LOG_ERR, "Error getting passwords\n");
goto err;
}
/*****************************************************************/
/* Load the OCSP certificate file */
if ((cert == NULL) && ((cert=NCONF_get_string(ocspd_conf->conf,
section,ENV_CERTIFICATE)) == NULL)) {
lookup_fail(section,ENV_CERTIFICATE);
}
if ( cert ) {
if( verbose )
syslog(LOG_INFO,"reading certificate file (%s).",
cert );
if ((certf=BIO_new_file( cert, "r")) == NULL) {
syslog(LOG_ERR,"unable to open certificate file.\n");
goto err;
}
if ((ocspd_conf->ocspd_cert =
PEM_read_bio_X509(certf,NULL,NULL,NULL))
==NULL) {
syslog(LOG_ERR,"cannot load certificate.\n");
goto err;
}
BIO_free( certf );
}
if (ocspd_conf->ocspd_cert == NULL) {
syslog(LOG_ERR,"unable to load OCSP certificate\n");
goto err;
}
/*****************************************************************/
/*****************************************************************/
/* Load the CA certificate file */
if ((cacert == NULL) && ((cacert=NCONF_get_string(ocspd_conf->conf,
section,ENV_CA_CERTIFICATE)) == NULL))
{
lookup_fail(section,ENV_CA_CERTIFICATE);
goto err;
}
if ( cacert ) {
if( verbose )
syslog(LOG_INFO,"reading CA certificate file.\n");
if ((certf=BIO_new_file( cacert, "r")) == NULL) {
syslog(LOG_ERR,"unable to open CA certificate file.\n");
goto err;
}
if ((ocspd_conf->cacert =
PEM_read_bio_X509(certf,NULL,NULL,NULL))
==NULL) {
syslog(LOG_ERR,"cannot load CA certificate.\n");
goto err;
}
BIO_free( certf );
}
if (ocspd_conf->cacert == NULL) {
syslog(LOG_ERR,"unable to load CA certificate\n");
goto err;
}
if(verbose)
syslog(LOG_INFO,"OCSP Daemon setup completed");
/*****************************************************************/
/* Let's get the digest */
if ((ocsp_digest_name == NULL) &&
((ocsp_digest_name=NCONF_get_string(ocspd_conf->conf,section,
ENV_OCSPD_MD)) == NULL)) {
lookup_fail(section,ENV_OCSPD_MD);
goto err;
}
ocspd_conf->digest = (EVP_MD *) EVP_get_digestbyname(ocsp_digest_name);
if( ocspd_conf->digest == NULL ) {
syslog(LOG_ERR, "unsupported digest type %s",
ocsp_digest_name);
goto err;
}
/*****************************************************************/
/* Load other important config keys */
/* Listen to port_s */
if ((port_s == NULL) && ((port_s = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_PORT)) == NULL)) {
if( verbose )
lookup_fail(section,ENV_OCSPD_PORT);
port_s = "2560";
}
/* Binds to address */
if ((bind_s == NULL) && ((bind_s = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_BIND)) == NULL)) {
if( verbose )
lookup_fail(section,ENV_OCSPD_BIND);
bind_s = "0.0.0.0";
}
/* Number of child threads to be spawned */
if ((child_s == NULL) && ((child_s = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_CHILD)) == NULL)) {
if( verbose )
lookup_fail(section,ENV_OCSPD_CHILD);
} else {
child_num = atoi( child_s );
}
/* Maximum timeout allowed for network operations */
if ((max_timeout_s == NULL) && ((max_timeout_s =
NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_MAX_NET_TIMEOUT)) == NULL)) {
if( verbose )
lookup_fail(section,ENV_OCSPD_MAX_NET_TIMEOUT);
} else {
ocspd_conf->max_timeout_secs = atoi( max_timeout_s );
if( ocspd_conf -> max_timeout_secs == 0 ) {
ocspd_conf->max_timeout_secs = 5;
}
}
/* Max req size allowed (http header included) */
if ((maxrs_s == NULL) && ((maxrs_s = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_MAXRS)) == NULL)) {
if( verbose )
lookup_fail(section,ENV_OCSPD_MAXRS);
ocspd_conf->max_req_size = 0L;
} else {
ocspd_conf->max_req_size = abs( atol( maxrs_s ) + 1);
}
/* Get the user name to set the process to */
if ((ocspd_conf->group == NULL) &&
((ocspd_conf->group = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_GROUP)) == NULL)) {
if( verbose )
lookup_fail(section,ENV_OCSPD_GROUP);
ocspd_conf->group = OCSPD_DEF_GROUP;
}
/* Get the user name to set the process to */
if ((ocspd_conf->user == NULL) &&
((ocspd_conf->user = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_USER)) == NULL)) {
if( verbose )
lookup_fail(section,ENV_OCSPD_USER);
ocspd_conf->user = OCSPD_DEF_USER;
}
/* Get the chroot dir */
if ((chroot_dir == NULL) &&
((ocspd_conf->chroot_dir = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_CHROOT_DIR)) == NULL)) {
if( verbose )
lookup_fail(section,ENV_OCSPD_CHROOT_DIR);
ocspd_conf->chroot_dir = NULL;
} else {
/* The command line options has the precedence */
ocspd_conf->chroot_dir = chroot_dir;
}
/* Get the pidfile name to write main pid to */
if ((pidfile == NULL) && ((pidfile = NCONF_get_string(ocspd_conf->conf,
section,
ENV_OCSPD_PIDFILE)) == NULL)) {
if( verbose )
lookup_fail(section,ENV_OCSPD_PIDFILE);
pidfile = OCSPD_DEF_PIDFILE;
}
/* CRL auto reload */
if ((tmp_s = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_CRL_AUTO_RELOAD))==NULL) {
if( verbose )
lookup_fail(section, ENV_OCSPD_CRL_AUTO_RELOAD);
ocspd_conf->crl_auto_reload = 0;
} else {
ocspd_conf->crl_auto_reload = atol(tmp_s);
if(verbose)
syslog( LOG_INFO, "Auto CRL reload every %d secs",
ocspd_conf->crl_auto_reload );
}
/* Get the expired CRL re-load parameter */
if ((tmp_s = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_CRL_RELOAD_EXPIRED)) ==NULL) {
if( verbose )
lookup_fail(section, ENV_OCSPD_CRL_RELOAD_EXPIRED);
ocspd_conf->crl_reload_expired = 0;
} else {
if( strcmp( tmp_s, "yes" ) == 0 ) {
ocspd_conf->crl_reload_expired = 1;
if(verbose)
syslog( LOG_INFO, "Reload on expired CRLs
enabled");
} else {
ocspd_conf->crl_reload_expired = 0;
if(verbose)
syslog( LOG_INFO, "Reload on expired CRLs
DISABLED");
}
}
/* Get CRL section name */
if ((dbms_section = NCONF_get_string(ocspd_conf->conf, section,
ENV_OCSPD_DBMS)) == NULL) {
if( verbose )
lookup_fail(section, ENV_OCSPD_DBMS);
dbms_section = ENV_DEFAULT_OCSPD;
}
/****************************************************************/
/* We load for every CA one CRL */
if( !ocspd_load_ca_section( ocspd_conf, dbms_section )) {
syslog(LOG_ERR, "%s:%d Error Loading ca section data.",
__FILE__, __LINE__);
}
/*****************************************************************/
/* OCSPD responder specific options */
ocspd_conf->flags = 0;
/* Get response section name */
if ((resp_section = NCONF_get_string(ocspd_conf->conf, section,
ENV_OCSPD_RESPONSE)) == NULL) {
if( verbose )
lookup_fail(section, ENV_OCSPD_RESPONSE);
resp_section = ENV_DEFAULT_OCSPD;
}
/* Get if the response has to include keyid */
if ((tmp_s = NCONF_get_string(ocspd_conf->conf, resp_section,
ENV_OCSPD_RESPONSE_KEYID)) == NULL) {
if( verbose )
lookup_fail(resp_section, ENV_OCSPD_RESPONSE_KEYID);
} else {
if( strstr( tmp_s, "n" ) || strstr( tmp_s, "N" )) {
ocspd_conf->flags |= OCSP_RESPID_KEY;
}
}
/* Include in the response the other_certs X509 STACK */
if ((tmp_s = NCONF_get_string(ocspd_conf->conf, resp_section,
ENV_OCSPD_RESPONSE_OTHER_CERTS)) == NULL) {
if( verbose )
lookup_fail(resp_section,
ENV_OCSPD_RESPONSE_OTHER_CERTS);
ocspd_conf->flags |= OCSP_NOCERTS;
} else {
ocspd_conf->other_certs = load_certs( NULL, tmp_s,
FORMAT_PEM, NULL, "responder other certificates" );
}
/* Get next update days */
if ((tmp_s = NCONF_get_string(ocspd_conf->conf, resp_section,
ENV_OCSPD_RESPONSE_DAYS)) == NULL) {
if( verbose )
lookup_fail(resp_section, ENV_OCSPD_RESPONSE_DAYS);
ocspd_conf->ndays = 0;
} else {
ocspd_conf->ndays = abs(atoi( tmp_s ));
}
/* Get next update minutes */
if ((tmp_s = NCONF_get_string(ocspd_conf->conf, resp_section,
ENV_OCSPD_RESPONSE_MINS)) == NULL) {
if( verbose )
lookup_fail(resp_section, ENV_OCSPD_RESPONSE_MINS);
ocspd_conf->nmin = 0;
} else {
ocspd_conf->nmin = abs(atoi( tmp_s ));
}
/* If any of nmin or ndays is used, we set the nextUpdate field
in the response, otherwise we leave it out */
ocspd_conf->set_nextUpdate =
ocspd_conf->ndays + ocspd_conf->nmin;
/* Get the crl_check_validity config parameter */
if ((tmp_s = NCONF_get_string(ocspd_conf->conf,
section, ENV_OCSPD_CRL_CHECK_VALIDITY)) ==NULL) {
if( verbose )
lookup_fail(section, ENV_OCSPD_CRL_CHECK_VALIDITY);
ocspd_conf->crl_check_validity = 0;
} else {
ocspd_conf->crl_check_validity = atol(tmp_s);
if(verbose)
syslog( LOG_INFO,
"CRL validity check every %d sec.",
ocspd_conf->crl_check_validity);
}
/*****************************************************************/
/* Main spawn and signal routines */
if (verbose)
syslog(LOG_INFO,"Configuration loaded and parsed");
if( daemon ) {
pid = fork();
if( pid == 0 ) {
/* Main process, we have to save the pid to the
* pidfile and then exit */
writePid( getpid(), pidfile );
} else if ( pid > 0 ) {
/* Nop */
goto end;
} else {
syslog( LOG_ERR, "Error While spawning child %d", i );
goto err;
}
} else {
ppid = getpid();
writePid( ppid, pidfile );
}
/* ENGINE support added */
#ifdef HAVE_ENGINE
/* Get db Filename */
if ((engine == NULL) &&
((engine = NCONF_get_string(ocspd_conf->conf, section,
ENV_OCSPD_ENGINE)) == NULL)) {
ocspd_conf->engine_id = NULL;
ocspd_conf->engine = NULL;
ocspd_conf->pre_cmds = NULL;
ocspd_conf->post_cmds = NULL;
} else {
ocspd_load_engine_section(ocspd_conf, engine );
ocspd_init_engine( ocspd_conf );
}
#endif
/* Reading Private key file */
if ((keyfile == NULL) &&
((keyfile = NCONF_get_string(ocspd_conf->conf, section,
ENV_PRIVATE_KEY)) == NULL)) {
lookup_fail(section,ENV_PRIVATE_KEY);
goto err;
}
#ifdef HAVE_ENGINE
if( (engine != NULL) && (keyfile) &&
(strncmp("engine:", keyfile, 7) == 0) ) {
syslog(LOG_INFO, "Private Key in HSM [ id = %s ]", keyfile+7);
keyform = FORMAT_ENGINE;
} else {
if( verbose )
syslog(LOG_INFO,"Reading Private Key file %s", keyfile);
if ((keyf=BIO_new_file( keyfile, "r")) == NULL) {
syslog( LOG_ERR,"cannot open BIO file, why ?" );
goto err;
}
}
#else
if( verbose )
syslog(LOG_INFO,"Reading Private Key file %s", keyfile);
if ((keyf=BIO_new_file( keyfile, "r")) == NULL) {
syslog( LOG_ERR,"cannot open BIO file, why ?" );
goto err;
}
#endif
#ifdef HAVE_ENGINE
if( keyform == FORMAT_ENGINE ) {
PW_CB_DATA cb_data;
cb_data.password = NULL;
cb_data.prompt_info = keyfile + 7;
if(!ocspd_conf->engine) {
syslog( LOG_ERR, "ERROR::ENGINE::no engine loaded!\n");
goto err;
}
ocspd_conf->ocspd_pkey =
ENGINE_load_private_key( ocspd_conf->engine,
(char *) keyfile+7, UI_OpenSSL(), &cb_data);
} else if ( keyform == FORMAT_PEM ) {
ocspd_conf->ocspd_pkey =
PEM_read_bio_PrivateKey(keyf,NULL,NULL,key);
if (key) memset(key,0,strlen(key));
} else {
syslog(LOG_ERR, "ERROR::ENGING::bad input format for "
"key file\n");
goto err;
};
#else
if ( keyform == FORMAT_PEM ) {
ocspd_conf->ocspd_pkey =
PEM_read_bio_PrivateKey(keyf,NULL,NULL,key);
if (key) memset(key,0,strlen(key));
} else {
syslog(LOG_ERR, "bad input format specified for key file\n");
goto err;
};
#endif
if( keyf ) BIO_free( keyf );
if( ocspd_conf->ocspd_pkey == NULL ) {
syslog(LOG_ERR,"Error loading private key\n");
goto err;
};
if ( keyform != FORMAT_ENGINE ) {
if (!X509_check_private_key(ocspd_conf->ocspd_cert,
ocspd_conf->ocspd_pkey)) {
syslog(LOG_ERR, "Cert and privateKey do not match!\n");
goto err;
}
}
// CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
start_threaded_server( bind_s, port_s, child_num, ocspd_conf );
goto end;
err:
ret = -1;
end:
return (ret);
}
int writePid ( int pid, char *pidfile ) {
FILE *fd;
if( (fd = fopen( pidfile, "w" )) == 0 ) {
syslog( LOG_ERR, "Cannot open pidfile (%s)",
pidfile );
return(0);
}
fprintf( fd, "%d", (int) getpid());
fclose( fd );
return(1);
}
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Openca-Users mailing list
Openca-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openca-users