From: Viktor Dukhovni Date: Thu, 4 Feb 2016 08:38:57 +0000 (-0500) Subject: Bitrot: use RSA_generate_key_ex with OpenSSL >= 1.0.0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=87c4627eeb4ee0b86d2d94c5924cc8528be86904;p=thirdparty%2Fpostfix.git Bitrot: use RSA_generate_key_ex with OpenSSL >= 1.0.0 --- diff --git a/postfix/src/tls/tls_rsa.c b/postfix/src/tls/tls_rsa.c index 3e85e19d9..c440b1e9f 100644 --- a/postfix/src/tls/tls_rsa.c +++ b/postfix/src/tls/tls_rsa.c @@ -12,10 +12,12 @@ /* int export; /* int keylength; /* DESCRIPTION -/* This module maintains parameters for Diffie-Hellman key generation. -/* /* tls_tmp_rsa_cb() is a call-back routine for the /* SSL_CTX_set_tmp_rsa_callback() function. +/* +/* This implementation will generate only 512-bit ephemeral +/* RSA keys for export ciphersuites. It will log a warning in +/* all other usage contexts. /* LICENSE /* .ad /* .fi @@ -35,11 +37,14 @@ /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Viktor Dukhovni. /*--*/ /* System library. */ #include +#include #ifdef USE_TLS @@ -47,6 +52,7 @@ #define TLS_INTERNAL #include +#include /* * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev @@ -55,30 +61,68 @@ /* tls_tmp_rsa_cb - call-back to generate ephemeral RSA key */ -RSA *tls_tmp_rsa_cb(SSL *unused_ssl, int unused_export, int keylength) +RSA *tls_tmp_rsa_cb(SSL *unused_ssl, int export, int keylength) { static RSA *rsa_tmp; - /* Code adapted from OpenSSL apps/s_cb.c */ + /* + * We generate ephemeral RSA keys only for export ciphersuites. In all + * other contexts use of ephemeral RSA keys violates the SSL/TLS + * protocol, and only takes place when applications ask for trouble and + * set the SSL_OP_EPHEMERAL_RSA option. Postfix should never do that. + */ + if (!export || keylength != 512) { + msg_warn("%sexport %d-bit ephemeral RSA key requested", + export ? "" : "non-", keylength); + return 0; + } +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + if (rsa_tmp == 0) { + BIGNUM *e = BN_new(); + if (e != 0 && BN_set_word(e, RSA_F4) && (rsa_tmp = RSA_new()) != 0) + if (!RSA_generate_key_ex(rsa_tmp, keylength, e, 0)) { + RSA_free(rsa_tmp); + rsa_tmp = 0; + } + if (e) + BN_free(e); + } +#else if (rsa_tmp == 0) rsa_tmp = RSA_generate_key(keylength, RSA_F4, NULL, NULL); +#endif + return (rsa_tmp); } -#endif /* OPENSSL_VERSION_NUMBER */ + +#endif /* OPENSSL_VERSION_NUMBER */ #ifdef TEST -int main(int unused_argc, char **unused_argv) +#include + +int main(int unused_argc, char *const argv[]) { - int ok = 1; + int ok = 0; + /* * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev */ #if OPENSSL_VERSION_NUMBER < 0x10100000L - ok = ok && tls_tmp_rsa_cb(0, 1, 512) != 0; - ok = ok && tls_tmp_rsa_cb(0, 0, 1024) != 0; - ok = ok && tls_tmp_rsa_cb(0, 0, 2048) != 0; + RSA *rsa; + + msg_vstream_init(argv[0], VSTREAM_ERR); + + /* Export at 512-bits should work */ + rsa = tls_tmp_rsa_cb(0, 1, 512); + ok = rsa != 0 && RSA_size(rsa) == 512 / 8; + ok = ok && PEM_write_RSAPrivateKey(stdout, rsa, 0, 0, 0, 0, 0); + tls_print_errors(); + + /* Non-export or unexpected bit length should fail */ + ok = ok && tls_tmp_rsa_cb(0, 0, 512) == 0; + ok = ok && tls_tmp_rsa_cb(0, 1, 1024) == 0; #endif return ok ? 0 : 1;