]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#7595 Add Elliptic Curve support for OpenSSL
authorHoward Chu <hyc@openldap.org>
Sat, 7 Sep 2013 16:47:19 +0000 (09:47 -0700)
committerQuanah Gibson-Mount <quanah@openldap.org>
Mon, 6 May 2019 20:07:30 +0000 (20:07 +0000)
doc/man/man5/slapd-config.5
doc/man/man5/slapd.conf.5
include/ldap.h
libraries/libldap/ldap-int.h
libraries/libldap/tls2.c
libraries/libldap/tls_o.c
servers/slapd/bconfig.c

index cb499e5111a436763d647fb116b2bb0de3013ec4..b332c1e43f0961f6b090c5586e3ce76d59899081 100644 (file)
@@ -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,
index a25d39dfeea23c496c49f80c4b6111277ffbc1c4..41e50aa47993b8ef84ba7389fa89ff5519ce87f0 100644 (file)
@@ -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,
index a86574488bfc599237f13e1617574adf86f1b65c..12a0fa58ed4077a040e2526ef1cc474d575b8aac 100644 (file)
@@ -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
index 0e99873a13ff79dd6c85a45824f39604e05a69c5..ebaab3336dc63cb8d24211e2016f25fbe406d7cf 100644 (file)
@@ -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
index bc93e4d633b37f40e61aa79022159546bd00dea9..71472dc5fd068336c63fedd2272caf38d83974d9 100644 (file)
@@ -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;
index 056dafc9a7a6e38f62ebcbee3924822120d29f38..d3fc020833986f22098d3dca20387158ef9b2269 100644 (file)
@@ -382,10 +382,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,
@@ -404,7 +403,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 );
index 7d99c5d75869908c7d5e6b9ba3a0374441c4400c..f5ff90fbb1b85051d2289c09e32e870ca2333c39 100644 (file)
@@ -194,7 +194,7 @@ enum {
        CFG_ACL_ADD,
        CFG_SYNC_SUBENTRY,
        CFG_LTHREADS,
-
+       CFG_TLS_ECNAME,
        CFG_LAST
 };
 
@@ -738,6 +738,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 +827,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 +3832,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