diff options
Diffstat (limited to 'qmail-smtpd.c')
| -rw-r--r-- | qmail-smtpd.c | 213 |
1 files changed, 22 insertions, 191 deletions
diff --git a/qmail-smtpd.c b/qmail-smtpd.c index 5ea23dc..0d3b16d 100644 --- a/qmail-smtpd.c +++ b/qmail-smtpd.c | |||
| @@ -67,8 +67,6 @@ static const stralloc *client_get_session_id(); | |||
| 67 | 67 | ||
| 68 | #ifdef TLS | 68 | #ifdef TLS |
| 69 | # include <sys/stat.h> | 69 | # include <sys/stat.h> |
| 70 | # include <openssl/bn.h> | ||
| 71 | # include <openssl/dh.h> | ||
| 72 | # include "tls.h" | 70 | # include "tls.h" |
| 73 | # include "ssl_timeoutio.h" | 71 | # include "ssl_timeoutio.h" |
| 74 | 72 | ||
| @@ -208,7 +206,7 @@ int err_write() { out("454 oops, unable to write pipe and I can't auth (#4.3.0)\ | |||
| 208 | void err_authd() { out("503 you're already authenticated (#5.5.0)\r\n"); } | 206 | void err_authd() { out("503 you're already authenticated (#5.5.0)\r\n"); } |
| 209 | void err_authmail() { out("503 no auth during mail transaction (#5.5.0)\r\n"); do_hard_errors(); } | 207 | void err_authmail() { out("503 no auth during mail transaction (#5.5.0)\r\n"); do_hard_errors(); } |
| 210 | int err_noauth() { out("504 auth type unimplemented (#5.5.1)\r\n"); do_hard_errors(); return -1; } | 208 | int err_noauth() { out("504 auth type unimplemented (#5.5.1)\r\n"); do_hard_errors(); return -1; } |
| 211 | int err_noauth2() { out("503 auth not available (#5.3.3)\r\n"); do_hard_errors(); } | 209 | int err_noauth2() { out("503 auth not available (#5.3.3)\r\n"); do_hard_errors(); return -1; } |
| 212 | int err_authabrt() { out("501 auth exchange canceled (#5.0.0)\r\n"); return -1; } | 210 | int err_authabrt() { out("501 auth exchange canceled (#5.0.0)\r\n"); return -1; } |
| 213 | int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; } | 211 | int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; } |
| 214 | int err_wantstarttls() { out("530 Must issue a STARTTLS command first (#5.7.0)\r\n"); return -1; }; | 212 | int err_wantstarttls() { out("530 Must issue a STARTTLS command first (#5.7.0)\r\n"); return -1; }; |
| @@ -386,7 +384,7 @@ char *arg; | |||
| 386 | if (!stralloc_copys(&addr,"")) die_nomem(); | 384 | if (!stralloc_copys(&addr,"")) die_nomem(); |
| 387 | flagesc = 0; | 385 | flagesc = 0; |
| 388 | flagquoted = 0; | 386 | flagquoted = 0; |
| 389 | for (i = 0;ch = arg[i];++i) { /* copy arg to addr, stripping quotes */ | 387 | for (i = 0; (ch = arg[i]); ++i) { /* copy arg to addr, stripping quotes */ |
| 390 | if (flagesc) { | 388 | if (flagesc) { |
| 391 | if (!stralloc_append(&addr,&ch)) die_nomem(); | 389 | if (!stralloc_append(&addr,&ch)) die_nomem(); |
| 392 | flagesc = 0; | 390 | flagesc = 0; |
| @@ -485,7 +483,7 @@ int bmcheck(which) int which; | |||
| 485 | } | 483 | } |
| 486 | if ((negate) && (x == 0)) { | 484 | if ((negate) && (x == 0)) { |
| 487 | if (!stralloc_copyb(&matchedregex,bmb.s + j - 1,(i - j + 1))) die_nomem(); | 485 | if (!stralloc_copyb(&matchedregex,bmb.s + j - 1,(i - j + 1))) die_nomem(); |
| 488 | if (!stralloc_0(&matchedregex)) die_nomem(); | 486 | if (!stralloc_0(&matchedregex)) die_nomem(); |
| 489 | return 1; | 487 | return 1; |
| 490 | } | 488 | } |
| 491 | if (!(negate) && (x > 0)) { | 489 | if (!(negate) && (x > 0)) { |
| @@ -582,8 +580,6 @@ void mailfrom_auth(arg,len) | |||
| 582 | char *arg; | 580 | char *arg; |
| 583 | int len; | 581 | int len; |
| 584 | { | 582 | { |
| 585 | int j; | ||
| 586 | |||
| 587 | if (!stralloc_copys(&fuser,"")) die_nomem(); | 583 | if (!stralloc_copys(&fuser,"")) die_nomem(); |
| 588 | if (case_starts(arg,"<>")) { if (!stralloc_cats(&fuser,"unknown")) die_nomem(); } | 584 | if (case_starts(arg,"<>")) { if (!stralloc_cats(&fuser,"unknown")) die_nomem(); } |
| 589 | else | 585 | else |
| @@ -610,7 +606,7 @@ void mailfrom_parms(arg) char *arg; | |||
| 610 | int len; | 606 | int len; |
| 611 | 607 | ||
| 612 | len = str_len(arg); | 608 | len = str_len(arg); |
| 613 | if (!stralloc_copys(&mfparms,"")) die_nomem; | 609 | if (!stralloc_copys(&mfparms,"")) die_nomem(); |
| 614 | i = byte_chr(arg,len,'>'); | 610 | i = byte_chr(arg,len,'>'); |
| 615 | if (i > 4 && i < len) { | 611 | if (i > 4 && i < len) { |
| 616 | while (len) { | 612 | while (len) { |
| @@ -622,10 +618,10 @@ void mailfrom_parms(arg) char *arg; | |||
| 622 | if (case_starts(mfparms.s,"SIZE=")) if (mailfrom_size(mfparms.s+5)) { flagsize = 1; return; } | 618 | if (case_starts(mfparms.s,"SIZE=")) if (mailfrom_size(mfparms.s+5)) { flagsize = 1; return; } |
| 623 | /* we do not support this */ | 619 | /* we do not support this */ |
| 624 | //if (case_starts(mfparms.s,"AUTH=")) mailfrom_auth(mfparms.s+5,mfparms.len-5); | 620 | //if (case_starts(mfparms.s,"AUTH=")) mailfrom_auth(mfparms.s+5,mfparms.len-5); |
| 625 | if (!stralloc_copys(&mfparms,"")) die_nomem; | 621 | if (!stralloc_copys(&mfparms,"")) die_nomem(); |
| 626 | } | 622 | } |
| 627 | else | 623 | else |
| 628 | if (!stralloc_catb(&mfparms,arg,1)) die_nomem; | 624 | if (!stralloc_catb(&mfparms,arg,1)) die_nomem(); |
| 629 | } | 625 | } |
| 630 | } | 626 | } |
| 631 | } | 627 | } |
| @@ -1094,17 +1090,17 @@ int authenticate(void) | |||
| 1094 | if (authout.len > 0) { | 1090 | if (authout.len > 0) { |
| 1095 | len = authout.len; | 1091 | len = authout.len; |
| 1096 | arg = authout.s; | 1092 | arg = authout.s; |
| 1097 | if (!stralloc_copys(&authparams, "")) die_nomem; | 1093 | if (!stralloc_copys(&authparams, "")) die_nomem(); |
| 1098 | while (len) { | 1094 | while (len) { |
| 1099 | if (*arg == '\0') { | 1095 | if (*arg == '\0') { |
| 1100 | if (case_starts(authparams.s, "USER=") && (authparams.len - 5) > 0) { | 1096 | if (case_starts(authparams.s, "USER=") && (authparams.len - 5) > 0) { |
| 1101 | if (!stralloc_copyb(&user, authparams.s + 5, authparams.len - 5)) die_nomem(); | 1097 | if (!stralloc_copyb(&user, authparams.s + 5, authparams.len - 5)) die_nomem(); |
| 1102 | if (!stralloc_0(&user)) die_nomem(); | 1098 | if (!stralloc_0(&user)) die_nomem(); |
| 1103 | } | 1099 | } |
| 1104 | if (!stralloc_copys(&authparams, "")) die_nomem; | 1100 | if (!stralloc_copys(&authparams, "")) die_nomem(); |
| 1105 | } | 1101 | } |
| 1106 | else | 1102 | else |
| 1107 | if (!stralloc_catb(&authparams, arg, 1)) die_nomem; | 1103 | if (!stralloc_catb(&authparams, arg, 1)) die_nomem(); |
| 1108 | arg++; | 1104 | arg++; |
| 1109 | len--; | 1105 | len--; |
| 1110 | } | 1106 | } |
| @@ -1130,19 +1126,19 @@ int auth_login(arg) char *arg; | |||
| 1130 | if (tls_before_auth && !ssl) return err_wantstarttls(); | 1126 | if (tls_before_auth && !ssl) return err_wantstarttls(); |
| 1131 | #endif | 1127 | #endif |
| 1132 | if (*arg) { | 1128 | if (*arg) { |
| 1133 | if (r = b64decode(arg,str_len(arg),&user) == 1) return err_input(); | 1129 | if ((r = b64decode(arg,str_len(arg),&user)) == 1) return err_input(); |
| 1134 | } | 1130 | } |
| 1135 | else { | 1131 | else { |
| 1136 | out("334 VXNlcm5hbWU6\r\n"); flush(); /* Username: */ | 1132 | out("334 VXNlcm5hbWU6\r\n"); flush(); /* Username: */ |
| 1137 | if (authgetl() < 0) return -1; | 1133 | if (authgetl() < 0) return -1; |
| 1138 | if (r = b64decode(authin.s,authin.len,&user) == 1) return err_input(); | 1134 | if ((r = b64decode(authin.s,authin.len,&user)) == 1) return err_input(); |
| 1139 | } | 1135 | } |
| 1140 | if (r == -1) die_nomem(); | 1136 | if (r == -1) die_nomem(); |
| 1141 | 1137 | ||
| 1142 | out("334 UGFzc3dvcmQ6\r\n"); flush(); /* Password: */ | 1138 | out("334 UGFzc3dvcmQ6\r\n"); flush(); /* Password: */ |
| 1143 | 1139 | ||
| 1144 | if (authgetl() < 0) return -1; | 1140 | if (authgetl() < 0) return -1; |
| 1145 | if (r = b64decode(authin.s,authin.len,&pass) == 1) return err_input(); | 1141 | if ((r = b64decode(authin.s,authin.len,&pass)) == 1) return err_input(); |
| 1146 | if (r == -1) die_nomem(); | 1142 | if (r == -1) die_nomem(); |
| 1147 | 1143 | ||
| 1148 | if (!user.len || !pass.len) return err_input(); | 1144 | if (!user.len || !pass.len) return err_input(); |
| @@ -1157,12 +1153,12 @@ int auth_plain(arg) char *arg; | |||
| 1157 | if (tls_before_auth && !ssl) return err_wantstarttls(); | 1153 | if (tls_before_auth && !ssl) return err_wantstarttls(); |
| 1158 | #endif | 1154 | #endif |
| 1159 | if (*arg) { | 1155 | if (*arg) { |
| 1160 | if (r = b64decode(arg,str_len(arg),&resp) == 1) return err_input(); | 1156 | if ((r = b64decode(arg,str_len(arg),&resp)) == 1) return err_input(); |
| 1161 | } | 1157 | } |
| 1162 | else { | 1158 | else { |
| 1163 | out("334 \r\n"); flush(); | 1159 | out("334 \r\n"); flush(); |
| 1164 | if (authgetl() < 0) return -1; | 1160 | if (authgetl() < 0) return -1; |
| 1165 | if (r = b64decode(authin.s,authin.len,&resp) == 1) return err_input(); | 1161 | if ((r = b64decode(authin.s,authin.len,&resp)) == 1) return err_input(); |
| 1166 | } | 1162 | } |
| 1167 | if (r == -1 || !stralloc_0(&resp)) die_nomem(); | 1163 | if (r == -1 || !stralloc_0(&resp)) die_nomem(); |
| 1168 | while (resp.s[id]) id++; /* "authorize-id\0userid\0passwd\0" */ | 1164 | while (resp.s[id]) id++; /* "authorize-id\0userid\0passwd\0" */ |
| @@ -1297,140 +1293,6 @@ void smtp_tls(char *arg) | |||
| 1297 | else tls_init(); | 1293 | else tls_init(); |
| 1298 | } | 1294 | } |
| 1299 | 1295 | ||
| 1300 | /* | ||
| 1301 | * Grab well-defined DH parameters from OpenSSL, see the get_rfc* | ||
| 1302 | * functions in <openssl/bn.h> for all available primes. | ||
| 1303 | */ | ||
| 1304 | #if OPENSSL_VERSION_NUMBER < 0x10100005L | ||
| 1305 | static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) | ||
| 1306 | { | ||
| 1307 | /* q is optional */ | ||
| 1308 | if (p == NULL || g == NULL) | ||
| 1309 | return 0; | ||
| 1310 | BN_free(dh->p); | ||
| 1311 | BN_free(dh->q); | ||
| 1312 | BN_free(dh->g); | ||
| 1313 | dh->p = p; | ||
| 1314 | dh->q = q; | ||
| 1315 | dh->g = g; | ||
| 1316 | |||
| 1317 | if (q != NULL) | ||
| 1318 | dh->length = BN_num_bits(q); | ||
| 1319 | |||
| 1320 | return 1; | ||
| 1321 | } | ||
| 1322 | #endif | ||
| 1323 | |||
| 1324 | static DH *make_dh_params(BIGNUM *(*prime)(BIGNUM *)) | ||
| 1325 | { | ||
| 1326 | BIGNUM *p, *g; | ||
| 1327 | DH *dh = DH_new(); | ||
| 1328 | if (!dh) | ||
| 1329 | return NULL; | ||
| 1330 | |||
| 1331 | p = prime(NULL); | ||
| 1332 | g = BN_new(); | ||
| 1333 | if (g != NULL) | ||
| 1334 | BN_set_word(g, 2); | ||
| 1335 | if (!p || !g || !DH_set0_pqg(dh, p, NULL, g)) { | ||
| 1336 | DH_free(dh); | ||
| 1337 | BN_free(p); | ||
| 1338 | BN_free(g); | ||
| 1339 | return NULL; | ||
| 1340 | } | ||
| 1341 | return dh; | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | /* Storage and initialization for DH parameters. */ | ||
| 1345 | static struct dhparam { | ||
| 1346 | BIGNUM *(*const prime)(BIGNUM *); /* function to generate... */ | ||
| 1347 | DH *dh; /* ...this, used for keys.... */ | ||
| 1348 | const unsigned int min; /* ...of length >= this. */ | ||
| 1349 | } dhparams[] = { | ||
| 1350 | { get_rfc3526_prime_8192, NULL, 6145 }, | ||
| 1351 | { get_rfc3526_prime_6144, NULL, 4097 }, | ||
| 1352 | { get_rfc3526_prime_4096, NULL, 3073 }, | ||
| 1353 | { get_rfc3526_prime_3072, NULL, 2049 }, | ||
| 1354 | { get_rfc3526_prime_2048, NULL, 1025 }, | ||
| 1355 | { get_rfc2409_prime_1024, NULL, 0 } | ||
| 1356 | }; | ||
| 1357 | |||
| 1358 | /* Hand out the same DH structure though once generated as we leak | ||
| 1359 | * memory otherwise and freeing the structure up after use would be | ||
| 1360 | * hard to track and in fact is not needed at all as it is safe to | ||
| 1361 | * use the same parameters over and over again security wise (in | ||
| 1362 | * contrast to the keys itself) and code safe as the returned structure | ||
| 1363 | * is duplicated by OpenSSL anyway. Hence no modification happens | ||
| 1364 | * to our copy. */ | ||
| 1365 | static DH *tmp_dh_cb(SSL *ssl, int export, int keylen) | ||
| 1366 | { | ||
| 1367 | EVP_PKEY *pkey = SSL_get_privatekey(ssl); | ||
| 1368 | int type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE; | ||
| 1369 | unsigned n; | ||
| 1370 | |||
| 1371 | /* | ||
| 1372 | * OpenSSL will call us with either keylen == 512 or keylen == 1024 | ||
| 1373 | * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h). | ||
| 1374 | * Adjust the DH parameter length according to the size of the | ||
| 1375 | * RSA/DSA private key used for the current connection, and always | ||
| 1376 | * use at least 1024-bit parameters. | ||
| 1377 | * Note: This may cause interoperability issues with implementations | ||
| 1378 | * which limit their DH support to 1024 bit - e.g. Java 7 and earlier. | ||
| 1379 | * In this case, SSLCertificateFile can be used to specify fixed | ||
| 1380 | * 1024-bit DH parameters (with the effect that OpenSSL skips this | ||
| 1381 | * callback). | ||
| 1382 | */ | ||
| 1383 | if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) | ||
| 1384 | keylen = EVP_PKEY_bits(pkey); | ||
| 1385 | |||
| 1386 | for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) { | ||
| 1387 | if (keylen >= dhparams[n].min) { | ||
| 1388 | if (dhparams[n].dh == NULL) | ||
| 1389 | dhparams[n].dh = make_dh_params(dhparams[n].prime); | ||
| 1390 | return dhparams[n].dh; | ||
| 1391 | } | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | return NULL; /* impossible to reach. */ | ||
| 1395 | } | ||
| 1396 | |||
| 1397 | static DH *ssl_dh_GetParamFromFile(const char *file) | ||
| 1398 | { | ||
| 1399 | DH *dh = NULL; | ||
| 1400 | BIO *bio; | ||
| 1401 | |||
| 1402 | if ((bio = BIO_new_file(file, "r")) == NULL) | ||
| 1403 | return NULL; | ||
| 1404 | dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); | ||
| 1405 | BIO_free(bio); | ||
| 1406 | if (!dh) | ||
| 1407 | (void)ERR_get_error(); | ||
| 1408 | return dh; | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | #ifdef HAVE_ECC | ||
| 1412 | static EC_GROUP *ssl_ec_GetParamFromFile(const char *file) | ||
| 1413 | { | ||
| 1414 | EC_GROUP *group = NULL; | ||
| 1415 | BIO *bio; | ||
| 1416 | |||
| 1417 | if ((bio = BIO_new_file(file, "r")) == NULL) | ||
| 1418 | return NULL; | ||
| 1419 | group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL); | ||
| 1420 | BIO_free(bio); | ||
| 1421 | if (!group) | ||
| 1422 | (void)ERR_get_error(); | ||
| 1423 | return group; | ||
| 1424 | } | ||
| 1425 | |||
| 1426 | #if !defined(SSL_set_ecdh_auto) | ||
| 1427 | static EC_KEY *tmp_ecdh_cb(SSL *ssl, int export, int keylen) | ||
| 1428 | { | ||
| 1429 | return EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); | ||
| 1430 | } | ||
| 1431 | #endif | ||
| 1432 | #endif | ||
| 1433 | |||
| 1434 | /* don't want to fail handshake if cert isn't verifiable */ | 1296 | /* don't want to fail handshake if cert isn't verifiable */ |
| 1435 | int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } | 1297 | int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } |
| 1436 | 1298 | ||
| @@ -1455,15 +1317,7 @@ void tls_init() | |||
| 1455 | SSL_CTX *ctx; | 1317 | SSL_CTX *ctx; |
| 1456 | const char *ciphers; | 1318 | const char *ciphers; |
| 1457 | stralloc saciphers = {0}; | 1319 | stralloc saciphers = {0}; |
| 1458 | X509_STORE *store; | ||
| 1459 | X509_LOOKUP *lookup; | ||
| 1460 | const char *servercert, *servercert2; | 1320 | const char *servercert, *servercert2; |
| 1461 | DH *dhparams; | ||
| 1462 | #ifdef HAVE_ECC | ||
| 1463 | EC_GROUP *ecparams; | ||
| 1464 | int nid; | ||
| 1465 | EC_KEY *eckey = NULL; | ||
| 1466 | #endif | ||
| 1467 | struct stat st; | 1321 | struct stat st; |
| 1468 | 1322 | ||
| 1469 | /* if set, use servercert selected through SMTP_SERVERCERT env var */ | 1323 | /* if set, use servercert selected through SMTP_SERVERCERT env var */ |
| @@ -1475,7 +1329,7 @@ void tls_init() | |||
| 1475 | SSL_library_init(); | 1329 | SSL_library_init(); |
| 1476 | 1330 | ||
| 1477 | /* a new SSL context with the bare minimum of options */ | 1331 | /* a new SSL context with the bare minimum of options */ |
| 1478 | ctx = SSL_CTX_new(SSLv23_server_method()); | 1332 | ctx = SSL_CTX_new(TLS_server_method()); |
| 1479 | if (!ctx) { tls_err("unable to initialize ctx"); return; } | 1333 | if (!ctx) { tls_err("unable to initialize ctx"); return; } |
| 1480 | int min_ssl_version = (*childargs) ? TLS1_2_VERSION : TLS1_VERSION; | 1334 | int min_ssl_version = (*childargs) ? TLS1_2_VERSION : TLS1_VERSION; |
| 1481 | SSL_CTX_set_min_proto_version(ctx, min_ssl_version); | 1335 | SSL_CTX_set_min_proto_version(ctx, min_ssl_version); |
| @@ -1490,13 +1344,13 @@ void tls_init() | |||
| 1490 | 1344 | ||
| 1491 | /* this will also check whether public and private keys match */ | 1345 | /* this will also check whether public and private keys match */ |
| 1492 | if (!SSL_CTX_use_PrivateKey_file(ctx, servercert, SSL_FILETYPE_PEM)) | 1346 | if (!SSL_CTX_use_PrivateKey_file(ctx, servercert, SSL_FILETYPE_PEM)) |
| 1493 | { SSL_free(myssl); tls_err("no valid private key"); return; } | 1347 | { SSL_CTX_free(ctx); tls_err("no valid private key"); return; } |
| 1494 | 1348 | ||
| 1495 | if (stat(servercert2, &st) == 0) { | 1349 | if (stat(servercert2, &st) == 0) { |
| 1496 | if (!SSL_CTX_use_certificate_chain_file(ctx, servercert2)) | 1350 | if (!SSL_CTX_use_certificate_chain_file(ctx, servercert2)) |
| 1497 | { SSL_CTX_free(ctx); tls_err("missing alternate certificate"); return; } | 1351 | { SSL_CTX_free(ctx); tls_err("invalid alternate certificate"); return; } |
| 1498 | if (!SSL_CTX_use_PrivateKey_file(ctx, servercert2, SSL_FILETYPE_PEM)) | 1352 | if (!SSL_CTX_use_PrivateKey_file(ctx, servercert2, SSL_FILETYPE_PEM)) |
| 1499 | { SSL_free(myssl); tls_err("no valid alternate private key"); return; } | 1353 | { SSL_CTX_free(ctx); tls_err("no valid alternate private key"); return; } |
| 1500 | } | 1354 | } |
| 1501 | 1355 | ||
| 1502 | /* a new SSL object, with the rest added to it directly to avoid copying */ | 1356 | /* a new SSL object, with the rest added to it directly to avoid copying */ |
| @@ -1519,39 +1373,17 @@ void tls_init() | |||
| 1519 | SSL_set_cipher_list(myssl, ciphers); | 1373 | SSL_set_cipher_list(myssl, ciphers); |
| 1520 | alloc_free(saciphers.s); | 1374 | alloc_free(saciphers.s); |
| 1521 | 1375 | ||
| 1522 | //TODO: we shouldn't use hardcoded DH: see https://weakdh.org/ | 1376 | SSL_set_dh_auto(myssl, 1); |
| 1523 | SSL_set_tmp_dh_callback(myssl, tmp_dh_cb); | 1377 | SSL_set_ecdh_auto(myssl, 1); |
| 1524 | |||
| 1525 | /* try to read DH parameters from certificate */ | ||
| 1526 | if ((dhparams = ssl_dh_GetParamFromFile(servercert))) | ||
| 1527 | SSL_set_tmp_dh(myssl, dhparams); | ||
| 1528 | |||
| 1529 | #ifdef HAVE_ECC | ||
| 1530 | /* similarly, try to read the ECDH curve name from certificate... */ | ||
| 1531 | if ((ecparams = ssl_ec_GetParamFromFile(servercert)) && | ||
| 1532 | (nid = EC_GROUP_get_curve_name(ecparams)) && | ||
| 1533 | (eckey = EC_KEY_new_by_curve_name(nid))) { | ||
| 1534 | SSL_set_tmp_ecdh(myssl, eckey); | ||
| 1535 | } | ||
| 1536 | else { | ||
| 1537 | #if defined(SSL_set_ecdh_auto) | ||
| 1538 | /* ...otherwise, enable auto curve selection (OpenSSL 1.0.2 and later) */ | ||
| 1539 | SSL_set_ecdh_auto(myssl, 1); | ||
| 1540 | #else | ||
| 1541 | /* or set callback, which will configure NIST P-256 */ | ||
| 1542 | SSL_set_tmp_ecdh_callback(myssl, tmp_ecdh_cb); | ||
| 1543 | #endif | ||
| 1544 | } | ||
| 1545 | EC_KEY_free(eckey); | ||
| 1546 | #endif | ||
| 1547 | 1378 | ||
| 1548 | #if OPENSSL_VERSION_NUMBER >= 0x10100005L | ||
| 1549 | stralloc opensslconf = {0}; | 1379 | stralloc opensslconf = {0}; |
| 1550 | if (control_readfile(&opensslconf, "control/opensslconf", 0) == -1) | 1380 | if (control_readfile(&opensslconf, "control/opensslconf", 0) == -1) |
| 1551 | { SSL_free(myssl); die_control(); } | 1381 | { SSL_free(myssl); die_control(); } |
| 1552 | if (opensslconf.len) { | 1382 | if (opensslconf.len) { |
| 1553 | SSL_CONF_CTX *cctx = SSL_CONF_CTX_new(); | 1383 | SSL_CONF_CTX *cctx = SSL_CONF_CTX_new(); |
| 1554 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); | 1384 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); |
| 1385 | /* client + server so we can share one single file */ | ||
| 1386 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); | ||
| 1555 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); | 1387 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); |
| 1556 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); | 1388 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); |
| 1557 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SHOW_ERRORS); | 1389 | SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SHOW_ERRORS); |
| @@ -1579,7 +1411,6 @@ void tls_init() | |||
| 1579 | 1411 | ||
| 1580 | (void)SSL_CONF_CTX_finish(cctx); | 1412 | (void)SSL_CONF_CTX_finish(cctx); |
| 1581 | } | 1413 | } |
| 1582 | #endif | ||
| 1583 | 1414 | ||
| 1584 | SSL_set_rfd(myssl, ssl_rfd = substdio_fileno(&ssin)); | 1415 | SSL_set_rfd(myssl, ssl_rfd = substdio_fileno(&ssin)); |
| 1585 | SSL_set_wfd(myssl, ssl_wfd = substdio_fileno(&ssout)); | 1416 | SSL_set_wfd(myssl, ssl_wfd = substdio_fileno(&ssout)); |
