ITS#4017, additional revisions for DH parameters

This commit is contained in:
Howard Chu 2005-10-28 05:35:19 +00:00
parent 39f39fcb44
commit 4ebed09d81
3 changed files with 64 additions and 62 deletions

View file

@ -136,7 +136,7 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_X_TLS_CRLCHECK 0x600b #define LDAP_OPT_X_TLS_CRLCHECK 0x600b
#define LDAP_OPT_X_TLS_CONNECT_CB 0x600c #define LDAP_OPT_X_TLS_CONNECT_CB 0x600c
#define LDAP_OPT_X_TLS_CONNECT_ARG 0x600d #define LDAP_OPT_X_TLS_CONNECT_ARG 0x600d
#define LDAP_OPT_X_TLS_DHPARAMDIR 0x600e #define LDAP_OPT_X_TLS_DHFILE 0x600e
#define LDAP_OPT_X_TLS_NEVER 0 #define LDAP_OPT_X_TLS_NEVER 0
#define LDAP_OPT_X_TLS_HARD 1 #define LDAP_OPT_X_TLS_HARD 1

View file

@ -50,7 +50,7 @@
static int tls_opt_trace = 1; static int tls_opt_trace = 1;
static char *tls_opt_certfile = NULL; static char *tls_opt_certfile = NULL;
static char *tls_opt_keyfile = NULL; static char *tls_opt_keyfile = NULL;
static char *tls_opt_dhparamdir = NULL; static char *tls_opt_dhfile = NULL;
static char *tls_opt_cacertfile = NULL; static char *tls_opt_cacertfile = NULL;
static char *tls_opt_cacertdir = NULL; static char *tls_opt_cacertdir = NULL;
static int tls_opt_require_cert = LDAP_OPT_X_TLS_DEMAND; static int tls_opt_require_cert = LDAP_OPT_X_TLS_DEMAND;
@ -59,7 +59,6 @@ static int tls_opt_crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
#endif #endif
static char *tls_opt_ciphersuite = NULL; static char *tls_opt_ciphersuite = NULL;
static char *tls_opt_randfile = NULL; static char *tls_opt_randfile = NULL;
static int tls_opt_dhparamdirlen;
#define HAS_TLS( sb ) ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \ #define HAS_TLS( sb ) ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
(void *)&sb_tls_sbio ) (void *)&sb_tls_sbio )
@ -76,6 +75,14 @@ static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
static SSL_CTX *tls_def_ctx = NULL; static SSL_CTX *tls_def_ctx = NULL;
typedef struct dhplist {
struct dhplist *next;
int keylength;
DH *param;
} dhplist;
static dhplist *dhparams;
static int tls_seed_PRNG( const char *randfile ); static int tls_seed_PRNG( const char *randfile );
#ifdef LDAP_R_COMPILE #ifdef LDAP_R_COMPILE
@ -134,9 +141,9 @@ ldap_pvt_tls_destroy( void )
LDAP_FREE( tls_opt_keyfile ); LDAP_FREE( tls_opt_keyfile );
tls_opt_keyfile = NULL; tls_opt_keyfile = NULL;
} }
if ( tls_opt_dhparamdir ) { if ( tls_opt_dhfile ) {
LDAP_FREE( tls_opt_dhparamdir ); LDAP_FREE( tls_opt_dhfile );
tls_opt_dhparamdir = NULL; tls_opt_dhfile = NULL;
} }
if ( tls_opt_cacertfile ) { if ( tls_opt_cacertfile ) {
LDAP_FREE( tls_opt_cacertfile ); LDAP_FREE( tls_opt_cacertfile );
@ -202,6 +209,7 @@ ldap_pvt_tls_init_def_ctx( void )
char *cacertdir = tls_opt_cacertdir; char *cacertdir = tls_opt_cacertdir;
char *certfile = tls_opt_certfile; char *certfile = tls_opt_certfile;
char *keyfile = tls_opt_keyfile; char *keyfile = tls_opt_keyfile;
char *dhfile = tls_opt_dhfile;
#ifdef LDAP_R_COMPILE #ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex ); ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
@ -234,6 +242,10 @@ ldap_pvt_tls_init_def_ctx( void )
keyfile = LDAP_STRDUP( keyfile ); keyfile = LDAP_STRDUP( keyfile );
__atoe( keyfile ); __atoe( keyfile );
} }
if ( dhfile ) {
dhfile = LDAP_STRDUP( dhfile );
__atoe( dhfile );
}
#endif #endif
if ( tls_def_ctx == NULL ) { if ( tls_def_ctx == NULL ) {
int i; int i;
@ -325,6 +337,31 @@ ldap_pvt_tls_init_def_ctx( void )
goto error_exit; goto error_exit;
} }
if ( tls_opt_dhfile ) {
DH *dh = NULL;
BIO *bio;
dhplist *p;
if (( bio=BIO_new_file( dhfile,"r" )) == NULL ) {
Debug( LDAP_DEBUG_ANY,
"TLS: could not use DH parameters file `%s'.\n",
tls_opt_dhfile,0,0);
tls_report_error();
rc = -1;
goto error_exit;
}
while (( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
p = LDAP_MALLOC( sizeof(dhplist) );
if ( p != NULL ) {
p->keylength = DH_size( dh ) * 8;
p->param = dh;
p->next = dhparams;
dhparams = p;
}
}
BIO_free( bio );
}
if ( tls_opt_trace ) { if ( tls_opt_trace ) {
SSL_CTX_set_info_callback( tls_def_ctx, tls_info_cb ); SSL_CTX_set_info_callback( tls_def_ctx, tls_info_cb );
} }
@ -366,6 +403,7 @@ error_exit:
LDAP_FREE( cacertdir ); LDAP_FREE( cacertdir );
LDAP_FREE( certfile ); LDAP_FREE( certfile );
LDAP_FREE( keyfile ); LDAP_FREE( keyfile );
LDAP_FREE( dhfile );
#endif #endif
#ifdef LDAP_R_COMPILE #ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex ); ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
@ -1125,7 +1163,7 @@ ldap_int_tls_config( LDAP *ld, int option, const char *arg )
case LDAP_OPT_X_TLS_KEYFILE: case LDAP_OPT_X_TLS_KEYFILE:
case LDAP_OPT_X_TLS_RANDOM_FILE: case LDAP_OPT_X_TLS_RANDOM_FILE:
case LDAP_OPT_X_TLS_CIPHER_SUITE: case LDAP_OPT_X_TLS_CIPHER_SUITE:
case LDAP_OPT_X_TLS_DHPARAMDIR: case LDAP_OPT_X_TLS_DHFILE:
return ldap_pvt_tls_set_option( ld, option, (void *) arg ); return ldap_pvt_tls_set_option( ld, option, (void *) arg );
case LDAP_OPT_X_TLS_REQUIRE_CERT: case LDAP_OPT_X_TLS_REQUIRE_CERT:
@ -1223,9 +1261,9 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
*(char **)arg = tls_opt_keyfile ? *(char **)arg = tls_opt_keyfile ?
LDAP_STRDUP( tls_opt_keyfile ) : NULL; LDAP_STRDUP( tls_opt_keyfile ) : NULL;
break; break;
case LDAP_OPT_X_TLS_DHPARAMDIR: case LDAP_OPT_X_TLS_DHFILE:
*(char **)arg = tls_opt_dhparamdir ? *(char **)arg = tls_opt_dhfile ?
LDAP_STRDUP( tls_opt_dhparamdir ) : NULL; LDAP_STRDUP( tls_opt_dhfile ) : NULL;
break; break;
case LDAP_OPT_X_TLS_REQUIRE_CERT: case LDAP_OPT_X_TLS_REQUIRE_CERT:
*(int *)arg = tls_opt_require_cert; *(int *)arg = tls_opt_require_cert;
@ -1338,11 +1376,9 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
if ( tls_opt_keyfile ) LDAP_FREE( tls_opt_keyfile ); if ( tls_opt_keyfile ) LDAP_FREE( tls_opt_keyfile );
tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL; tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break; break;
case LDAP_OPT_X_TLS_DHPARAMDIR: case LDAP_OPT_X_TLS_DHFILE:
if ( tls_opt_dhparamdir ) LDAP_FREE( tls_opt_dhparamdir ); if ( tls_opt_dhfile ) LDAP_FREE( tls_opt_dhfile );
tls_opt_dhparamdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL; tls_opt_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
if ( tls_opt_dhparamdir )
tls_opt_dhparamdirlen = strlen( tls_opt_dhparamdir );
break; break;
case LDAP_OPT_X_TLS_REQUIRE_CERT: case LDAP_OPT_X_TLS_REQUIRE_CERT:
switch( *(int *) arg ) { switch( *(int *) arg ) {
@ -1647,13 +1683,6 @@ struct dhinfo {
size_t size; size_t size;
}; };
struct dhplist {
struct dhplist *next;
int keylength;
DH *param;
};
static struct dhplist *dhparams;
/* From the OpenSSL 0.9.7 distro */ /* From the OpenSSL 0.9.7 distro */
static const char dhpem512[] = static const char dhpem512[] =
@ -1702,18 +1731,13 @@ static const struct dhinfo dhpem[] = {
{ 0, NULL, 0 } { 0, NULL, 0 }
}; };
#define MAXDIGITS 12
#define DHFILEPATTERN "dh%d.pem"
static DH * static DH *
tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length ) tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
{ {
struct dhplist *p = NULL; struct dhplist *p = NULL;
BIO *b = NULL; BIO *b = NULL;
FILE *f;
char *file;
DH *dh = NULL; DH *dh = NULL;
int i;
/* Do we have params of this length already? */ /* Do we have params of this length already? */
#ifdef LDAP_R_COMPILE #ifdef LDAP_R_COMPILE
@ -1728,29 +1752,7 @@ tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
} }
} }
/* See if there's a file to load */
if ( tls_opt_dhparamdir ) {
file = LDAP_MALLOC( tls_opt_dhparamdirlen + 1 + MAXDIGITS +
sizeof(DHFILEPATTERN) );
if ( file == NULL )
goto done;
sprintf( file, "%s/" DHFILEPATTERN, tls_opt_dhparamdir, key_length );
} else {
file = LDAP_MALLOC( STRLENOF(LDAP_SYSCONFDIR) + 1 + MAXDIGITS +
sizeof(DHFILEPATTERN) );
if ( file == NULL )
goto done;
sprintf( file, LDAP_SYSCONFDIR "/" DHFILEPATTERN, key_length );
}
f = fopen(file,"r");
/* Did we get the file? */
if ( f ) {
b = BIO_new_fp( f, BIO_CLOSE );
if ( b == NULL )
fclose( f );
} else {
/* No - check for hardcoded params */ /* No - check for hardcoded params */
int i;
for (i=0; dhpem[i].keylength; i++) { for (i=0; dhpem[i].keylength; i++) {
if ( dhpem[i].keylength == key_length ) { if ( dhpem[i].keylength == key_length ) {
@ -1758,7 +1760,7 @@ tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
break; break;
} }
} }
}
if ( b ) { if ( b ) {
dh = PEM_read_bio_DHparams( b, NULL, NULL, NULL ); dh = PEM_read_bio_DHparams( b, NULL, NULL, NULL );
BIO_free( b ); BIO_free( b );

View file

@ -136,7 +136,7 @@ enum {
CFG_TLS_CERT_KEY, CFG_TLS_CERT_KEY,
CFG_TLS_CA_PATH, CFG_TLS_CA_PATH,
CFG_TLS_CA_FILE, CFG_TLS_CA_FILE,
CFG_TLS_DH_DIR, CFG_TLS_DH_FILE,
CFG_TLS_VERIFY, CFG_TLS_VERIFY,
CFG_TLS_CRLCHECK, CFG_TLS_CRLCHECK,
CFG_CONCUR, CFG_CONCUR,
@ -563,13 +563,13 @@ static ConfigTable config_back_cf_table[] = {
#endif #endif
"( OLcfgGlAt:75 NAME 'olcTLSVerifyClient' " "( OLcfgGlAt:75 NAME 'olcTLSVerifyClient' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "TLSDHParamDir", NULL, 0, 0, 0, { "TLSDHParamFile", NULL, 0, 0, 0,
#ifdef HAVE_TLS #ifdef HAVE_TLS
CFG_TLS_DH_DIR|ARG_STRING|ARG_MAGIC, &config_tls_option, CFG_TLS_DH_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
#else #else
ARG_IGNORED, NULL, ARG_IGNORED, NULL,
#endif #endif
"( OLcfgGlAt:77 NAME 'olcTLSDHParamDir' " "( OLcfgGlAt:77 NAME 'olcTLSDHParamFile' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "tool-threads", "count", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_TTHREADS, { "tool-threads", "count", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_TTHREADS,
&config_generic, "( OLcfgGlAt:80 NAME 'olcToolThreads' " &config_generic, "( OLcfgGlAt:80 NAME 'olcToolThreads' "
@ -631,7 +631,7 @@ static ConfigOCs cf_ocs[] = {
"olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ " "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
"olcTLSCACertificatePath $ olcTLSCertificateFile $ " "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
"olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ " "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
"olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamDir $ " "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
"olcToolThreads $ " "olcToolThreads $ "
"olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ " "olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
"olcDitContentRules ) )", Cft_Global }, "olcDitContentRules ) )", Cft_Global },
@ -2537,7 +2537,7 @@ config_tls_option(ConfigArgs *c) {
case CFG_TLS_CERT_KEY: flag = LDAP_OPT_X_TLS_KEYFILE; break; case CFG_TLS_CERT_KEY: flag = LDAP_OPT_X_TLS_KEYFILE; break;
case CFG_TLS_CA_PATH: flag = LDAP_OPT_X_TLS_CACERTDIR; break; case CFG_TLS_CA_PATH: flag = LDAP_OPT_X_TLS_CACERTDIR; break;
case CFG_TLS_CA_FILE: flag = LDAP_OPT_X_TLS_CACERTFILE; break; case CFG_TLS_CA_FILE: flag = LDAP_OPT_X_TLS_CACERTFILE; break;
case CFG_TLS_DH_DIR: flag = LDAP_OPT_X_TLS_DHPARAMDIR; break; case CFG_TLS_DH_FILE: flag = LDAP_OPT_X_TLS_DHFILE; break;
default: Debug(LDAP_DEBUG_ANY, "%s: " default: Debug(LDAP_DEBUG_ANY, "%s: "
"unknown tls_option <0x%x>\n", "unknown tls_option <0x%x>\n",
c->log, c->type, 0); c->log, c->type, 0);