From c6852449efeadbfc5a05c733da7136ce72a68a35 Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 30 Dec 2016 17:20:51 +0000
Subject: Add support for SSL_get_server_tmp_key().

ok doug@
---
 src/lib/libssl/s3_lib.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/lib/libssl/ssl.h    |  9 +++++--
 2 files changed, 74 insertions(+), 3 deletions(-)

(limited to 'src')

diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index 212de5f7a4..5c7f2cb27c 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.114 2016/12/21 16:44:31 jsing Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.115 2016/12/30 17:20:51 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -151,6 +151,7 @@
 #include <limits.h>
 #include <stdio.h>
 
+#include <openssl/bn.h>
 #include <openssl/curve25519.h>
 #include <openssl/dh.h>
 #include <openssl/md5.h>
@@ -1904,6 +1905,67 @@ ssl3_clear(SSL *s)
 	s->next_proto_negotiated_len = 0;
 }
 
+static long
+ssl_ctrl_get_server_tmp_key(SSL *s, EVP_PKEY **pkey_tmp)
+{
+	EVP_PKEY *pkey = NULL;
+	EC_GROUP *group = NULL;
+	EC_POINT *point = NULL;
+	EC_KEY *ec_key = NULL;
+	BIGNUM *order = NULL;
+	SESS_CERT *sc;
+	int ret = 0;
+
+	*pkey_tmp = NULL;
+
+	if (s->server != 0)
+		return 0;
+	if (s->session == NULL || s->session->sess_cert == NULL)
+		return 0;
+
+	sc = s->session->sess_cert;
+
+	if ((pkey = EVP_PKEY_new()) == NULL)
+		return 0;
+
+	if (sc->peer_dh_tmp != NULL) {
+		ret = EVP_PKEY_set1_DH(pkey, sc->peer_dh_tmp);
+	} else if (sc->peer_ecdh_tmp) {
+		ret = EVP_PKEY_set1_EC_KEY(pkey, sc->peer_ecdh_tmp);
+	} else if (sc->peer_x25519_tmp != NULL) {
+		/* Fudge up an EC_KEY that looks like X25519... */
+		if ((group = EC_GROUP_new(EC_GFp_mont_method())) == NULL)
+			goto err;
+		if ((point = EC_POINT_new(group)) == NULL)
+			goto err;
+		if ((order = BN_new()) == NULL)
+			goto err;
+		if (!BN_set_bit(order, 252))
+			goto err;
+		if (!EC_GROUP_set_generator(group, point, order, NULL))
+			goto err;
+		EC_GROUP_set_curve_name(group, NID_X25519);
+		if ((ec_key = EC_KEY_new()) == NULL)
+			goto err;
+		if (!EC_KEY_set_group(ec_key, group))
+			goto err;
+		ret = EVP_PKEY_set1_EC_KEY(pkey, ec_key);
+	}
+
+	if (ret == 1) {
+		*pkey_tmp = pkey;
+		pkey = NULL;
+	}
+
+  err:
+	EVP_PKEY_free(pkey);
+	EC_GROUP_free(group);
+	EC_POINT_free(point);
+	EC_KEY_free(ec_key);
+	BN_free(order);
+
+	return (ret);
+}
 
 long
 ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
@@ -2077,6 +2139,10 @@ ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 		ret = 1;
 		break;
 
+	case SSL_CTRL_GET_SERVER_TMP_KEY:
+		ret = ssl_ctrl_get_server_tmp_key(s, parg);
+		break;
+
 	default:
 		break;
 	}
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
index d8c25cac42..37844bdeaa 100644
--- a/src/lib/libssl/ssl.h
+++ b/src/lib/libssl/ssl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.h,v 1.101 2016/12/21 16:51:10 jsing Exp $ */
+/* $OpenBSD: ssl.h,v 1.102 2016/12/30 17:20:51 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -1469,7 +1469,9 @@ int PEM_write_SSL_SESSION(FILE *fp, SSL_SESSION *x);
 #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_SET_ECDH_AUTO			94
+
+#define SSL_CTRL_GET_SERVER_TMP_KEY		109
 
 #define SSL_CTRL_SET_DH_AUTO			118
 
@@ -1522,6 +1524,9 @@ int PEM_write_SSL_SESSION(FILE *fp, SSL_SESSION *x);
 #define SSL_CTX_clear_extra_chain_certs(ctx) \
 	SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL)
 
+#define SSL_get_server_tmp_key(s, pk) \
+	SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk)
+
 #ifndef OPENSSL_NO_BIO
 BIO_METHOD *BIO_f_ssl(void);
 BIO *BIO_new_ssl(SSL_CTX *ctx, int client);
-- 
cgit v1.2.3-55-g6feb