summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2014-10-03 13:58:19 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2014-10-03 13:58:19 +0000
commitb9a87bb6890852e78fbfda2d3561b11194e0db8e (patch)
treeac83e1a191a91403af20b5a78ad6e443d6b730d4
parent64ec975e1e324d7dcbf99caef225607f20a95702 (diff)
Add support for automatic ephemeral EC keys.
This allows an SSL server to enable ECDHE ciphers with a single setting, which results in an EC key being generated using the first preference shared curve. Based on OpenSSL with inspiration from boringssl. ok miod@
-rw-r--r--lib/libssl/src/ssl/s3_lib.c10
-rw-r--r--lib/libssl/src/ssl/s3_srvr.c14
-rw-r--r--lib/libssl/src/ssl/ssl.h8
-rw-r--r--lib/libssl/src/ssl/ssl_cert.c3
-rw-r--r--lib/libssl/src/ssl/ssl_lib.c5
-rw-r--r--lib/libssl/src/ssl/ssl_locl.h8
-rw-r--r--lib/libssl/src/ssl/t1_lib.c41
7 files changed, 76 insertions, 13 deletions
diff --git a/lib/libssl/src/ssl/s3_lib.c b/lib/libssl/src/ssl/s3_lib.c
index 246aa6f23df..42f8074f8c3 100644
--- a/lib/libssl/src/ssl/s3_lib.c
+++ b/lib/libssl/src/ssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.81 2014/09/30 15:40:09 jsing Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.82 2014/10/03 13:58:17 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -2128,6 +2128,11 @@ ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
ret = 1;
break;
+ case SSL_CTRL_SET_ECDH_AUTO:
+ s->cert->ecdh_tmp_auto = larg;
+ ret = 1;
+ break;
+
default:
break;
}
@@ -2322,6 +2327,9 @@ ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
return 1;
break;
+ case SSL_CTRL_SET_ECDH_AUTO:
+ ctx->cert->ecdh_tmp_auto = larg;
+ return 1;
/* A Thawte special :-) */
case SSL_CTRL_EXTRA_CHAIN_CERT:
diff --git a/lib/libssl/src/ssl/s3_srvr.c b/lib/libssl/src/ssl/s3_srvr.c
index cba875a3e69..c4a8442a3e0 100644
--- a/lib/libssl/src/ssl/s3_srvr.c
+++ b/lib/libssl/src/ssl/s3_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_srvr.c,v 1.85 2014/09/27 11:03:43 jsing Exp $ */
+/* $OpenBSD: s3_srvr.c,v 1.86 2014/10/03 13:58:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1465,9 +1465,15 @@ 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 != 0) {
+ int nid = tls1_get_shared_curve(s);
+ if (nid != NID_undef)
+ ecdhp = EC_KEY_new_by_curve_name(nid);
+ } else if (ecdhp == NULL &&
+ s->cert->ecdh_tmp_cb != NULL) {
ecdhp = s->cert->ecdh_tmp_cb(s, 0,
SSL_C_PKEYLENGTH(s->s3->tmp.new_cipher));
+ }
if (ecdhp == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
@@ -1482,7 +1488,9 @@ ssl3_send_server_key_exchange(SSL *s)
}
/* Duplicate the ECDH structure. */
- if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) {
+ if (s->cert->ecdh_tmp_auto != 0) {
+ 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 --git a/lib/libssl/src/ssl/ssl.h b/lib/libssl/src/ssl/ssl.h
index c7dd4259ccb..1e9e8461955 100644
--- a/lib/libssl/src/ssl/ssl.h
+++ b/lib/libssl/src/ssl/ssl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.h,v 1.66 2014/09/28 14:45:48 reyk Exp $ */
+/* $OpenBSD: ssl.h,v 1.67 2014/10/03 13:58:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1425,6 +1425,8 @@ 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 DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
#define DTLSv1_handle_timeout(ssl) \
@@ -1449,6 +1451,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+#define SSL_CTX_set_ecdh_auto(ctx, onoff) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL)
#define SSL_need_tmp_RSA(ssl) \
SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL)
@@ -1458,6 +1462,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
#define SSL_set_tmp_ecdh(ssl,ecdh) \
SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+#define SSL_set_ecdh_auto(s, onoff) \
+ SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL)
#define SSL_CTX_add_extra_chain_cert(ctx,x509) \
SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
diff --git a/lib/libssl/src/ssl/ssl_cert.c b/lib/libssl/src/ssl/ssl_cert.c
index 6aae59e3106..6f1815067b9 100644
--- a/lib/libssl/src/ssl/ssl_cert.c
+++ b/lib/libssl/src/ssl/ssl_cert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_cert.c,v 1.41 2014/07/10 08:25:00 guenther Exp $ */
+/* $OpenBSD: ssl_cert.c,v 1.42 2014/10/03 13:58:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -244,6 +244,7 @@ ssl_cert_dup(CERT *cert)
}
}
ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
+ ret->ecdh_tmp_auto = cert->ecdh_tmp_auto;
for (i = 0; i < SSL_PKEY_NUM; i++) {
if (cert->pkeys[i].x509 != NULL) {
diff --git a/lib/libssl/src/ssl/ssl_lib.c b/lib/libssl/src/ssl/ssl_lib.c
index bd5f9f6da14..f6a21d43514 100644
--- a/lib/libssl/src/ssl/ssl_lib.c
+++ b/lib/libssl/src/ssl/ssl_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_lib.c,v 1.84 2014/09/07 12:16:23 jsing Exp $ */
+/* $OpenBSD: ssl_lib.c,v 1.85 2014/10/03 13:58:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1943,7 +1943,8 @@ ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
rsa_tmp = (c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
- have_ecdh_tmp = (c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL);
+ have_ecdh_tmp = (c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL ||
+ c->ecdh_tmp_auto != 0);
cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]);
rsa_enc = (cpk->x509 != NULL && cpk->privatekey != NULL);
cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]);
diff --git a/lib/libssl/src/ssl/ssl_locl.h b/lib/libssl/src/ssl/ssl_locl.h
index 8ec4c69d5be..976f835c923 100644
--- a/lib/libssl/src/ssl/ssl_locl.h
+++ b/lib/libssl/src/ssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.70 2014/09/30 15:40:09 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.71 2014/10/03 13:58:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -439,13 +439,16 @@ typedef struct cert_st {
int valid;
unsigned long mask_k;
unsigned long mask_a;
+
RSA *rsa_tmp;
RSA *(*rsa_tmp_cb)(SSL *ssl, int is_export, int keysize);
+
DH *dh_tmp;
DH *(*dh_tmp_cb)(SSL *ssl, int is_export, int keysize);
+
EC_KEY *ecdh_tmp;
- /* Callback for generating ephemeral ECDH keys */
EC_KEY *(*ecdh_tmp_cb)(SSL *ssl, int is_export, int keysize);
+ int ecdh_tmp_auto;
CERT_PKEY pkeys[SSL_PKEY_NUM];
@@ -799,6 +802,7 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
int tls1_ec_curve_id2nid(int curve_id);
int tls1_ec_nid2curve_id(int nid);
int tls1_check_curve(SSL *s, const unsigned char *p, size_t len);
+int tls1_get_shared_curve(SSL *s);
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p,
unsigned char *limit);
diff --git a/lib/libssl/src/ssl/t1_lib.c b/lib/libssl/src/ssl/t1_lib.c
index d40768560cb..678818d51b2 100644
--- a/lib/libssl/src/ssl/t1_lib.c
+++ b/lib/libssl/src/ssl/t1_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t1_lib.c,v 1.59 2014/09/30 15:40:09 jsing Exp $ */
+/* $OpenBSD: t1_lib.c,v 1.60 2014/10/03 13:58:18 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -408,6 +408,35 @@ tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
return (0);
}
+int
+tls1_get_shared_curve(SSL *s)
+{
+ const unsigned char *pref, *supp, *tsupp;
+ size_t preflen, supplen, i, j;
+ unsigned long server_pref;
+ int id;
+
+ /* Cannot do anything on the client side. */
+ if (s->server == 0)
+ return (NID_undef);
+
+ /* Return first preference shared curve. */
+ server_pref = (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE);
+ tls1_get_curvelist(s, (server_pref == 0), &pref, &preflen);
+ tls1_get_curvelist(s, (server_pref != 0), &supp, &supplen);
+
+ for (i = 0; i < preflen; i += 2, pref += 2) {
+ tsupp = supp;
+ for (j = 0; j < supplen; j += 2, tsupp += 2) {
+ if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) {
+ id = (pref[0] << 8) | pref[1];
+ return (tls1_ec_curve_id2nid(id));
+ }
+ }
+ }
+ return (NID_undef);
+}
+
/* For an EC key set TLS ID and required compression based on parameters. */
static int
tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec)
@@ -524,11 +553,17 @@ tls1_check_ec_tmp_key(SSL *s)
EC_KEY *ec = s->cert->ecdh_tmp;
unsigned char curve_id[2];
+ if (s->cert->ecdh_tmp_auto != 0) {
+ /* Need a shared curve. */
+ if (tls1_get_shared_curve(s) != NID_undef)
+ return (1);
+ return (0);
+ }
+
if (ec == NULL) {
if (s->cert->ecdh_tmp_cb != NULL)
return (1);
- else
- return (0);
+ return (0);
}
if (tls1_set_ec_id(curve_id, NULL, ec) != 1)
return (0);