diff -up openssl-1.0.1k/apps/s_apps.h.ephemeral openssl-1.0.1k/apps/s_apps.h --- openssl-1.0.1k/apps/s_apps.h.ephemeral 2015-01-09 10:22:03.289896211 +0100 +++ openssl-1.0.1k/apps/s_apps.h 2015-01-09 10:22:03.373898111 +0100 @@ -156,6 +156,7 @@ int MS_CALLBACK verify_callback(int ok, int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key); #endif +int ssl_print_tmp_key(BIO *out, SSL *s); int init_client(int *sock, char *server, char *port, int type); int should_retry(int i); int extract_host_port(char *str,char **host_ptr,char **port_ptr); diff -up openssl-1.0.1k/apps/s_cb.c.ephemeral openssl-1.0.1k/apps/s_cb.c --- openssl-1.0.1k/apps/s_cb.c.ephemeral 2015-01-08 15:00:36.000000000 +0100 +++ openssl-1.0.1k/apps/s_cb.c 2015-01-09 10:22:03.373898111 +0100 @@ -338,6 +338,38 @@ void MS_CALLBACK apps_ssl_info_callback( } } +int ssl_print_tmp_key(BIO *out, SSL *s) + { + EVP_PKEY *key; + if (!SSL_get_server_tmp_key(s, &key)) + return 1; + BIO_puts(out, "Server Temp Key: "); + switch (EVP_PKEY_id(key)) + { + case EVP_PKEY_RSA: + BIO_printf(out, "RSA, %d bits\n", EVP_PKEY_bits(key)); + break; + + case EVP_PKEY_DH: + BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(key)); + break; + + case EVP_PKEY_EC: + { + EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); + int nid; + const char *cname; + nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + EC_KEY_free(ec); + cname = OBJ_nid2sn(nid); + BIO_printf(out, "ECDH, %s, %d bits\n", + cname, EVP_PKEY_bits(key)); + } + } + EVP_PKEY_free(key); + return 1; + } + void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) { diff -up openssl-1.0.1k/apps/s_client.c.ephemeral openssl-1.0.1k/apps/s_client.c --- openssl-1.0.1k/apps/s_client.c.ephemeral 2015-01-09 10:22:03.367897975 +0100 +++ openssl-1.0.1k/apps/s_client.c 2015-01-09 10:22:03.373898111 +0100 @@ -2058,6 +2058,8 @@ static void print_stuff(BIO *bio, SSL *s BIO_write(bio,"\n",1); } + ssl_print_tmp_key(bio, s); + BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n", BIO_number_read(SSL_get_rbio(s)), BIO_number_written(SSL_get_wbio(s))); diff -up openssl-1.0.1k/ssl/ssl.h.ephemeral openssl-1.0.1k/ssl/ssl.h --- openssl-1.0.1k/ssl/ssl.h.ephemeral 2015-01-09 10:22:03.358897772 +0100 +++ openssl-1.0.1k/ssl/ssl.h 2015-01-09 10:25:08.644088146 +0100 @@ -1593,6 +1593,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_GET_SERVER_TMP_KEY 109 #define SSL_CTRL_CHECK_PROTO_VERSION 119 #define DTLS_CTRL_SET_LINK_MTU 120 #define DTLS_CTRL_GET_LINK_MIN_MTU 121 @@ -1638,6 +1639,9 @@ 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_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); diff -up openssl-1.0.1k/ssl/s3_lib.c.ephemeral openssl-1.0.1k/ssl/s3_lib.c --- openssl-1.0.1k/ssl/s3_lib.c.ephemeral 2015-01-08 15:00:56.000000000 +0100 +++ openssl-1.0.1k/ssl/s3_lib.c 2015-01-09 10:22:03.374898133 +0100 @@ -3356,6 +3356,45 @@ long ssl3_ctrl(SSL *s, int cmd, long lar #endif /* !OPENSSL_NO_TLSEXT */ + case SSL_CTRL_GET_SERVER_TMP_KEY: + if (s->server || !s->session || !s->session->sess_cert) + return 0; + else + { + SESS_CERT *sc; + EVP_PKEY *ptmp; + int rv = 0; + sc = s->session->sess_cert; +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC) + if (!sc->peer_rsa_tmp && !sc->peer_dh_tmp + && !sc->peer_ecdh_tmp) + return 0; +#endif + ptmp = EVP_PKEY_new(); + if (!ptmp) + return 0; + if (0); +#ifndef OPENSSL_NO_RSA + else if (sc->peer_rsa_tmp) + rv = EVP_PKEY_set1_RSA(ptmp, sc->peer_rsa_tmp); +#endif +#ifndef OPENSSL_NO_DH + else if (sc->peer_dh_tmp) + rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp); +#endif +#ifndef OPENSSL_NO_ECDH + else if (sc->peer_ecdh_tmp) + rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp); +#endif + if (rv) + { + *(EVP_PKEY **)parg = ptmp; + return 1; + } + EVP_PKEY_free(ptmp); + return 0; + } + case SSL_CTRL_CHECK_PROTO_VERSION: /* For library-internal use; checks that the current protocol * is the highest enabled version (according to s->ctx->method,