2016-01-21 23:42:40 +01:00

285 lines
9.3 KiB
Plaintext

$NetBSD: patch-its7595,v 1.1 2015/09/14 16:32:26 manu Exp $
ECDH support from upstream
From e631ce808ed56119e61321463d06db7999ba5a08 Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Sat, 7 Sep 2013 09:47:19 -0700
Subject: [PATCH] ITS#7595 Add Elliptic Curve support for OpenSSL
From 9562ad00bd7f965df721bc22ac905bc759298a27 Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Sat, 7 Sep 2013 10:13:40 -0700
Subject: [PATCH] ITS#7595 more doc for elliptic curve
From 721e46fe6695077d63a3df6ea2e397920a72308d Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Sun, 8 Sep 2013 06:32:23 -0700
Subject: [PATCH] ITS#7595 don't try to use EC if OpenSSL lacks it
--- doc/guide/admin/tls.sdf.orig
+++ doc/guide/admin/tls.sdf
@@ -200,8 +200,20 @@
> openssl dhparam [-dsaparam] -out <filename> <numbits>
This directive is ignored with GnuTLS and Mozilla NSS.
+H4: TLSECName <name>
+
+This directive specifies the curve to use for Elliptic Curve
+Diffie-Hellman ephemeral key exchange. This is required in order
+to use ECDHE-based cipher suites in OpenSSL. The names of supported
+curves may be shown using the following command
+
+> openssl ecparam -list_curves
+
+This directive is not used for GnuTLS and is ignored with Mozilla NSS.
+For GnuTLS the curves may be specified in the ciphersuite.
+
H4: TLSVerifyClient { never | allow | try | demand }
This directive specifies what checks to perform on client certificates
in an incoming TLS session, if any. This option is set to {{EX:never}}
--- doc/man/man5/slapd-config.5.orig
+++ doc/man/man5/slapd-config.5
@@ -917,8 +917,15 @@
from the default, otherwise no certificate exchanges or verification will
be done. When using GnuTLS or Mozilla NSS these parameters are always generated randomly
so this directive is ignored.
.TP
+.B olcTLSECName: <name>
+Specify the name of a curve to use for Elliptic curve Diffie-Hellman
+ephemeral key exchange. This is required to enable ECDHE algorithms in
+OpenSSL. This option is not used with GnuTLS; the curves may be
+chosen in the GnuTLS ciphersuite specification. This option is also
+ignored for Mozilla NSS.
+.TP
.B olcTLSProtocolMin: <major>[.<minor>]
Specifies minimum SSL/TLS protocol version that will be negotiated.
If the server doesn't support at least that version,
the SSL handshake will fail.
--- doc/man/man5/slapd.conf.5.orig
+++ doc/man/man5/slapd.conf.5
@@ -1148,8 +1148,15 @@
from the default, otherwise no certificate exchanges or verification will
be done. When using GnuTLS these parameters are always generated randomly so
this directive is ignored. This directive is ignored when using Mozilla NSS.
.TP
+.B TLSECName <name>
+Specify the name of a curve to use for Elliptic curve Diffie-Hellman
+ephemeral key exchange. This is required to enable ECDHE algorithms in
+OpenSSL. This option is not used with GnuTLS; the curves may be
+chosen in the GnuTLS ciphersuite specification. This option is also
+ignored for Mozilla NSS.
+.TP
.B TLSProtocolMin <major>[.<minor>]
Specifies minimum SSL/TLS protocol version that will be negotiated.
If the server doesn't support at least that version,
the SSL handshake will fail.
--- include/ldap.h.orig
+++ include/ldap.h
@@ -157,8 +157,9 @@
#define LDAP_OPT_X_TLS_DHFILE 0x600e
#define LDAP_OPT_X_TLS_NEWCTX 0x600f
#define LDAP_OPT_X_TLS_CRLFILE 0x6010 /* GNUtls only */
#define LDAP_OPT_X_TLS_PACKAGE 0x6011
+#define LDAP_OPT_X_TLS_ECNAME 0x6012
#define LDAP_OPT_X_TLS_NEVER 0
#define LDAP_OPT_X_TLS_HARD 1
#define LDAP_OPT_X_TLS_DEMAND 2
--- libraries/libldap/ldap-int.h.orig
+++ libraries/libldap/ldap-int.h
@@ -164,8 +164,9 @@
char *lt_cacertdir;
char *lt_ciphersuite;
char *lt_crlfile;
char *lt_randfile; /* OpenSSL only */
+ char *lt_ecname; /* OpenSSL only */
int lt_protocol_min;
};
#endif
@@ -249,8 +250,9 @@
struct ldaptls ldo_tls_info;
#define ldo_tls_certfile ldo_tls_info.lt_certfile
#define ldo_tls_keyfile ldo_tls_info.lt_keyfile
#define ldo_tls_dhfile ldo_tls_info.lt_dhfile
+#define ldo_tls_ecname ldo_tls_info.lt_ecname
#define ldo_tls_cacertfile ldo_tls_info.lt_cacertfile
#define ldo_tls_cacertdir ldo_tls_info.lt_cacertdir
#define ldo_tls_ciphersuite ldo_tls_info.lt_ciphersuite
#define ldo_tls_protocol_min ldo_tls_info.lt_protocol_min
--- libraries/libldap/tls2.c.orig
+++ libraries/libldap/tls2.c
@@ -117,8 +117,12 @@
if ( lo->ldo_tls_dhfile ) {
LDAP_FREE( lo->ldo_tls_dhfile );
lo->ldo_tls_dhfile = NULL;
}
+ if ( lo->ldo_tls_ecname ) {
+ LDAP_FREE( lo->ldo_tls_ecname );
+ lo->ldo_tls_ecname = NULL;
+ }
if ( lo->ldo_tls_cacertfile ) {
LDAP_FREE( lo->ldo_tls_cacertfile );
lo->ldo_tls_cacertfile = NULL;
}
@@ -231,8 +235,12 @@
if ( lts.lt_dhfile ) {
lts.lt_dhfile = LDAP_STRDUP( lts.lt_dhfile );
__atoe( lts.lt_dhfile );
}
+ if ( lts.lt_ecname ) {
+ lts.lt_ecname = LDAP_STRDUP( lts.lt_ecname );
+ __atoe( lts.lt_ecname );
+ }
#endif
lo->ldo_tls_ctx = ti->ti_ctx_new( lo );
if ( lo->ldo_tls_ctx == NULL ) {
Debug( LDAP_DEBUG_ANY,
@@ -256,8 +264,9 @@
LDAP_FREE( lts.lt_keyfile );
LDAP_FREE( lts.lt_crlfile );
LDAP_FREE( lts.lt_cacertdir );
LDAP_FREE( lts.lt_dhfile );
+ LDAP_FREE( lts.lt_ecname );
#endif
return rc;
}
@@ -633,8 +642,12 @@
case LDAP_OPT_X_TLS_DHFILE:
*(char **)arg = lo->ldo_tls_dhfile ?
LDAP_STRDUP( lo->ldo_tls_dhfile ) : NULL;
break;
+ case LDAP_OPT_X_TLS_ECNAME:
+ *(char **)arg = lo->ldo_tls_ecname ?
+ LDAP_STRDUP( lo->ldo_tls_ecname ) : NULL;
+ break;
case LDAP_OPT_X_TLS_CRLFILE: /* GnuTLS only */
*(char **)arg = lo->ldo_tls_crlfile ?
LDAP_STRDUP( lo->ldo_tls_crlfile ) : NULL;
break;
@@ -752,8 +765,12 @@
case LDAP_OPT_X_TLS_DHFILE:
if ( lo->ldo_tls_dhfile ) LDAP_FREE( lo->ldo_tls_dhfile );
lo->ldo_tls_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
return 0;
+ case LDAP_OPT_X_TLS_ECNAME:
+ if ( lo->ldo_tls_ecname ) LDAP_FREE( lo->ldo_tls_ecname );
+ lo->ldo_tls_ecname = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+ return 0;
case LDAP_OPT_X_TLS_CRLFILE: /* GnuTLS only */
if ( lo->ldo_tls_crlfile ) LDAP_FREE( lo->ldo_tls_crlfile );
lo->ldo_tls_crlfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
return 0;
--- libraries/libldap/tls_o.c.orig
+++ libraries/libldap/tls_o.c
@@ -295,12 +295,11 @@
tlso_report_error();
return -1;
}
- if ( lo->ldo_tls_dhfile ) {
- DH *dh = NULL;
+ if ( is_server && lo->ldo_tls_dhfile ) {
+ DH *dh;
BIO *bio;
- SSL_CTX_set_options( ctx, SSL_OP_SINGLE_DH_USE );
if (( bio=BIO_new_file( lt->lt_dhfile,"r" )) == NULL ) {
Debug( LDAP_DEBUG_ANY,
"TLS: could not use DH parameters file `%s'.\n",
@@ -317,8 +316,40 @@
return -1;
}
BIO_free( bio );
SSL_CTX_set_tmp_dh( ctx, dh );
+ SSL_CTX_set_options( ctx, SSL_OP_SINGLE_DH_USE );
+ DH_free( dh );
+ }
+
+ if ( is_server && lo->ldo_tls_ecname ) {
+#ifdef OPENSSL_NO_EC
+ Debug( LDAP_DEBUG_ANY,
+ "TLS: Elliptic Curves not supported.\n", 0,0,0 );
+ return -1;
+#else
+ EC_KEY *ecdh;
+
+ int nid = OBJ_sn2nid( lt->lt_ecname );
+ if ( nid == NID_undef ) {
+ Debug( LDAP_DEBUG_ANY,
+ "TLS: could not use EC name `%s'.\n",
+ lo->ldo_tls_ecname,0,0);
+ tlso_report_error();
+ return -1;
+ }
+ ecdh = EC_KEY_new_by_curve_name( nid );
+ if ( ecdh == NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+ "TLS: could not generate key for EC name `%s'.\n",
+ lo->ldo_tls_ecname,0,0);
+ tlso_report_error();
+ return -1;
+ }
+ SSL_CTX_set_tmp_ecdh( ctx, ecdh );
+ SSL_CTX_set_options( ctx, SSL_OP_SINGLE_ECDH_USE );
+ EC_KEY_free( ecdh );
+#endif
}
if ( tlso_opt_trace ) {
SSL_CTX_set_info_callback( ctx, tlso_info_cb );
--- servers/slapd/bconfig.c.orig
+++ servers/slapd/bconfig.c
@@ -193,8 +193,9 @@
CFG_SYNTAX,
CFG_ACL_ADD,
CFG_SYNC_SUBENTRY,
CFG_LTHREADS,
+ CFG_TLS_ECNAME,
CFG_LAST
};
@@ -737,8 +738,16 @@
ARG_IGNORED, NULL,
#endif
"( OLcfgGlAt:77 NAME 'olcTLSDHParamFile' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "TLSECName", NULL, 2, 2, 0,
+#ifdef HAVE_TLS
+ CFG_TLS_ECNAME|ARG_STRING|ARG_MAGIC, &config_tls_option,
+#else
+ ARG_IGNORED, NULL,
+#endif
+ "( OLcfgGlAt:96 NAME 'olcTLSECName' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "TLSProtocolMin", NULL, 2, 2, 0,
#ifdef HAVE_TLS
CFG_TLS_PROTOCOL_MIN|ARG_STRING|ARG_MAGIC, &config_tls_config,
#else
@@ -818,9 +827,9 @@
"olcTCPBuffer $ "
"olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
"olcTLSCACertificatePath $ olcTLSCertificateFile $ "
"olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
- "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
+ "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSECName $ "
"olcTLSCRLFile $ olcTLSProtocolMin $ olcToolThreads $ olcWriteTimeout $ "
"olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
"olcDitContentRules $ olcLdapSyntaxes ) )", Cft_Global },
{ "( OLcfgGlOc:2 "
@@ -3823,8 +3832,9 @@
case CFG_TLS_CERT_KEY: flag = LDAP_OPT_X_TLS_KEYFILE; break;
case CFG_TLS_CA_PATH: flag = LDAP_OPT_X_TLS_CACERTDIR; break;
case CFG_TLS_CA_FILE: flag = LDAP_OPT_X_TLS_CACERTFILE; break;
case CFG_TLS_DH_FILE: flag = LDAP_OPT_X_TLS_DHFILE; break;
+ case CFG_TLS_ECNAME: flag = LDAP_OPT_X_TLS_ECNAME; break;
#ifdef HAVE_GNUTLS
case CFG_TLS_CRL_FILE: flag = LDAP_OPT_X_TLS_CRLFILE; break;
#endif
default: Debug(LDAP_DEBUG_ANY, "%s: "