Package: exim4-daemon-heavy Severity: wishlist The attached patches remove RSA_EXPORT support from Exim. RSA_EXPORT was used to support insecure browsers during the U.S. crypto embargo. It requires special client support, and Exim is probably the only MTA that supports it -- and will never use it because real RSA is always available.
This patch removes blocking on /dev/random from the DH parameter generation. Exim still consumes lots of entropy, but it will never block. The only remaining problem is lack of locking, which will lead to wasted CPU cycles when multiple Exim process try to generate new DH parameters. However, CPU cycles grow much faster than random bits. The first patch has been tested to be backwards compatible (Exim still can read the old parameter format), and new DH parameters are generated correctly. The second patch only illustrates how the DH parameters file should be generated from outside Exim; it is completely untrusted. Further documentation upgrades are probably necessary.
#! /bin/sh /usr/share/dpatch/dpatch-run ## disable_rsa_export.dpatch by <[EMAIL PROTECTED]> ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: No description. @DPATCH@ diff -urNad exim4-4.63~/src/tls-gnu.c exim4-4.63/src/tls-gnu.c --- exim4-4.63~/src/tls-gnu.c 2006-07-31 16:19:48.000000000 +0200 +++ exim4-4.63/src/tls-gnu.c 2006-10-08 21:58:54.000000000 +0200 @@ -23,7 +23,6 @@ #define UNKNOWN_NAME "unknown" #define DH_BITS 768 -#define RSA_BITS 512 #define PARAM_SIZE 2*1024 @@ -37,7 +36,6 @@ static BOOL initialized = INITIALIZED_NOT; static host_item *client_host; -static gnutls_rsa_params rsa_params = NULL; static gnutls_dh_params dh_params = NULL; static gnutls_certificate_server_credentials x509_cred = NULL; @@ -57,7 +55,6 @@ GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, - GNUTLS_KX_RSA_EXPORT, 0 }; static int default_cipher_priority[16] = { @@ -262,9 +259,6 @@ /* Initialize the data structures for holding the parameters */ -ret = gnutls_rsa_params_init(&rsa_params); -if (ret < 0) return tls_error(US"init rsa_params", host, ret); - ret = gnutls_dh_params_init(&dh_params); if (ret < 0) return tls_error(US"init dh_params", host, ret); @@ -298,20 +292,10 @@ return tls_error(US"TLS cache read failed", host, 0); (void)close(fd); - ret = gnutls_rsa_params_import_pkcs1(rsa_params, &m, GNUTLS_X509_FMT_PEM); - + ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM); if (ret < 0) - { - DEBUG(D_tls) - debug_printf("RSA params import failed: assume old-style cache file\n"); - } - else - { - ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM); - if (ret < 0) - return tls_error(US"DH params import", host, ret); - DEBUG(D_tls) debug_printf("read RSA and D-H parameters from file\n"); - } + return tls_error(US"DH params import", host, ret); + DEBUG(D_tls) debug_printf("read D-H parameters from file\n"); free(m.data); } @@ -339,10 +323,6 @@ { uschar tempfilename[sizeof(filename) + 10]; - DEBUG(D_tls) debug_printf("generating %d bit RSA key...\n", RSA_BITS); - ret = gnutls_rsa_params_generate2(rsa_params, RSA_BITS); - if (ret < 0) return tls_error(US"RSA key generation", host, ret); - DEBUG(D_tls) debug_printf("generating %d bit Diffie-Hellman key...\n", DH_BITS); ret = gnutls_dh_params_generate2(dh_params, DH_BITS); @@ -362,27 +342,13 @@ * certtool or other programs. * * The commands for certtool are: - * $ certtool --generate-privkey --bits 512 >params - * $ echo "" >>params - * $ certtool --generate-dh-params --bits 1024 >> params + * $ certtool --generate-dh-params --bits 1024 > params */ m.size = PARAM_SIZE; m.data = malloc(m.size); if (m.data == NULL) return tls_error(US"memory allocation failed", host, 0); - - ret = gnutls_rsa_params_export_pkcs1(rsa_params, GNUTLS_X509_FMT_PEM, - m.data, &m.size); - if (ret < 0) return tls_error(US"RSA params export", host, ret); - - /* Do not write the null termination byte. */ - - m.size = Ustrlen(m.data); - if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1) - return tls_error(US"TLS cache write failed", host, 0); - - m.size = PARAM_SIZE; ret = gnutls_dh_params_export_pkcs3(dh_params, GNUTLS_X509_FMT_PEM, m.data, &m.size); if (ret < 0) return tls_error(US"DH params export", host, ret); @@ -398,11 +364,11 @@ return tls_error(string_sprintf("failed to rename %s as %s: %s", tempfilename, filename, strerror(errno)), host, 0); - DEBUG(D_tls) debug_printf("wrote RSA and D-H parameters to file %s\n", + DEBUG(D_tls) debug_printf("wrote D-H parameters to file %s\n", filename); } -DEBUG(D_tls) debug_printf("initialized RSA and D-H parameters\n"); +DEBUG(D_tls) debug_printf("initialized D-H parameters\n"); return OK; } @@ -540,7 +506,6 @@ /* Associate the parameters with the x509 credentials structure. */ gnutls_certificate_set_dh_params(x509_cred, dh_params); -gnutls_certificate_set_rsa_export_params(x509_cred, rsa_params); DEBUG(D_tls) debug_printf("initialized certificate stuff\n"); return OK;
--- exim4_refresh_gnutls-params 2006/10/08 20:13:09 1.1 +++ exim4_refresh_gnutls-params 2006/10/08 20:14:22 @@ -49,12 +49,9 @@ tempgnutls=$(tempfile -d $SPOOLDIR -p "gnutp" ) if [ -x /usr/bin/certtool ] ; then - if /usr/share/exim4/timeout.pl \ - "$1" /usr/bin/certtool --generate-privkey --bits 512 \ - > "$tempgnutls" 2> /dev/null && \ /usr/share/exim4/timeout.pl \ "$1" /usr/bin/certtool --generate-dh-params --bits 1024 \ - >> "$tempgnutls" 2> /dev/null ; then + > "$tempgnutls" 2> /dev/null ; then if [ -e $SPOOLDIR/gnutls-params ] ; then chmod --reference=$SPOOLDIR/gnutls-params "$tempgnutls" fi @@ -64,11 +61,8 @@ fi elif [ -x /usr/bin/openssl ] ;then if /usr/share/exim4/timeout.pl \ - "$1" /usr/bin/openssl genrsa 512 \ - > "$tempgnutls" 2> /dev/null && \ - /usr/share/exim4/timeout.pl \ "$1" /usr/bin/openssl gendh 1024 \ - >> "$tempgnutls" 2> /dev/null ; then + > "$tempgnutls" 2> /dev/null ; then if [ -e $SPOOLDIR/gnutls-params ] ; then chmod --reference=$SPOOLDIR/gnutls-params "$tempgnutls" fi