You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
8.2 KiB
227 lines
8.2 KiB
ITS#7595 Add Elliptic Curve support for OpenSSL |
|
|
|
Cherry-picked upstream e631ce808ed56119e61321463d06db7999ba5a08 |
|
Author: Howard Chu <hyc@openldap.org> |
|
Date: Sat Sep 7 09:47:19 2013 -0700 |
|
|
|
diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5 |
|
index 9c72e8296..2311c3096 100644 |
|
--- a/doc/man/man5/slapd-config.5 |
|
+++ b/doc/man/man5/slapd-config.5 |
|
@@ -922,6 +922,13 @@ are not used. |
|
When using 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, |
|
diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 |
|
index f504adcf9..ef03e0ad8 100644 |
|
--- a/doc/man/man5/slapd.conf.5 |
|
+++ b/doc/man/man5/slapd.conf.5 |
|
@@ -1153,6 +1153,13 @@ are not used. |
|
When using Mozilla NSS these parameters are always generated randomly |
|
so this directive is ignored. |
|
.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, |
|
diff --git a/include/ldap.h b/include/ldap.h |
|
index c245651c2..0964a193e 100644 |
|
--- a/include/ldap.h |
|
+++ b/include/ldap.h |
|
@@ -158,6 +158,7 @@ LDAP_BEGIN_DECL |
|
#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 |
|
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h |
|
index 66e04ae80..db7193f4f 100644 |
|
--- a/libraries/libldap/ldap-int.h |
|
+++ b/libraries/libldap/ldap-int.h |
|
@@ -165,6 +165,7 @@ struct ldaptls { |
|
char *lt_ciphersuite; |
|
char *lt_crlfile; |
|
char *lt_randfile; /* OpenSSL only */ |
|
+ char *lt_ecname; /* OpenSSL only */ |
|
int lt_protocol_min; |
|
}; |
|
#endif |
|
@@ -250,6 +251,7 @@ struct ldapoptions { |
|
#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 |
|
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c |
|
index d25c190ea..0451b01af 100644 |
|
--- a/libraries/libldap/tls2.c |
|
+++ b/libraries/libldap/tls2.c |
|
@@ -118,6 +118,10 @@ ldap_int_tls_destroy( struct ldapoptions *lo ) |
|
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; |
|
@@ -232,6 +236,10 @@ ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server ) |
|
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 ) { |
|
@@ -257,6 +265,7 @@ error_exit: |
|
LDAP_FREE( lts.lt_crlfile ); |
|
LDAP_FREE( lts.lt_cacertdir ); |
|
LDAP_FREE( lts.lt_dhfile ); |
|
+ LDAP_FREE( lts.lt_ecname ); |
|
#endif |
|
return rc; |
|
} |
|
@@ -646,6 +655,10 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg ) |
|
*(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; |
|
@@ -765,6 +778,10 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg ) |
|
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; |
|
diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c |
|
index f24060b7e..1370923af 100644 |
|
--- a/libraries/libldap/tls_o.c |
|
+++ b/libraries/libldap/tls_o.c |
|
@@ -373,10 +373,9 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server ) |
|
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, |
|
@@ -395,7 +394,35 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server ) |
|
} |
|
BIO_free( bio ); |
|
SSL_CTX_set_tmp_dh( ctx, dh ); |
|
+ SSL_CTX_set_options( ctx, SSL_OP_SINGLE_DH_USE ); |
|
+ DH_free( dh ); |
|
+ } |
|
+ |
|
+#ifdef SSL_OP_SINGLE_ECDH_USE |
|
+ if ( is_server && lo->ldo_tls_ecname ) { |
|
+ 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 ); |
|
diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c |
|
index 250f14100..8b1e4e582 100644 |
|
--- a/servers/slapd/bconfig.c |
|
+++ b/servers/slapd/bconfig.c |
|
@@ -194,6 +194,7 @@ enum { |
|
CFG_ACL_ADD, |
|
CFG_SYNC_SUBENTRY, |
|
CFG_LTHREADS, |
|
+ CFG_TLS_ECNAME, |
|
|
|
CFG_LAST |
|
}; |
|
@@ -738,6 +739,14 @@ static ConfigTable config_back_cf_table[] = { |
|
#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, |
|
@@ -819,7 +828,7 @@ static ConfigOCs cf_ocs[] = { |
|
"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 }, |
|
@@ -3824,6 +3833,7 @@ config_tls_option(ConfigArgs *c) { |
|
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
|
|
|