From fe23628faac08e0723c5932f01881bae27ae042a Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Sat, 8 Jul 2000 22:17:50 +0000 Subject: [PATCH] ITS#619: TLS PRNG initialization code based upon patch provided by Ted C. Cheng --- include/ldap.h | 1 + libraries/libldap/init.c | 14 ++++++--- libraries/libldap/tls.c | 67 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/include/ldap.h b/include/ldap.h index 8a06fe60e8..527344594a 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -122,6 +122,7 @@ LDAP_BEGIN_DECL #define LDAP_OPT_X_TLS 0x6007 #define LDAP_OPT_X_TLS_PROTOCOL 0x6008 #define LDAP_OPT_X_TLS_CIPHER_SUITE 0x6009 +#define LDAP_OPT_X_TLS_RANDOM_FILE 0x600a #define LDAP_OPT_X_TLS_NEVER 0 #define LDAP_OPT_X_TLS_HARD 1 diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c index 03fee191de..d507e8cb4d 100644 --- a/libraries/libldap/init.c +++ b/libraries/libldap/init.c @@ -59,26 +59,30 @@ static const struct ol_attribute { offsetof(struct ldapoptions, ldo_defbinddn)}, {0, ATTR_STRING, "BASE", NULL, offsetof(struct ldapoptions, ldo_defbase)}, - {0, ATTR_INT, "PORT", NULL, + {0, ATTR_INT, "PORT", NULL, /* deprecated */ offsetof(struct ldapoptions, ldo_defport)}, - /* **** keep this around for backward compatibility */ - {0, ATTR_URIS, "HOST", NULL, 1}, - /* **** */ - {0, ATTR_URIS, "URI", NULL, 0}, + {0, ATTR_URIS, "HOST", NULL, 1}, /* deprecated */ + {0, ATTR_URIS, "URI", NULL, 0}, /* replaces HOST/URI */ {0, ATTR_BOOL, "REFERRALS", NULL, LDAP_BOOL_REFERRALS}, {0, ATTR_BOOL, "RESTART", NULL, LDAP_BOOL_RESTART}, + +#ifdef HAVE_TLS {0, ATTR_TLS, "TLS", NULL, LDAP_OPT_X_TLS}, {0, ATTR_TLS, "TLS_CERT", NULL, LDAP_OPT_X_TLS_CERTFILE}, {0, ATTR_TLS, "TLS_KEY", NULL, LDAP_OPT_X_TLS_KEYFILE}, {0, ATTR_TLS, "TLS_CACERT", NULL, LDAP_OPT_X_TLS_CACERTFILE}, {0, ATTR_TLS, "TLS_CACERTDIR",NULL, LDAP_OPT_X_TLS_CACERTDIR}, {0, ATTR_TLS, "TLS_REQCERT", NULL, LDAP_OPT_X_TLS_REQUIRE_CERT}, + {0, ATTR_TLS, "TLS_RANDFILE", NULL, LDAP_OPT_X_TLS_RANDOM_FILE}, +#endif + #ifdef HAVE_CYRUS_SASL {0, ATTR_INT, "SASL_MINSSF", NULL, offsetof(struct ldapoptions, ldo_sasl_minssf)}, {0, ATTR_INT, "SASL_MAXSSF", NULL, offsetof(struct ldapoptions, ldo_sasl_maxssf)}, #endif + {0, ATTR_NONE, NULL, NULL, 0} }; diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c index 9e49d64197..3ecb5f4c40 100644 --- a/libraries/libldap/tls.c +++ b/libraries/libldap/tls.c @@ -29,6 +29,7 @@ #include #include #include +#include #elif defined( HAVE_SSL_H ) #include #endif @@ -40,6 +41,7 @@ static char *tls_opt_cacertfile = NULL; static char *tls_opt_cacertdir = NULL; static int tls_opt_require_cert = 0; static char *tls_opt_ciphersuite = NULL; +static char *tls_opt_randfile = NULL; #define HAS_TLS( sb ) ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \ (void *)&ldap_pvt_sockbuf_io_tls ) @@ -100,8 +102,10 @@ ldap_pvt_tls_init( void ) { static int tls_initialized = 0; - if ( tls_initialized ) - return 0; + if ( tls_initialized ) return 0; + + (void) tls_seed_PRNG( tls_opt_randfile ); + tls_initialized = 1; #ifdef LDAP_R_COMPILE tls_init_threads(); @@ -673,6 +677,7 @@ ldap_pvt_tls_config( struct ldapoptions *lo, int option, const char *arg ) case LDAP_OPT_X_TLS_CACERTDIR: case LDAP_OPT_X_TLS_CERTFILE: case LDAP_OPT_X_TLS_KEYFILE: + case LDAP_OPT_X_TLS_RANDOM_FILE: return ldap_pvt_tls_set_option( NULL, option, (void *) arg ); case LDAP_OPT_X_TLS_REQUIRE_CERT: i = ( ( strcasecmp( arg, "on" ) == 0 ) || @@ -731,6 +736,9 @@ ldap_pvt_tls_get_option( struct ldapoptions *lo, int option, void *arg ) case LDAP_OPT_X_TLS_REQUIRE_CERT: *(int *)arg = tls_opt_require_cert; break; + case LDAP_OPT_X_TLS_RANDOM_FILE: + *(char **)arg = tls_opt_randfile; + break; default: return -1; } @@ -794,6 +802,10 @@ ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg ) if ( tls_opt_ciphersuite ) free( tls_opt_ciphersuite ); tls_opt_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL; break; + case LDAP_OPT_X_TLS_RANDOM_FILE: + if (tls_opt_randfile ) free (tls_opt_randfile ); + tls_opt_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL; + break; default: return -1; } @@ -803,6 +815,9 @@ ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg ) int ldap_pvt_tls_start ( LDAP *ld, Sockbuf *sb, void *ctx_arg ) { + /* Make sure tls is initialized, including PRNG properly seeded. */ + ldap_pvt_tls_init(); + /* * Fortunately, the lib uses blocking io... */ @@ -919,13 +934,57 @@ tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length ) tmp_rsa = RSA_generate_key( key_length, RSA_F4, NULL, NULL ); if ( !tmp_rsa ) { - Debug( LDAP_DEBUG_ANY, "TLS: Failed to generate temporary %d-bit %s RSA key\n", - key_length, is_export ? "export" : "domestic", 0 ); + Debug( LDAP_DEBUG_ANY, + "TLS: Failed to generate temporary %d-bit %s RSA key\n", + key_length, is_export ? "export" : "domestic", 0 ); return NULL; } return tmp_rsa; } +static int +tls_seed_PRNG( const char *randfile ) +{ +#ifndef URANDOM_DEVICE + /* no /dev/urandom (or equiv) */ + + char buffer[1024]; + static int egdsocket = 0; + + if (randfile == NULL) { + /* The seed file is $RANDFILE if defined, otherwise $HOME/.rnd. + * If $HOME is not set or buffer too small to hold the pathname, + * an error occurs. - From RAND_file_name() man page. + * The fact is that when $HOME is NULL, .rnd is used. + */ + randfile = RAND_file_name(buffer, sizeof( buffer )); + + } else if (RAND_egd(randfile) > 0) { + /* EGD socket */ + egdsocket = 1; + return 0; + } + + if (randfile == NULL) { + Debug( LDAP_DEBUG_ANY, + "TLS: Use configuration file or $RANDFILE to define seed file", + 0, 0, 0); + return -1; + } + + RAND_load_file(randfile, -1); + + if (RAND_status() == 0) { + Debug( LDAP_DEBUG_ANY, + "TLS: PRNG has not been seeded with enough data", + 0, 0, 0); + return -1; + } +#endif + + return 0; +} + #if 0 static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length ) -- 2.39.5