summaryrefslogtreecommitdiffstats
path: root/qmail-smtpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'qmail-smtpd.c')
-rw-r--r--qmail-smtpd.c92
1 files changed, 64 insertions, 28 deletions
diff --git a/qmail-smtpd.c b/qmail-smtpd.c
index 3360cfe..817524d 100644
--- a/qmail-smtpd.c
+++ b/qmail-smtpd.c
@@ -1141,41 +1141,78 @@ void smtp_tls(char *arg)
1141 else tls_init(); 1141 else tls_init();
1142} 1142}
1143 1143
1144RSA *tmp_rsa_cb(SSL *ssl, int export, int keylen) 1144/*
1145 * Grab well-defined DH parameters from OpenSSL, see the get_rfc*
1146 * functions in <openssl/bn.h> for all available primes.
1147 */
1148static DH *make_dh_params(BIGNUM *(*prime)(BIGNUM *), const char *gen)
1145{ 1149{
1146 if (!export) keylen = 512; 1150 DH *dh = DH_new();
1147 if (keylen == 512) { 1151
1148 FILE *in = fopen("control/rsa512.pem", "r"); 1152 if (!dh) {
1149 if (in) { 1153 return NULL;
1150 RSA *rsa = PEM_read_RSAPrivateKey(in, NULL, NULL, NULL);
1151 fclose(in);
1152 if (rsa) return rsa;
1153 } 1154 }
1154 } 1155 dh->p = prime(NULL);
1155 return RSA_generate_key(keylen, RSA_F4, NULL, NULL); 1156 BN_dec2bn(&dh->g, gen);
1157 if (!dh->p || !dh->g) {
1158 DH_free(dh);
1159 return NULL;
1160 }
1161 return dh;
1156} 1162}
1157 1163
1164/* Storage and initialization for DH parameters. */
1165static struct dhparam {
1166 BIGNUM *(*const prime)(BIGNUM *); /* function to generate... */
1167 DH *dh; /* ...this, used for keys.... */
1168 const unsigned int min; /* ...of length >= this. */
1169} dhparams[] = {
1170 { get_rfc3526_prime_8192, NULL, 6145 },
1171 { get_rfc3526_prime_6144, NULL, 4097 },
1172 { get_rfc3526_prime_4096, NULL, 3073 },
1173 { get_rfc3526_prime_3072, NULL, 2049 },
1174 { get_rfc3526_prime_2048, NULL, 1025 },
1175 { get_rfc2409_prime_1024, NULL, 0 }
1176};
1177
1178/* Hand out the same DH structure though once generated as we leak
1179 * memory otherwise and freeing the structure up after use would be
1180 * hard to track and in fact is not needed at all as it is safe to
1181 * use the same parameters over and over again security wise (in
1182 * contrast to the keys itself) and code safe as the returned structure
1183 * is duplicated by OpenSSL anyway. Hence no modification happens
1184 * to our copy. */
1158DH *tmp_dh_cb(SSL *ssl, int export, int keylen) 1185DH *tmp_dh_cb(SSL *ssl, int export, int keylen)
1159{ 1186{
1160 if (!export) keylen = 1024; 1187 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1161 if (keylen == 512) { 1188 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1162 FILE *in = fopen("control/dh512.pem", "r"); 1189 unsigned n;
1163 if (in) { 1190
1164 DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL); 1191 /*
1165 fclose(in); 1192 * OpenSSL will call us with either keylen == 512 or keylen == 1024
1166 if (dh) return dh; 1193 * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
1194 * Adjust the DH parameter length according to the size of the
1195 * RSA/DSA private key used for the current connection, and always
1196 * use at least 1024-bit parameters.
1197 * Note: This may cause interoperability issues with implementations
1198 * which limit their DH support to 1024 bit - e.g. Java 7 and earlier.
1199 * In this case, SSLCertificateFile can be used to specify fixed
1200 * 1024-bit DH parameters (with the effect that OpenSSL skips this
1201 * callback).
1202 */
1203 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA)
1204 keylen = EVP_PKEY_bits(pkey);
1205
1206 for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) {
1207 if (keylen >= dhparams[n].min) {
1208 if (dhparams[n].dh == NULL)
1209 dhparams[n].dh = make_dh_params(dhparams[n].prime, "2");
1210 return dhparams[n].dh;
1167 } 1211 }
1168 } 1212 }
1169 if (keylen == 1024) { 1213
1170 FILE *in = fopen("control/dh1024.pem", "r"); 1214 return NULL; /* impossible to reach. */
1171 if (in) { 1215}
1172 DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL);
1173 fclose(in);
1174 if (dh) return dh;
1175 }
1176 }
1177 return DH_generate_parameters(keylen, DH_GENERATOR_2, NULL, NULL);
1178}
1179 1216
1180/* don't want to fail handshake if cert isn't verifiable */ 1217/* don't want to fail handshake if cert isn't verifiable */
1181int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } 1218int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; }
@@ -1338,7 +1375,6 @@ void tls_init()
1338 SSL_set_cipher_list(myssl, ciphers); 1375 SSL_set_cipher_list(myssl, ciphers);
1339 alloc_free(saciphers.s); 1376 alloc_free(saciphers.s);
1340 1377
1341 SSL_set_tmp_rsa_callback(myssl, tmp_rsa_cb);
1342 SSL_set_tmp_dh_callback(myssl, tmp_dh_cb); 1378 SSL_set_tmp_dh_callback(myssl, tmp_dh_cb);
1343 SSL_set_rfd(myssl, ssl_rfd = substdio_fileno(&ssin)); 1379 SSL_set_rfd(myssl, ssl_rfd = substdio_fileno(&ssin));
1344 SSL_set_wfd(myssl, ssl_wfd = substdio_fileno(&ssout)); 1380 SSL_set_wfd(myssl, ssl_wfd = substdio_fileno(&ssout));