From: Kaspar Brand Date: Sun, 29 Sep 2013 10:35:46 +0000 (+0000) Subject: Improve ephemeral key handling (companion to r1526168): X-Git-Tag: 2.5.0-alpha~4994 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=169f992d899d366a74162e18169986fb5dcdc6cf;p=apache Improve ephemeral key handling (companion to r1526168): - allow to configure custom DHE or ECDHE parameters via the SSLCertificateFile directive, and adapt its documentation accordingly (addresses PR 49559) - add standardized DH parameters from RFCs 2409 and 3526, use them based on the length of the certificate's RSA/DSA key, and add a FAQ entry for clients which limit DH support to 1024 bits (such as Java 7 and earlier) - move ssl_dh_GetParamFromFile() from ssl_engine_dh.c to ssl_util_ssl.c, and add ssl_ec_GetParamFromFile() - drop ssl_engine_dh.c from mod_ssl For the standardized DH parameters, OpenSSL version 0.9.8a or later is required, which was therefore made a new minimum requirement in r1527294. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1527295 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 357ccb322a..93bfe4bed6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,12 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_ssl: Improve handling of ephemeral DH and ECDH keys by + allowing custom parameters to be configured via SSLCertificateFile, + and by adding standardized DH parameters for 1024/2048/3072/4096 bits. + Unless custom parameters are configured, the standardized parameters + are applied based on the certificate's RSA/DSA key size. + *) mod_ssl, configure: Require OpenSSL 0.9.8a or later. [Kaspar Brand] *) mod_lua: Let the Inter-VM get/set functions work with a global diff --git a/CMakeLists.txt b/CMakeLists.txt index d8c1cf0be5..3965939785 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -417,7 +417,7 @@ IF(OPENSSL_FOUND) SET(mod_ssl_extra_libs ${OPENSSL_LIBRARIES}) ENDIF() SET(mod_ssl_extra_sources - modules/ssl/ssl_engine_config.c modules/ssl/ssl_engine_dh.c + modules/ssl/ssl_engine_config.c modules/ssl/ssl_engine_init.c modules/ssl/ssl_engine_io.c modules/ssl/ssl_engine_kernel.c modules/ssl/ssl_engine_log.c modules/ssl/ssl_engine_mutex.c modules/ssl/ssl_engine_ocsp.c diff --git a/LAYOUT b/LAYOUT index 9a630689c9..b5faadb132 100644 --- a/LAYOUT +++ b/LAYOUT @@ -108,7 +108,6 @@ modules/ ................ Manditory and Add-In Apache stock modules mod_ssl.c ............... main source file containing API structures mod_ssl.h ............... common header file of mod_ssl ssl_engine_config.c ..... module configuration handling - ssl_engine_dh.c ......... DSA/DH support ssl_engine_init.c ....... module initialization ssl_engine_io.c ......... I/O support ssl_engine_kernel.c ..... SSL engine kernel diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml index 62d1c3d644..6be654289b 100644 --- a/docs/manual/mod/mod_ssl.xml +++ b/docs/manual/mod/mod_ssl.xml @@ -808,12 +808,33 @@ SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW

-This directive points to the PEM-encoded Certificate file for the server and -optionally also to the corresponding RSA or DSA Private Key file for it -(contained in the same file). If the contained Private Key is encrypted the -Pass Phrase dialog is forced at startup time. This directive can be used up to -three times (referencing different filenames) when both a RSA, a DSA, and an -ECC based server certificate is used in parallel.

+This directive points to the file with the PEM-encoded certificate, +optionally also the corresponding private key, and - beginning with +version 2.5.0-dev as of 2013-09-29 - DH parameters and/or an EC curve name +for ephemeral keys (as generated by openssl dhparam +and openssl ecparam, respectively). If the private key +is encrypted, the pass phrase dialog is forced at startup time. +

+

+This directive can be used up to three times (referencing different filenames) +when both an RSA, a DSA, and an ECC based server certificate is used in +parallel. Note that DH and ECDH parameters are only read from the first +SSLCertificateFile directive.

+ + +DH parameter interoperability with primes > 1024 bit +

+Beginning with version 2.5.0-dev as of 2013-09-29, mod_ssl makes use of +standardized DH parameters with prime lengths of 2048, 3072 and 4096 bits +(from RFC 3526), and hands +them out to clients based on the length of the certificate's RSA/DSA key. +With Java-based clients in particular (Java 7 or earlier), this may lead +to handshake failures - see this +FAQ answer for working around +such issues. +

+
+ Example SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt diff --git a/docs/manual/ssl/ssl_faq.xml b/docs/manual/ssl/ssl_faq.xml index 22aa7b32f0..0e340a2f6a 100644 --- a/docs/manual/ssl/ssl_faq.xml +++ b/docs/manual/ssl/ssl_faq.xml @@ -519,6 +519,8 @@ Does this mean the username/password is being sent unencrypted?
  • Why do I get I/O errors when connecting via HTTPS to an Apache+mod_ssl server with Microsoft Internet Explorer (MSIE)?
  • +
  • How do I enable TLS-SRP?
  • +
  • Why do I get handshake failures with Java-based clients when using a certificate with more than 1024 bits?
  • Why do I get lots of random SSL protocol @@ -740,6 +742,37 @@ SetEnvIf User-Agent "MSIE [2-5]" \ </example> </section> +<section id="javadh"><title>Why do I get handshake failures with Java-based clients when using a certificate with more than 1024 bits? +

    Beginning with version 2.5.0-dev as of 2013-09-29, + mod_ssl will use DH parameters which include primes + with lengths of more than 1024 bits. Java 7 and earlier limit their + support for DH prime sizes to a maximum of 1024 bits, however.

    + +

    If your Java-based client aborts with exceptions such as + java.lang.RuntimeException: Could not generate DH keypair and + java.security.InvalidAlgorithmParameterException: Prime size must be + multiple of 64, and can only range from 512 to 1024 (inclusive), + and httpd logs tlsv1 alert internal error (SSL alert number 80) + (at LogLevel info + or higher), you can either rearrange mod_ssl's cipher list with + SSLCipherSuite + (possibly in conjunction with SSLHonorCipherOrder), + or you can use the SSLCertificateFile + directive to configure custom DH parameters with a 1024-bit prime, which + will always have precedence over any of the built-in DH parameters.

    + +

    To generate custom DH parameters, use the openssl dhparam + command. Alternatively, you can append the following standard 1024-bit DH + parameters from RFC 2409, + section 6.2 to the respective + SSLCertificateFile file:

    +
    -----BEGIN DH PARAMETERS-----
    +MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR
    +Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL
    +/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC
    +-----END DH PARAMETERS-----
    +
    + diff --git a/modules/ssl/config.m4 b/modules/ssl/config.m4 index 1b589d8150..45eeb43d9d 100644 --- a/modules/ssl/config.m4 +++ b/modules/ssl/config.m4 @@ -20,7 +20,6 @@ dnl # list of module object files ssl_objs="dnl mod_ssl.lo dnl ssl_engine_config.lo dnl -ssl_engine_dh.lo dnl ssl_engine_init.lo dnl ssl_engine_io.lo dnl ssl_engine_kernel.lo dnl diff --git a/modules/ssl/mod_ssl.dsp b/modules/ssl/mod_ssl.dsp index fc86a7b6e8..58b55456ab 100644 --- a/modules/ssl/mod_ssl.dsp +++ b/modules/ssl/mod_ssl.dsp @@ -112,10 +112,6 @@ SOURCE=.\ssl_engine_config.c # End Source File # Begin Source File -SOURCE=.\ssl_engine_dh.c -# End Source File -# Begin Source File - SOURCE=.\ssl_engine_init.c # End Source File # Begin Source File diff --git a/modules/ssl/ssl_engine_dh.c b/modules/ssl/ssl_engine_dh.c deleted file mode 100644 index 0cc7455570..0000000000 --- a/modules/ssl/ssl_engine_dh.c +++ /dev/null @@ -1,244 +0,0 @@ -#if 0 -=pod -#endif - -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* _ _ - * _ __ ___ ___ __| | ___ ___| | mod_ssl - * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL - * | | | | | | (_) | (_| | \__ \__ \ | - * |_| |_| |_|\___/ \__,_|___|___/___/_| - * |_____| - * ssl_engine_dh.c - * Diffie-Hellman Built-in Temporary Parameters - */ - -#include "ssl_private.h" - -/* ----BEGIN GENERATED SECTION-------- */ - -/* -** Diffie-Hellman-Parameters: (512 bit) -** prime: -** 00:9f:db:8b:8a:00:45:44:f0:04:5f:17:37:d0:ba: -** 2e:0b:27:4c:df:1a:9f:58:82:18:fb:43:53:16:a1: -** 6e:37:41:71:fd:19:d8:d8:f3:7c:39:bf:86:3f:d6: -** 0e:3e:30:06:80:a3:03:0c:6e:4c:37:57:d0:8f:70: -** e6:aa:87:10:33 -** generator: 2 (0x2) -** Diffie-Hellman-Parameters: (1024 bit) -** prime: -** 00:d6:7d:e4:40:cb:bb:dc:19:36:d6:93:d3:4a:fd: -** 0a:d5:0c:84:d2:39:a4:5f:52:0b:b8:81:74:cb:98: -** bc:e9:51:84:9f:91:2e:63:9c:72:fb:13:b4:b4:d7: -** 17:7e:16:d5:5a:c1:79:ba:42:0b:2a:29:fe:32:4a: -** 46:7a:63:5e:81:ff:59:01:37:7b:ed:dc:fd:33:16: -** 8a:46:1a:ad:3b:72:da:e8:86:00:78:04:5b:07:a7: -** db:ca:78:74:08:7d:15:10:ea:9f:cc:9d:dd:33:05: -** 07:dd:62:db:88:ae:aa:74:7d:e0:f4:d6:e2:bd:68: -** b0:e7:39:3e:0f:24:21:8e:b3 -** generator: 2 (0x2) -*/ - -static unsigned char dh512_p[] = { - 0x9F, 0xDB, 0x8B, 0x8A, 0x00, 0x45, 0x44, 0xF0, 0x04, 0x5F, 0x17, 0x37, - 0xD0, 0xBA, 0x2E, 0x0B, 0x27, 0x4C, 0xDF, 0x1A, 0x9F, 0x58, 0x82, 0x18, - 0xFB, 0x43, 0x53, 0x16, 0xA1, 0x6E, 0x37, 0x41, 0x71, 0xFD, 0x19, 0xD8, - 0xD8, 0xF3, 0x7C, 0x39, 0xBF, 0x86, 0x3F, 0xD6, 0x0E, 0x3E, 0x30, 0x06, - 0x80, 0xA3, 0x03, 0x0C, 0x6E, 0x4C, 0x37, 0x57, 0xD0, 0x8F, 0x70, 0xE6, - 0xAA, 0x87, 0x10, 0x33, -}; -static unsigned char dh512_g[] = { - 0x02, -}; - -static DH *get_dh512(void) -{ - DH *dh; - - if (!(dh = DH_new())) { - return NULL; - } - - dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL); - dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL); - if (!(dh->p && dh->g)) { - DH_free(dh); - return NULL; - } - - return dh; -} - -static unsigned char dh1024_p[] = { - 0xD6, 0x7D, 0xE4, 0x40, 0xCB, 0xBB, 0xDC, 0x19, 0x36, 0xD6, 0x93, 0xD3, - 0x4A, 0xFD, 0x0A, 0xD5, 0x0C, 0x84, 0xD2, 0x39, 0xA4, 0x5F, 0x52, 0x0B, - 0xB8, 0x81, 0x74, 0xCB, 0x98, 0xBC, 0xE9, 0x51, 0x84, 0x9F, 0x91, 0x2E, - 0x63, 0x9C, 0x72, 0xFB, 0x13, 0xB4, 0xB4, 0xD7, 0x17, 0x7E, 0x16, 0xD5, - 0x5A, 0xC1, 0x79, 0xBA, 0x42, 0x0B, 0x2A, 0x29, 0xFE, 0x32, 0x4A, 0x46, - 0x7A, 0x63, 0x5E, 0x81, 0xFF, 0x59, 0x01, 0x37, 0x7B, 0xED, 0xDC, 0xFD, - 0x33, 0x16, 0x8A, 0x46, 0x1A, 0xAD, 0x3B, 0x72, 0xDA, 0xE8, 0x86, 0x00, - 0x78, 0x04, 0x5B, 0x07, 0xA7, 0xDB, 0xCA, 0x78, 0x74, 0x08, 0x7D, 0x15, - 0x10, 0xEA, 0x9F, 0xCC, 0x9D, 0xDD, 0x33, 0x05, 0x07, 0xDD, 0x62, 0xDB, - 0x88, 0xAE, 0xAA, 0x74, 0x7D, 0xE0, 0xF4, 0xD6, 0xE2, 0xBD, 0x68, 0xB0, - 0xE7, 0x39, 0x3E, 0x0F, 0x24, 0x21, 0x8E, 0xB3, -}; -static unsigned char dh1024_g[] = { - 0x02, -}; - -static DH *get_dh1024(void) -{ - DH *dh; - - if (!(dh = DH_new())) { - return NULL; - } - - dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); - dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); - if (!(dh->p && dh->g)) { - DH_free(dh); - return NULL; - } - - return dh; -} - -/* ----END GENERATED SECTION---------- */ - -DH *ssl_dh_GetTmpParam(int nKeyLen) -{ - DH *dh; - - if (nKeyLen == 512) - dh = get_dh512(); - else if (nKeyLen == 1024) - dh = get_dh1024(); - else - dh = get_dh1024(); - return dh; -} - -DH *ssl_dh_GetParamFromFile(char *file) -{ - DH *dh = NULL; - BIO *bio; - - if ((bio = BIO_new_file(file, "r")) == NULL) - return NULL; - dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); - BIO_free(bio); - return (dh); -} - -/* -=cut -## -## Embedded Perl script for generating the temporary DH parameters -## - -require 5.003; -use strict; - -# configuration -my $file = $0; -my $begin = '----BEGIN GENERATED SECTION--------'; -my $end = '----END GENERATED SECTION----------'; - -# read ourself and keep a backup -open(FP, "<$file") || die; -my $source = ''; -$source .= $_ while (); -close(FP); -open(FP, ">$file.bak") || die; -print FP $source; -close(FP); - -# generate the DH parameters -print "1. Generate 512 and 1024 bit Diffie-Hellman parameters (p, g)\n"; -my $rand = ''; -foreach $file (qw(/var/log/messages /var/adm/messages - /kernel /vmunix /vmlinuz /etc/hosts /etc/resolv.conf)) { - if (-f $file) { - $rand = $file if ($rand eq ''); - $rand .= ":$file" if ($rand ne ''); - } -} -$rand = "-rand $rand" if ($rand ne ''); -system("openssl gendh $rand -out dh512.pem 512"); -system("openssl gendh $rand -out dh1024.pem 1024"); - -# generate DH param info -my $dhinfo = ''; -open(FP, "openssl dh -noout -text -in dh512.pem |") || die; -$dhinfo .= $_ while (); -close(FP); -open(FP, "openssl dh -noout -text -in dh1024.pem |") || die; -$dhinfo .= $_ while (); -close(FP); -$dhinfo =~ s|^|** |mg; -$dhinfo = "\n\/\*\n$dhinfo\*\/\n\n"; - -my $indent_args = "-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1"; - -# generate C source from DH params -my $dhsource = ''; -open(FP, "openssl dh -noout -C -in dh512.pem | indent $indent_args | expand |") || die; -$dhsource .= $_ while (); -close(FP); -open(FP, "openssl dh -noout -C -in dh1024.pem | indent $indent_args | expand |") || die; -$dhsource .= $_ while (); -close(FP); -$dhsource =~ s|(DH\s+\*get_dh)(\d+)[^}]*\n}|static $1$2(void) -{ - DH *dh; - - if (!(dh = DH_new())) { - return NULL; - } - - dh->p = BN_bin2bn(dh$2_p, sizeof(dh$2_p), NULL); - dh->g = BN_bin2bn(dh$2_g, sizeof(dh$2_g), NULL); - if (!(dh->p && dh->g)) { - DH_free(dh); - return NULL; - } - - return dh; -} -|sg; - -# generate output -my $o = $dhinfo . $dhsource; - -# insert the generated code at the target location -$source =~ s|(\/\* $begin.+?\n).*\n(.*?\/\* $end)|$1$o$2|s; - -# and update the source on disk -print "Updating file `$file'\n"; -open(FP, ">$file") || die; -print FP $source; -close(FP); - -# cleanup -unlink("dh512.pem"); -unlink("dh1024.pem"); - -=pod -*/ diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index 9a47bc02fe..0e352a2d45 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -1007,10 +1007,14 @@ static void ssl_init_server_certs(server_rec *s, const char *rsa_id, *dsa_id; #ifdef HAVE_ECC const char *ecc_id; + EC_GROUP *ecparams; + int nid; + EC_KEY *eckey; #endif const char *vhost_id = mctx->sc->vhost_id; int i; int have_rsa, have_dsa; + DH *dhparams; #ifdef HAVE_ECC int have_ecc; #endif @@ -1058,10 +1062,38 @@ static void ssl_init_server_certs(server_rec *s, ssl_die(s); } + /* + * Try to read DH parameters from the (first) SSLCertificateFile + */ + if ((mctx->pks->cert_files[0] != NULL) && + (dhparams = ssl_dh_GetParamFromFile(mctx->pks->cert_files[0]))) { + SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dhparams); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO() + "Custom DH parameters (%d bits) for %s loaded from %s", + BN_num_bits(dhparams->p), vhost_id, + mctx->pks->cert_files[0]); + } + #ifdef HAVE_ECC - /* Enable ECDHE by configuring a default curve */ - SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, - EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); + /* + * Similarly, try to read the ECDH curve name from SSLCertificateFile... + */ + if ((mctx->pks->cert_files[0] != NULL) && + (ecparams = ssl_ec_GetParamFromFile(mctx->pks->cert_files[0])) && + (nid = EC_GROUP_get_curve_name(ecparams)) && + (eckey = EC_KEY_new_by_curve_name(nid))) { + SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO() + "ECDH curve %s for %s specified in %s", + OBJ_nid2sn(nid), vhost_id, mctx->pks->cert_files[0]); + } + /* + * ...otherwise, configure NIST P-256 (required to enable ECDHE) + */ + else { + SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, + EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); + } #endif } diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 36f3c7046b..54edd9ccae 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -1300,16 +1300,69 @@ const authz_provider ssl_authz_provider_verify_client = */ /* - * Hand out the already generated DH parameters... + * Grab well-defined DH parameters from OpenSSL, see + * (get_rfc*) for all available primes. + */ +#define make_get_dh(rfc,size,gen) \ +static DH *get_dh##size(void) \ +{ \ + DH *dh; \ + if (!(dh = DH_new())) { \ + return NULL; \ + } \ + dh->p = get_##rfc##_prime_##size(NULL); \ + BN_dec2bn(&dh->g, #gen); \ + if (!dh->p || !dh->g) { \ + DH_free(dh); \ + return NULL; \ + } \ + return dh; \ +} + +/* + * Prepare DH parameters from 1024 to 4096 bits, in 1024-bit increments + */ +make_get_dh(rfc2409, 1024, 2) +make_get_dh(rfc3526, 2048, 2) +make_get_dh(rfc3526, 3072, 2) +make_get_dh(rfc3526, 4096, 2) + +/* + * Hand out standard DH parameters, based on the authentication strength */ DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) { conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); + EVP_PKEY *pkey = SSL_get_privatekey(ssl); + int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE; - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, - "handing out parameters for temporary %d bit DH key", keylen); + /* + * OpenSSL will call us with either keylen == 512 or keylen == 1024 + * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h). + * Adjust the DH parameter length according to the size of the + * RSA/DSA private key used for the current connection, and always + * use at least 1024-bit parameters. + * Note: This may cause interoperability issues with implementations + * which limit their DH support to 1024 bit - e.g. Java 7 and earlier. + * In this case, SSLCertificateFile can be used to specify fixed + * 1024-bit DH parameters (with the effect that OpenSSL skips this + * callback). + */ + if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) { + keylen = EVP_PKEY_bits(pkey); + } - return ssl_dh_GetTmpParam(keylen); + ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, + "handing out built-in DH parameters for %d-bit authenticated connection", keylen); + + if (keylen >= 4096) + return get_dh4096(); + else if (keylen >= 3072) + return get_dh3072(); + else if (keylen >= 2048) + return get_dh2048(); + else + return get_dh1024(); } /* diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 6e47ef6342..01f03be0f4 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -887,8 +887,10 @@ int ssl_init_ssl_connection(conn_rec *c, request_rec *r); void ssl_pphrase_Handle(server_rec *, apr_pool_t *); /** Diffie-Hellman Parameter Support */ -DH *ssl_dh_GetTmpParam(int); -DH *ssl_dh_GetParamFromFile(char *); +DH *ssl_dh_GetParamFromFile(const char *); +#ifdef HAVE_ECC +EC_GROUP *ssl_ec_GetParamFromFile(const char *); +#endif unsigned char *ssl_asn1_table_set(apr_hash_t *table, const char *key, diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c index a8c36adb47..9f4cfa2c71 100644 --- a/modules/ssl/ssl_util_ssl.c +++ b/modules/ssl/ssl_util_ssl.c @@ -481,6 +481,38 @@ BOOL SSL_X509_INFO_load_path(apr_pool_t *ptemp, return ok; } +/* _________________________________________________________________ +** +** Custom (EC)DH parameter support +** _________________________________________________________________ +*/ + +DH *ssl_dh_GetParamFromFile(const char *file) +{ + DH *dh = NULL; + BIO *bio; + + if ((bio = BIO_new_file(file, "r")) == NULL) + return NULL; + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + return (dh); +} + +#ifdef HAVE_ECC +EC_GROUP *ssl_ec_GetParamFromFile(const char *file) +{ + EC_GROUP *group = NULL; + BIO *bio; + + if ((bio = BIO_new_file(file, "r")) == NULL) + return NULL; + group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL); + BIO_free(bio); + return (group); +} +#endif + /* _________________________________________________________________ ** ** Extra Server Certificate Chain Support