openldap-openssl-ITS7595-Add-EC-support-1.patch 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. ITS#7595 Add Elliptic Curve support for OpenSSL
  2. Cherry-picked upstream e631ce808ed56119e61321463d06db7999ba5a08
  3. Author: Howard Chu <hyc@openldap.org>
  4. Date: Sat Sep 7 09:47:19 2013 -0700
  5. diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5
  6. index 9c72e8296..2311c3096 100644
  7. --- a/doc/man/man5/slapd-config.5
  8. +++ b/doc/man/man5/slapd-config.5
  9. @@ -922,6 +922,13 @@ are not used.
  10. When using Mozilla NSS these parameters are always generated randomly
  11. so this directive is ignored.
  12. .TP
  13. +.B olcTLSECName: <name>
  14. +Specify the name of a curve to use for Elliptic curve Diffie-Hellman
  15. +ephemeral key exchange. This is required to enable ECDHE algorithms in
  16. +OpenSSL. This option is not used with GnuTLS; the curves may be
  17. +chosen in the GnuTLS ciphersuite specification. This option is also
  18. +ignored for Mozilla NSS.
  19. +.TP
  20. .B olcTLSProtocolMin: <major>[.<minor>]
  21. Specifies minimum SSL/TLS protocol version that will be negotiated.
  22. If the server doesn't support at least that version,
  23. diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5
  24. index f504adcf9..ef03e0ad8 100644
  25. --- a/doc/man/man5/slapd.conf.5
  26. +++ b/doc/man/man5/slapd.conf.5
  27. @@ -1153,6 +1153,13 @@ are not used.
  28. When using Mozilla NSS these parameters are always generated randomly
  29. so this directive is ignored.
  30. .TP
  31. +.B TLSECName <name>
  32. +Specify the name of a curve to use for Elliptic curve Diffie-Hellman
  33. +ephemeral key exchange. This is required to enable ECDHE algorithms in
  34. +OpenSSL. This option is not used with GnuTLS; the curves may be
  35. +chosen in the GnuTLS ciphersuite specification. This option is also
  36. +ignored for Mozilla NSS.
  37. +.TP
  38. .B TLSProtocolMin <major>[.<minor>]
  39. Specifies minimum SSL/TLS protocol version that will be negotiated.
  40. If the server doesn't support at least that version,
  41. diff --git a/include/ldap.h b/include/ldap.h
  42. index c245651c2..0964a193e 100644
  43. --- a/include/ldap.h
  44. +++ b/include/ldap.h
  45. @@ -158,6 +158,7 @@ LDAP_BEGIN_DECL
  46. #define LDAP_OPT_X_TLS_NEWCTX 0x600f
  47. #define LDAP_OPT_X_TLS_CRLFILE 0x6010 /* GNUtls only */
  48. #define LDAP_OPT_X_TLS_PACKAGE 0x6011
  49. +#define LDAP_OPT_X_TLS_ECNAME 0x6012
  50. #define LDAP_OPT_X_TLS_NEVER 0
  51. #define LDAP_OPT_X_TLS_HARD 1
  52. diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
  53. index 66e04ae80..db7193f4f 100644
  54. --- a/libraries/libldap/ldap-int.h
  55. +++ b/libraries/libldap/ldap-int.h
  56. @@ -165,6 +165,7 @@ struct ldaptls {
  57. char *lt_ciphersuite;
  58. char *lt_crlfile;
  59. char *lt_randfile; /* OpenSSL only */
  60. + char *lt_ecname; /* OpenSSL only */
  61. int lt_protocol_min;
  62. };
  63. #endif
  64. @@ -250,6 +251,7 @@ struct ldapoptions {
  65. #define ldo_tls_certfile ldo_tls_info.lt_certfile
  66. #define ldo_tls_keyfile ldo_tls_info.lt_keyfile
  67. #define ldo_tls_dhfile ldo_tls_info.lt_dhfile
  68. +#define ldo_tls_ecname ldo_tls_info.lt_ecname
  69. #define ldo_tls_cacertfile ldo_tls_info.lt_cacertfile
  70. #define ldo_tls_cacertdir ldo_tls_info.lt_cacertdir
  71. #define ldo_tls_ciphersuite ldo_tls_info.lt_ciphersuite
  72. diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
  73. index d25c190ea..0451b01af 100644
  74. --- a/libraries/libldap/tls2.c
  75. +++ b/libraries/libldap/tls2.c
  76. @@ -118,6 +118,10 @@ ldap_int_tls_destroy( struct ldapoptions *lo )
  77. LDAP_FREE( lo->ldo_tls_dhfile );
  78. lo->ldo_tls_dhfile = NULL;
  79. }
  80. + if ( lo->ldo_tls_ecname ) {
  81. + LDAP_FREE( lo->ldo_tls_ecname );
  82. + lo->ldo_tls_ecname = NULL;
  83. + }
  84. if ( lo->ldo_tls_cacertfile ) {
  85. LDAP_FREE( lo->ldo_tls_cacertfile );
  86. lo->ldo_tls_cacertfile = NULL;
  87. @@ -232,6 +236,10 @@ ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server )
  88. lts.lt_dhfile = LDAP_STRDUP( lts.lt_dhfile );
  89. __atoe( lts.lt_dhfile );
  90. }
  91. + if ( lts.lt_ecname ) {
  92. + lts.lt_ecname = LDAP_STRDUP( lts.lt_ecname );
  93. + __atoe( lts.lt_ecname );
  94. + }
  95. #endif
  96. lo->ldo_tls_ctx = ti->ti_ctx_new( lo );
  97. if ( lo->ldo_tls_ctx == NULL ) {
  98. @@ -257,6 +265,7 @@ error_exit:
  99. LDAP_FREE( lts.lt_crlfile );
  100. LDAP_FREE( lts.lt_cacertdir );
  101. LDAP_FREE( lts.lt_dhfile );
  102. + LDAP_FREE( lts.lt_ecname );
  103. #endif
  104. return rc;
  105. }
  106. @@ -646,6 +655,10 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
  107. *(char **)arg = lo->ldo_tls_dhfile ?
  108. LDAP_STRDUP( lo->ldo_tls_dhfile ) : NULL;
  109. break;
  110. + case LDAP_OPT_X_TLS_ECNAME:
  111. + *(char **)arg = lo->ldo_tls_ecname ?
  112. + LDAP_STRDUP( lo->ldo_tls_ecname ) : NULL;
  113. + break;
  114. case LDAP_OPT_X_TLS_CRLFILE: /* GnuTLS only */
  115. *(char **)arg = lo->ldo_tls_crlfile ?
  116. LDAP_STRDUP( lo->ldo_tls_crlfile ) : NULL;
  117. @@ -765,6 +778,10 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
  118. if ( lo->ldo_tls_dhfile ) LDAP_FREE( lo->ldo_tls_dhfile );
  119. lo->ldo_tls_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
  120. return 0;
  121. + case LDAP_OPT_X_TLS_ECNAME:
  122. + if ( lo->ldo_tls_ecname ) LDAP_FREE( lo->ldo_tls_ecname );
  123. + lo->ldo_tls_ecname = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
  124. + return 0;
  125. case LDAP_OPT_X_TLS_CRLFILE: /* GnuTLS only */
  126. if ( lo->ldo_tls_crlfile ) LDAP_FREE( lo->ldo_tls_crlfile );
  127. lo->ldo_tls_crlfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
  128. diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
  129. index f24060b7e..1370923af 100644
  130. --- a/libraries/libldap/tls_o.c
  131. +++ b/libraries/libldap/tls_o.c
  132. @@ -373,10 +373,9 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
  133. return -1;
  134. }
  135. - if ( lo->ldo_tls_dhfile ) {
  136. - DH *dh = NULL;
  137. + if ( is_server && lo->ldo_tls_dhfile ) {
  138. + DH *dh;
  139. BIO *bio;
  140. - SSL_CTX_set_options( ctx, SSL_OP_SINGLE_DH_USE );
  141. if (( bio=BIO_new_file( lt->lt_dhfile,"r" )) == NULL ) {
  142. Debug( LDAP_DEBUG_ANY,
  143. @@ -395,7 +394,35 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
  144. }
  145. BIO_free( bio );
  146. SSL_CTX_set_tmp_dh( ctx, dh );
  147. + SSL_CTX_set_options( ctx, SSL_OP_SINGLE_DH_USE );
  148. + DH_free( dh );
  149. + }
  150. +
  151. +#ifdef SSL_OP_SINGLE_ECDH_USE
  152. + if ( is_server && lo->ldo_tls_ecname ) {
  153. + EC_KEY *ecdh;
  154. +
  155. + int nid = OBJ_sn2nid( lt->lt_ecname );
  156. + if ( nid == NID_undef ) {
  157. + Debug( LDAP_DEBUG_ANY,
  158. + "TLS: could not use EC name `%s'.\n",
  159. + lo->ldo_tls_ecname,0,0);
  160. + tlso_report_error();
  161. + return -1;
  162. + }
  163. + ecdh = EC_KEY_new_by_curve_name( nid );
  164. + if ( ecdh == NULL ) {
  165. + Debug( LDAP_DEBUG_ANY,
  166. + "TLS: could not generate key for EC name `%s'.\n",
  167. + lo->ldo_tls_ecname,0,0);
  168. + tlso_report_error();
  169. + return -1;
  170. + }
  171. + SSL_CTX_set_tmp_ecdh( ctx, ecdh );
  172. + SSL_CTX_set_options( ctx, SSL_OP_SINGLE_ECDH_USE );
  173. + EC_KEY_free( ecdh );
  174. }
  175. +#endif
  176. if ( tlso_opt_trace ) {
  177. SSL_CTX_set_info_callback( ctx, tlso_info_cb );
  178. diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c
  179. index 250f14100..8b1e4e582 100644
  180. --- a/servers/slapd/bconfig.c
  181. +++ b/servers/slapd/bconfig.c
  182. @@ -194,6 +194,7 @@ enum {
  183. CFG_ACL_ADD,
  184. CFG_SYNC_SUBENTRY,
  185. CFG_LTHREADS,
  186. + CFG_TLS_ECNAME,
  187. CFG_LAST
  188. };
  189. @@ -738,6 +739,14 @@ static ConfigTable config_back_cf_table[] = {
  190. #endif
  191. "( OLcfgGlAt:77 NAME 'olcTLSDHParamFile' "
  192. "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
  193. + { "TLSECName", NULL, 2, 2, 0,
  194. +#ifdef HAVE_TLS
  195. + CFG_TLS_ECNAME|ARG_STRING|ARG_MAGIC, &config_tls_option,
  196. +#else
  197. + ARG_IGNORED, NULL,
  198. +#endif
  199. + "( OLcfgGlAt:96 NAME 'olcTLSECName' "
  200. + "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
  201. { "TLSProtocolMin", NULL, 2, 2, 0,
  202. #ifdef HAVE_TLS
  203. CFG_TLS_PROTOCOL_MIN|ARG_STRING|ARG_MAGIC, &config_tls_config,
  204. @@ -819,7 +828,7 @@ static ConfigOCs cf_ocs[] = {
  205. "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
  206. "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
  207. "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
  208. - "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
  209. + "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSECName $ "
  210. "olcTLSCRLFile $ olcTLSProtocolMin $ olcToolThreads $ olcWriteTimeout $ "
  211. "olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
  212. "olcDitContentRules $ olcLdapSyntaxes ) )", Cft_Global },
  213. @@ -3824,6 +3833,7 @@ config_tls_option(ConfigArgs *c) {
  214. case CFG_TLS_CA_PATH: flag = LDAP_OPT_X_TLS_CACERTDIR; break;
  215. case CFG_TLS_CA_FILE: flag = LDAP_OPT_X_TLS_CACERTFILE; break;
  216. case CFG_TLS_DH_FILE: flag = LDAP_OPT_X_TLS_DHFILE; break;
  217. + case CFG_TLS_ECNAME: flag = LDAP_OPT_X_TLS_ECNAME; break;
  218. #ifdef HAVE_GNUTLS
  219. case CFG_TLS_CRL_FILE: flag = LDAP_OPT_X_TLS_CRLFILE; break;
  220. #endif