From 4ebed09d81ec07faeb78b5da8946624cc825257f Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 28 Oct 2005 05:35:19 +0000 Subject: [PATCH] ITS#4017, additional revisions for DH parameters --- include/ldap.h | 2 +- libraries/libldap/tls.c | 112 ++++++++++++++++++++-------------------- servers/slapd/bconfig.c | 12 ++--- 3 files changed, 64 insertions(+), 62 deletions(-) diff --git a/include/ldap.h b/include/ldap.h index f5085f9d4a..1c12852fa4 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -136,7 +136,7 @@ LDAP_BEGIN_DECL #define LDAP_OPT_X_TLS_CRLCHECK 0x600b #define LDAP_OPT_X_TLS_CONNECT_CB 0x600c #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_HARD 1 diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c index 6774fed54d..716c243e89 100644 --- a/libraries/libldap/tls.c +++ b/libraries/libldap/tls.c @@ -50,7 +50,7 @@ static int tls_opt_trace = 1; static char *tls_opt_certfile = 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_cacertdir = NULL; 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 static char *tls_opt_ciphersuite = 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, \ (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; +typedef struct dhplist { + struct dhplist *next; + int keylength; + DH *param; +} dhplist; + +static dhplist *dhparams; + static int tls_seed_PRNG( const char *randfile ); #ifdef LDAP_R_COMPILE @@ -134,9 +141,9 @@ ldap_pvt_tls_destroy( void ) LDAP_FREE( tls_opt_keyfile ); tls_opt_keyfile = NULL; } - if ( tls_opt_dhparamdir ) { - LDAP_FREE( tls_opt_dhparamdir ); - tls_opt_dhparamdir = NULL; + if ( tls_opt_dhfile ) { + LDAP_FREE( tls_opt_dhfile ); + tls_opt_dhfile = NULL; } if ( 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 *certfile = tls_opt_certfile; char *keyfile = tls_opt_keyfile; + char *dhfile = tls_opt_dhfile; #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex ); @@ -234,6 +242,10 @@ ldap_pvt_tls_init_def_ctx( void ) keyfile = LDAP_STRDUP( keyfile ); __atoe( keyfile ); } + if ( dhfile ) { + dhfile = LDAP_STRDUP( dhfile ); + __atoe( dhfile ); + } #endif if ( tls_def_ctx == NULL ) { int i; @@ -325,6 +337,31 @@ ldap_pvt_tls_init_def_ctx( void ) 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 ) { SSL_CTX_set_info_callback( tls_def_ctx, tls_info_cb ); } @@ -366,6 +403,7 @@ error_exit: LDAP_FREE( cacertdir ); LDAP_FREE( certfile ); LDAP_FREE( keyfile ); + LDAP_FREE( dhfile ); #endif #ifdef LDAP_R_COMPILE 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_RANDOM_FILE: 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 ); 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 ? LDAP_STRDUP( tls_opt_keyfile ) : NULL; break; - case LDAP_OPT_X_TLS_DHPARAMDIR: - *(char **)arg = tls_opt_dhparamdir ? - LDAP_STRDUP( tls_opt_dhparamdir ) : NULL; + case LDAP_OPT_X_TLS_DHFILE: + *(char **)arg = tls_opt_dhfile ? + LDAP_STRDUP( tls_opt_dhfile ) : NULL; break; case LDAP_OPT_X_TLS_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 ); tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL; break; - case LDAP_OPT_X_TLS_DHPARAMDIR: - if ( tls_opt_dhparamdir ) LDAP_FREE( tls_opt_dhparamdir ); - tls_opt_dhparamdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL; - if ( tls_opt_dhparamdir ) - tls_opt_dhparamdirlen = strlen( tls_opt_dhparamdir ); + case LDAP_OPT_X_TLS_DHFILE: + if ( tls_opt_dhfile ) LDAP_FREE( tls_opt_dhfile ); + tls_opt_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL; break; case LDAP_OPT_X_TLS_REQUIRE_CERT: switch( *(int *) arg ) { @@ -1647,13 +1683,6 @@ struct dhinfo { size_t size; }; -struct dhplist { - struct dhplist *next; - int keylength; - DH *param; -}; - -static struct dhplist *dhparams; /* From the OpenSSL 0.9.7 distro */ static const char dhpem512[] = @@ -1702,18 +1731,13 @@ static const struct dhinfo dhpem[] = { { 0, NULL, 0 } }; -#define MAXDIGITS 12 - -#define DHFILEPATTERN "dh%d.pem" - static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length ) { struct dhplist *p = NULL; BIO *b = NULL; - FILE *f; - char *file; DH *dh = NULL; + int i; /* Do we have params of this length already? */ #ifdef LDAP_R_COMPILE @@ -1728,37 +1752,15 @@ 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 */ - int i; + /* No - check for hardcoded params */ - for (i=0; dhpem[i].keylength; i++) { - if ( dhpem[i].keylength == key_length ) { - b = BIO_new_mem_buf( (char *)dhpem[i].pem, dhpem[i].size ); - break; - } + for (i=0; dhpem[i].keylength; i++) { + if ( dhpem[i].keylength == key_length ) { + b = BIO_new_mem_buf( (char *)dhpem[i].pem, dhpem[i].size ); + break; } } + if ( b ) { dh = PEM_read_bio_DHparams( b, NULL, NULL, NULL ); BIO_free( b ); diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 8b66270c0f..1c8af46e89 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -136,7 +136,7 @@ enum { CFG_TLS_CERT_KEY, CFG_TLS_CA_PATH, CFG_TLS_CA_FILE, - CFG_TLS_DH_DIR, + CFG_TLS_DH_FILE, CFG_TLS_VERIFY, CFG_TLS_CRLCHECK, CFG_CONCUR, @@ -563,13 +563,13 @@ static ConfigTable config_back_cf_table[] = { #endif "( OLcfgGlAt:75 NAME 'olcTLSVerifyClient' " "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, - { "TLSDHParamDir", NULL, 0, 0, 0, + { "TLSDHParamFile", NULL, 0, 0, 0, #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 ARG_IGNORED, NULL, #endif - "( OLcfgGlAt:77 NAME 'olcTLSDHParamDir' " + "( OLcfgGlAt:77 NAME 'olcTLSDHParamFile' " "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, { "tool-threads", "count", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_TTHREADS, &config_generic, "( OLcfgGlAt:80 NAME 'olcToolThreads' " @@ -631,7 +631,7 @@ static ConfigOCs cf_ocs[] = { "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ " "olcTLSCACertificatePath $ olcTLSCertificateFile $ " "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ " - "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamDir $ " + "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ " "olcToolThreads $ " "olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ " "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_CA_PATH: flag = LDAP_OPT_X_TLS_CACERTDIR; 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: " "unknown tls_option <0x%x>\n", c->log, c->type, 0); -- 2.39.5