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.
248 lines
7.8 KiB
248 lines
7.8 KiB
diff -up openssl-1.0.1e/apps/s_server.c.ecdh-auto openssl-1.0.1e/apps/s_server.c |
|
--- openssl-1.0.1e/apps/s_server.c.ecdh-auto 2014-09-17 15:52:01.659445244 +0200 |
|
+++ openssl-1.0.1e/apps/s_server.c 2014-09-17 16:24:44.378754502 +0200 |
|
@@ -1708,7 +1708,7 @@ bad: |
|
{ |
|
EC_KEY *ecdh=NULL; |
|
|
|
- if (named_curve) |
|
+ if (named_curve && strcmp(named_curve, "auto")) |
|
{ |
|
int nid = OBJ_sn2nid(named_curve); |
|
|
|
@@ -1731,6 +1731,8 @@ bad: |
|
{ |
|
BIO_printf(bio_s_out,"Setting temp ECDH parameters\n"); |
|
} |
|
+ else if (named_curve) |
|
+ SSL_CTX_set_ecdh_auto(ctx, 1); |
|
else |
|
{ |
|
BIO_printf(bio_s_out,"Using default temp ECDH parameters\n"); |
|
diff -up openssl-1.0.1e/ssl/ssl_cert.c.ecdh-auto openssl-1.0.1e/ssl/ssl_cert.c |
|
--- openssl-1.0.1e/ssl/ssl_cert.c.ecdh-auto 2013-02-11 16:26:04.000000000 +0100 |
|
+++ openssl-1.0.1e/ssl/ssl_cert.c 2014-09-17 16:20:24.355884360 +0200 |
|
@@ -270,6 +270,7 @@ CERT *ssl_cert_dup(CERT *cert) |
|
} |
|
} |
|
ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; |
|
+ ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; |
|
#endif |
|
|
|
for (i = 0; i < SSL_PKEY_NUM; i++) |
|
diff -up openssl-1.0.1e/ssl/ssl.h.ecdh-auto openssl-1.0.1e/ssl/ssl.h |
|
--- openssl-1.0.1e/ssl/ssl.h.ecdh-auto 2014-09-17 16:20:24.354884336 +0200 |
|
+++ openssl-1.0.1e/ssl/ssl.h 2014-09-17 16:49:29.135273514 +0200 |
|
@@ -1563,6 +1563,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) |
|
#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 |
|
#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 |
|
|
|
+#define SSL_CTRL_SET_ECDH_AUTO 94 |
|
#define SSL_CTRL_GET_SERVER_TMP_KEY 109 |
|
|
|
#define DTLSv1_get_timeout(ssl, arg) \ |
|
@@ -1606,6 +1607,11 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) |
|
#define SSL_CTX_clear_extra_chain_certs(ctx) \ |
|
SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) |
|
|
|
+#define SSL_CTX_set_ecdh_auto(ctx, onoff) \ |
|
+ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) |
|
+#define SSL_set_ecdh_auto(s, onoff) \ |
|
+ SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) |
|
+ |
|
#define SSL_get_server_tmp_key(s, pk) \ |
|
SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk) |
|
|
|
diff -up openssl-1.0.1e/ssl/ssl_lib.c.ecdh-auto openssl-1.0.1e/ssl/ssl_lib.c |
|
--- openssl-1.0.1e/ssl/ssl_lib.c.ecdh-auto 2014-09-17 15:52:01.616444274 +0200 |
|
+++ openssl-1.0.1e/ssl/ssl_lib.c 2014-09-17 16:20:24.356884383 +0200 |
|
@@ -2045,7 +2045,7 @@ void ssl_set_cert_masks(CERT *c, const S |
|
#endif |
|
|
|
#ifndef OPENSSL_NO_ECDH |
|
- have_ecdh_tmp=(c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL); |
|
+ have_ecdh_tmp=(c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto); |
|
#endif |
|
cpk= &(c->pkeys[SSL_PKEY_RSA_ENC]); |
|
rsa_enc= (cpk->x509 != NULL && cpk->privatekey != NULL); |
|
diff -up openssl-1.0.1e/ssl/ssl_locl.h.ecdh-auto openssl-1.0.1e/ssl/ssl_locl.h |
|
--- openssl-1.0.1e/ssl/ssl_locl.h.ecdh-auto 2014-09-17 15:52:01.632444635 +0200 |
|
+++ openssl-1.0.1e/ssl/ssl_locl.h 2014-09-17 17:26:29.764405189 +0200 |
|
@@ -511,6 +511,8 @@ typedef struct cert_st |
|
EC_KEY *ecdh_tmp; |
|
/* Callback for generating ephemeral ECDH keys */ |
|
EC_KEY *(*ecdh_tmp_cb)(SSL *ssl,int is_export,int keysize); |
|
+ /* Select ECDH parameters automatically */ |
|
+ int ecdh_tmp_auto; |
|
#endif |
|
|
|
CERT_PKEY pkeys[SSL_PKEY_NUM]; |
|
@@ -1091,6 +1093,7 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_CO |
|
#ifndef OPENSSL_NO_EC |
|
int tls1_ec_curve_id2nid(int curve_id); |
|
int tls1_ec_nid2curve_id(int nid); |
|
+int tls1_shared_curve(SSL *s, int nmatch); |
|
#endif /* OPENSSL_NO_EC */ |
|
|
|
#ifndef OPENSSL_NO_TLSEXT |
|
diff -up openssl-1.0.1e/ssl/s3_lib.c.ecdh-auto openssl-1.0.1e/ssl/s3_lib.c |
|
--- openssl-1.0.1e/ssl/s3_lib.c.ecdh-auto 2014-09-17 16:20:24.352884288 +0200 |
|
+++ openssl-1.0.1e/ssl/s3_lib.c 2014-09-17 17:37:26.274226185 +0200 |
|
@@ -3350,6 +3350,12 @@ long ssl3_ctrl(SSL *s, int cmd, long lar |
|
#endif |
|
|
|
#endif /* !OPENSSL_NO_TLSEXT */ |
|
+ |
|
+#ifndef OPENSSL_NO_EC |
|
+ case SSL_CTRL_SET_ECDH_AUTO: |
|
+ s->cert->ecdh_tmp_auto = larg; |
|
+ return 1; |
|
+#endif |
|
case SSL_CTRL_GET_SERVER_TMP_KEY: |
|
if (s->server || !s->session || !s->session->sess_cert) |
|
return 0; |
|
@@ -3651,6 +3657,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd |
|
ctx->srp_ctx.strength=larg; |
|
break; |
|
#endif |
|
+ |
|
+#ifndef OPENSSL_NO_EC |
|
+ case SSL_CTRL_SET_ECDH_AUTO: |
|
+ ctx->cert->ecdh_tmp_auto = larg; |
|
+ return 1; |
|
+#endif |
|
#endif /* !OPENSSL_NO_TLSEXT */ |
|
|
|
/* A Thawte special :-) */ |
|
@@ -4003,6 +4015,14 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, S |
|
if ( |
|
/* if we are considering an ECC cipher suite that uses an ephemeral EC key */ |
|
(alg_k & SSL_kEECDH) |
|
+ && (s->cert->ecdh_tmp_auto) |
|
+ ) |
|
+ { |
|
+ ok = ok && tls1_shared_curve(s, 0); |
|
+ } |
|
+ else if ( |
|
+ /* if we are considering an ECC cipher suite that uses an ephemeral EC key */ |
|
+ (alg_k & SSL_kEECDH) |
|
/* and we have an ephemeral EC key */ |
|
&& (s->cert->ecdh_tmp != NULL) |
|
/* and the client specified an EllipticCurves extension */ |
|
diff -up openssl-1.0.1e/ssl/s3_srvr.c.ecdh-auto openssl-1.0.1e/ssl/s3_srvr.c |
|
--- openssl-1.0.1e/ssl/s3_srvr.c.ecdh-auto 2014-09-17 15:52:01.644444906 +0200 |
|
+++ openssl-1.0.1e/ssl/s3_srvr.c 2014-09-17 16:20:24.353884312 +0200 |
|
@@ -1693,7 +1693,14 @@ int ssl3_send_server_key_exchange(SSL *s |
|
const EC_GROUP *group; |
|
|
|
ecdhp=cert->ecdh_tmp; |
|
- if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) |
|
+ if (s->cert->ecdh_tmp_auto) |
|
+ { |
|
+ /* Get NID of first shared curve */ |
|
+ int nid = tls1_shared_curve(s, 0); |
|
+ if (nid != NID_undef) |
|
+ ecdhp = EC_KEY_new_by_curve_name(nid); |
|
+ } |
|
+ else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) |
|
{ |
|
ecdhp=s->cert->ecdh_tmp_cb(s, |
|
SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), |
|
@@ -1718,7 +1725,9 @@ int ssl3_send_server_key_exchange(SSL *s |
|
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); |
|
goto err; |
|
} |
|
- if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) |
|
+ if (s->cert->ecdh_tmp_auto) |
|
+ ecdh = ecdhp; |
|
+ else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) |
|
{ |
|
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); |
|
goto err; |
|
diff -up openssl-1.0.1e/ssl/t1_lib.c.ecdh-auto openssl-1.0.1e/ssl/t1_lib.c |
|
--- openssl-1.0.1e/ssl/t1_lib.c.ecdh-auto 2014-09-17 16:20:24.358884427 +0200 |
|
+++ openssl-1.0.1e/ssl/t1_lib.c 2014-09-17 17:32:04.054951942 +0200 |
|
@@ -202,6 +202,13 @@ static int nid_list[] = |
|
NID_secp521r1 /* secp521r1 (25) */ |
|
}; |
|
|
|
+static const unsigned char eccurves_default[] = |
|
+ { |
|
+ 0,23, /* secp256r1 (23) */ |
|
+ 0,24, /* secp384r1 (24) */ |
|
+ 0,25, /* secp521r1 (25) */ |
|
+ }; |
|
+ |
|
static int pref_list[] = |
|
{ |
|
NID_secp521r1, /* secp521r1 (25) */ |
|
@@ -277,6 +284,69 @@ int tls1_ec_nid2curve_id(int nid) |
|
return 0; |
|
} |
|
} |
|
+/* Get curves list, if "sess" is set return client curves otherwise |
|
+ * preferred list |
|
+ */ |
|
+static void tls1_get_curvelist(SSL *s, int sess, |
|
+ const unsigned char **pcurves, |
|
+ size_t *pcurveslen) |
|
+ { |
|
+ if (sess) |
|
+ { |
|
+ *pcurves = s->session->tlsext_ellipticcurvelist; |
|
+ *pcurveslen = s->session->tlsext_ellipticcurvelist_length; |
|
+ } |
|
+ else |
|
+ { |
|
+ *pcurves = s->tlsext_ellipticcurvelist; |
|
+ *pcurveslen = s->tlsext_ellipticcurvelist_length; |
|
+ } |
|
+ if (!*pcurves) |
|
+ { |
|
+ *pcurves = eccurves_default; |
|
+ *pcurveslen = sizeof(eccurves_default); |
|
+ } |
|
+ } |
|
+/* Return nth shared curve. If nmatch == -1 return number of |
|
+ * matches. |
|
+ */ |
|
+ |
|
+int tls1_shared_curve(SSL *s, int nmatch) |
|
+ { |
|
+ const unsigned char *pref, *supp; |
|
+ size_t preflen, supplen, i, j; |
|
+ int k; |
|
+ /* Can't do anything on client side */ |
|
+ if (s->server == 0) |
|
+ return -1; |
|
+ tls1_get_curvelist(s, !!(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), |
|
+ &supp, &supplen); |
|
+ tls1_get_curvelist(s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), |
|
+ &pref, &preflen); |
|
+ preflen /= 2; |
|
+ supplen /= 2; |
|
+ k = 0; |
|
+ for (i = 0; i < preflen; i++, pref+=2) |
|
+ { |
|
+ const unsigned char *tsupp = supp; |
|
+ for (j = 0; j < supplen; j++, tsupp+=2) |
|
+ { |
|
+ if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) |
|
+ { |
|
+ if (nmatch == k) |
|
+ { |
|
+ int id = (pref[0] << 8) | pref[1]; |
|
+ return tls1_ec_curve_id2nid(id); |
|
+ } |
|
+ k++; |
|
+ } |
|
+ } |
|
+ } |
|
+ if (nmatch == -1) |
|
+ return k; |
|
+ return 0; |
|
+ } |
|
+ |
|
#endif /* OPENSSL_NO_EC */ |
|
|
|
#ifndef OPENSSL_NO_TLSEXT
|
|
|