diff options
Diffstat (limited to 'patches/0011-ecdhe_psk.patch')
-rw-r--r-- | patches/0011-ecdhe_psk.patch | 1435 |
1 files changed, 0 insertions, 1435 deletions
diff --git a/patches/0011-ecdhe_psk.patch b/patches/0011-ecdhe_psk.patch deleted file mode 100644 index a3ab573107..0000000000 --- a/patches/0011-ecdhe_psk.patch +++ /dev/null @@ -1,1435 +0,0 @@ -From 1d43b892d27915843e5714d96de269672b5b35db Mon Sep 17 00:00:00 2001 -From: Adam Langley <agl@chromium.org> -Date: Thu, 14 Nov 2013 16:12:01 -0500 -Subject: Implement ECDHE-PSK-WITH-AES. - -Add support for TLS-ECDHE-PSK cipher suites: -* TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256, and -* TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384. ---- - ssl/s3_clnt.c | 360 ++++++++++++++++++++++---------------- - ssl/s3_enc.c | 2 +- - ssl/s3_lib.c | 38 +++++- - ssl/s3_srvr.c | 541 ++++++++++++++++++++++++++++++++-------------------------- - ssl/ssl_lib.c | 2 +- - ssl/tls1.h | 8 + - 6 files changed, 555 insertions(+), 396 deletions(-) - -diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c -index 8f3740f..3672cce 100644 ---- a/ssl/s3_clnt.c -+++ b/ssl/s3_clnt.c -@@ -333,9 +333,10 @@ int ssl3_connect(SSL *s) - } - #endif - /* Check if it is anon DH/ECDH, SRP auth */ -- /* or PSK */ -+ /* or non-RSA PSK */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) && -- !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) -+ !((s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK) && -+ !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kRSA))) - { - ret=ssl3_get_server_certificate(s); - if (ret <= 0) goto end; -@@ -1368,7 +1369,7 @@ int ssl3_get_key_exchange(SSL *s) - omitted if no identity hint is sent. Set - session->sess_cert anyway to avoid problems - later.*/ -- if (alg_k & SSL_kPSK) -+ if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK) - { - s->session->sess_cert=ssl_sess_cert_new(); - if (s->ctx->psk_identity_hint) -@@ -1416,61 +1417,65 @@ int ssl3_get_key_exchange(SSL *s) - EVP_MD_CTX_init(&md_ctx); - - #ifndef OPENSSL_NO_PSK -- if (alg_k & SSL_kPSK) -+ if (alg_a & SSL_aPSK) - { - char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1]; - - param_len = 2; - if (param_len > n) - { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p,i); - -- /* Store PSK identity hint for later use, hint is used -- * in ssl3_send_client_key_exchange. Assume that the -- * maximum length of a PSK identity hint can be as -- * long as the maximum length of a PSK identity. */ -- if (i > PSK_MAX_IDENTITY_LEN) -- { -- al=SSL_AD_HANDSHAKE_FAILURE; -- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, -- SSL_R_DATA_LENGTH_TOO_LONG); -- goto f_err; -- } -- if (i > n - param_len) -+ s->ctx->psk_identity_hint = NULL; -+ if (i != 0) - { -- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, -- SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); -- goto f_err; -+ /* Store PSK identity hint for later use, hint is used -+ * in ssl3_send_client_key_exchange. Assume that the -+ * maximum length of a PSK identity hint can be as -+ * long as the maximum length of a PSK identity. */ -+ if (i > PSK_MAX_IDENTITY_LEN) -+ { -+ al=SSL_AD_HANDSHAKE_FAILURE; -+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, -+ SSL_R_DATA_LENGTH_TOO_LONG); -+ goto f_err; -+ } -+ if (i > n - param_len) -+ { -+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, -+ SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); -+ goto f_err; -+ } -+ param_len += i; -+ -+ /* If received PSK identity hint contains NULL -+ * characters, the hint is truncated from the first -+ * NULL. p may not be ending with NULL, so create a -+ * NULL-terminated string. */ -+ memcpy(tmp_id_hint, p, i); -+ memset(tmp_id_hint+i, 0, PSK_MAX_IDENTITY_LEN+1-i); -+ if (s->ctx->psk_identity_hint != NULL) -+ OPENSSL_free(s->ctx->psk_identity_hint); -+ s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint); -+ if (s->ctx->psk_identity_hint == NULL) -+ { -+ al=SSL_AD_HANDSHAKE_FAILURE; -+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); -+ goto f_err; -+ } - } -- param_len += i; -- -- /* If received PSK identity hint contains NULL -- * characters, the hint is truncated from the first -- * NULL. p may not be ending with NULL, so create a -- * NULL-terminated string. */ -- memcpy(tmp_id_hint, p, i); -- memset(tmp_id_hint+i, 0, PSK_MAX_IDENTITY_LEN+1-i); -- if (s->ctx->psk_identity_hint != NULL) -- OPENSSL_free(s->ctx->psk_identity_hint); -- s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint); -- if (s->ctx->psk_identity_hint == NULL) -- { -- al=SSL_AD_HANDSHAKE_FAILURE; -- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); -- goto f_err; -- } -- - p+=i; - n-=param_len; - } -- else - #endif /* !OPENSSL_NO_PSK */ -+ -+ if (0) {} - #ifndef OPENSSL_NO_SRP -- if (alg_k & SSL_kSRP) -+ else if (alg_k & SSL_kSRP) - { - n2s(p,i); - param_len=i+2; -@@ -1538,10 +1543,9 @@ int ssl3_get_key_exchange(SSL *s) - pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509); - #endif - } -- else - #endif /* !OPENSSL_NO_SRP */ - #ifndef OPENSSL_NO_RSA -- if (alg_k & SSL_kRSA) -+ else if (alg_k & SSL_kRSA) - { - if ((rsa=RSA_new()) == NULL) - { -@@ -1590,9 +1594,6 @@ int ssl3_get_key_exchange(SSL *s) - s->session->sess_cert->peer_rsa_tmp=rsa; - rsa=NULL; - } --#else /* OPENSSL_NO_RSA */ -- if (0) -- ; - #endif - #ifndef OPENSSL_NO_DH - else if (alg_k & SSL_kEDH) -@@ -1773,14 +1774,14 @@ int ssl3_get_key_exchange(SSL *s) - EC_POINT_free(srvr_ecpoint); - srvr_ecpoint = NULL; - } -- else if (alg_k) -+#endif /* !OPENSSL_NO_ECDH */ -+ -+ else if (!(alg_k & SSL_kPSK)) - { - al=SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } --#endif /* !OPENSSL_NO_ECDH */ -- - - /* p points to the next byte, there are 'n' bytes left */ - -@@ -1885,8 +1886,9 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); - } - else - { -- /* aNULL, aSRP or kPSK do not need public keys */ -- if (!(alg_a & (SSL_aNULL|SSL_aSRP)) && !(alg_k & SSL_kPSK)) -+ if (!(alg_a & (SSL_aNULL|SSL_aSRP)) && -+ /* Among PSK ciphers only RSA_PSK needs a public key */ -+ !((alg_a & SSL_aPSK) && !(alg_k & SSL_kRSA))) - { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); - goto err; -@@ -2286,8 +2288,9 @@ int ssl3_get_server_done(SSL *s) - int ssl3_send_client_key_exchange(SSL *s) - { - unsigned char *p,*d; -- int n; -+ int n = 0; - unsigned long alg_k; -+ unsigned long alg_a; - #ifndef OPENSSL_NO_RSA - unsigned char *q; - EVP_PKEY *pkey=NULL; -@@ -2302,7 +2305,11 @@ int ssl3_send_client_key_exchange(SSL *s) - unsigned char *encodedPoint = NULL; - int encoded_pt_len = 0; - BN_CTX * bn_ctx = NULL; --#endif -+#ifndef OPENSSL_NO_PSK -+ unsigned int psk_len = 0; -+ unsigned char psk[PSK_MAX_PSK_LEN]; -+#endif /* OPENSSL_NO_PSK */ -+#endif /* OPENSSL_NO_ECDH */ - - if (s->state == SSL3_ST_CW_KEY_EXCH_A) - { -@@ -2310,7 +2317,106 @@ int ssl3_send_client_key_exchange(SSL *s) - p= &(d[4]); - - alg_k=s->s3->tmp.new_cipher->algorithm_mkey; -+ alg_a=s->s3->tmp.new_cipher->algorithm_auth; -+ -+#ifndef OPENSSL_NO_PSK -+ if (alg_a & SSL_aPSK) -+ { -+ /* The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes -+ * to return a \0-terminated identity. The last byte -+ * is for us for simulating strnlen. */ -+ char identity[PSK_MAX_IDENTITY_LEN + 2]; -+ size_t identity_len; -+ unsigned char *t = NULL; -+ unsigned char pre_ms[PSK_MAX_PSK_LEN*2+4]; -+ unsigned int pre_ms_len = 0; -+ int psk_err = 1; -+ -+ n = 0; -+ if (s->psk_client_callback == NULL) -+ { -+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -+ SSL_R_PSK_NO_CLIENT_CB); -+ goto err; -+ } - -+ psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint, -+ identity, sizeof(identity) - 1, psk, sizeof(psk)); -+ if (psk_len > PSK_MAX_PSK_LEN) -+ { -+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -+ ERR_R_INTERNAL_ERROR); -+ goto psk_err; -+ } -+ else if (psk_len == 0) -+ { -+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -+ SSL_R_PSK_IDENTITY_NOT_FOUND); -+ goto psk_err; -+ } -+ identity[PSK_MAX_IDENTITY_LEN + 1] = '\0'; -+ identity_len = strlen(identity); -+ if (identity_len > PSK_MAX_IDENTITY_LEN) -+ { -+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -+ ERR_R_INTERNAL_ERROR); -+ goto psk_err; -+ } -+ if (!(alg_k & SSL_kEECDH)) -+ { -+ /* Create the shared secret now if we're not using ECDHE-PSK.*/ -+ pre_ms_len = 2+psk_len+2+psk_len; -+ t = pre_ms; -+ s2n(psk_len, t); -+ memset(t, 0, psk_len); -+ t+=psk_len; -+ s2n(psk_len, t); -+ memcpy(t, psk, psk_len); -+ -+ s->session->master_key_length = -+ s->method->ssl3_enc->generate_master_secret(s, -+ s->session->master_key, -+ pre_ms, pre_ms_len); -+ s2n(identity_len, p); -+ memcpy(p, identity, identity_len); -+ n = 2 + identity_len; -+ } -+ -+ if (s->session->psk_identity_hint != NULL) -+ OPENSSL_free(s->session->psk_identity_hint); -+ s->session->psk_identity_hint = NULL; -+ if (s->ctx->psk_identity_hint) -+ { -+ s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); -+ if (s->ctx->psk_identity_hint != NULL && -+ s->session->psk_identity_hint == NULL) -+ { -+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -+ ERR_R_MALLOC_FAILURE); -+ goto psk_err; -+ } -+ } -+ -+ if (s->session->psk_identity != NULL) -+ OPENSSL_free(s->session->psk_identity); -+ s->session->psk_identity = BUF_strdup(identity); -+ if (s->session->psk_identity == NULL) -+ { -+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -+ ERR_R_MALLOC_FAILURE); -+ goto psk_err; -+ } -+ psk_err = 0; -+ psk_err: -+ OPENSSL_cleanse(identity, sizeof(identity)); -+ OPENSSL_cleanse(pre_ms, sizeof(pre_ms)); -+ if (psk_err != 0) -+ { -+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); -+ goto err; -+ } -+ } -+#endif - /* Fool emacs indentation */ - if (0) {} - #ifndef OPENSSL_NO_RSA -@@ -2571,14 +2667,19 @@ int ssl3_send_client_key_exchange(SSL *s) - /* perhaps clean things up a bit EAY EAY EAY EAY*/ - } - #endif -- --#ifndef OPENSSL_NO_ECDH -+#ifndef OPENSSL_NO_ECDH - else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) - { - const EC_GROUP *srvr_group = NULL; - EC_KEY *tkey; - int ecdh_clnt_cert = 0; - int field_size = 0; -+#ifndef OPENSSL_NO_PSK -+ unsigned char *pre_ms; -+ unsigned char *t; -+ unsigned int pre_ms_len; -+ unsigned int i; -+#endif - - if (s->session->sess_cert == NULL) - { -@@ -2706,15 +2807,41 @@ int ssl3_send_client_key_exchange(SSL *s) - goto err; - } - -- /* generate master key from the result */ -- s->session->master_key_length = s->method->ssl3_enc \ -- -> generate_master_secret(s, -- s->session->master_key, -- p, n); -- -+#ifndef OPENSSL_NO_PSK -+ /* ECDHE PSK ciphersuites from RFC 5489 */ -+ if ((alg_a & SSL_aPSK) && psk_len != 0) -+ { -+ pre_ms_len = 2+n+2+psk_len; -+ pre_ms = OPENSSL_malloc(pre_ms_len); -+ if (pre_ms == NULL) -+ { -+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -+ ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ memset(pre_ms, 0, pre_ms_len); -+ t = pre_ms; -+ s2n(n, t); -+ memcpy(t, p, n); -+ t += n; -+ s2n(psk_len, t); -+ memcpy(t, psk, psk_len); -+ s->session->master_key_length = s->method->ssl3_enc \ -+ -> generate_master_secret(s, -+ s->session->master_key, pre_ms, pre_ms_len); -+ OPENSSL_cleanse(pre_ms, pre_ms_len); -+ OPENSSL_free(pre_ms); -+ } -+#endif /* OPENSSL_NO_PSK */ -+ if (!(alg_a & SSL_aPSK)) -+ { -+ /* generate master key from the result */ -+ s->session->master_key_length = s->method->ssl3_enc \ -+ -> generate_master_secret(s, -+ s->session->master_key, p, n); -+ } - memset(p, 0, n); /* clean up */ -- -- if (ecdh_clnt_cert) -+ if (ecdh_clnt_cert) - { - /* Send empty client key exch message */ - n = 0; -@@ -2742,29 +2869,42 @@ int ssl3_send_client_key_exchange(SSL *s) - } - - /* Encode the public key */ -- n = EC_POINT_point2oct(srvr_group, -- EC_KEY_get0_public_key(clnt_ecdh), -- POINT_CONVERSION_UNCOMPRESSED, -+ encoded_pt_len = EC_POINT_point2oct(srvr_group, -+ EC_KEY_get0_public_key(clnt_ecdh), -+ POINT_CONVERSION_UNCOMPRESSED, - encodedPoint, encoded_pt_len, bn_ctx); -+ -+ n = 0; -+#ifndef OPENSSL_NO_PSK -+ if ((alg_a & SSL_aPSK) && psk_len != 0) -+ { -+ i = strlen(s->session->psk_identity); -+ s2n(i, p); -+ memcpy(p, s->session->psk_identity, i); -+ p += i; -+ n = i + 2; -+ } -+#endif - -- *p = n; /* length of encoded point */ -+ *p = encoded_pt_len; /* length of encoded point */ - /* Encoded point will be copied here */ -- p += 1; -+ p += 1; -+ n += 1; - /* copy the point */ -- memcpy((unsigned char *)p, encodedPoint, n); -+ memcpy((unsigned char *)p, encodedPoint, encoded_pt_len); - /* increment n to account for length field */ -- n += 1; -+ n += encoded_pt_len; - } - - /* Free allocated memory */ - BN_CTX_free(bn_ctx); - if (encodedPoint != NULL) OPENSSL_free(encodedPoint); -- if (clnt_ecdh != NULL) -+ if (clnt_ecdh != NULL) - EC_KEY_free(clnt_ecdh); - EVP_PKEY_free(srvr_pub_pkey); - } - #endif /* !OPENSSL_NO_ECDH */ -- else if (alg_k & SSL_kGOST) -+ else if (alg_k & SSL_kGOST) - { - /* GOST key exchange message creation */ - EVP_PKEY_CTX *pkey_ctx; -@@ -2887,100 +3027,7 @@ int ssl3_send_client_key_exchange(SSL *s) - } - } - #endif --#ifndef OPENSSL_NO_PSK -- else if (alg_k & SSL_kPSK) -- { -- /* The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes -- * to return a \0-terminated identity. The last byte -- * is for us for simulating strnlen. */ -- char identity[PSK_MAX_IDENTITY_LEN + 2]; -- size_t identity_len; -- unsigned char *t = NULL; -- unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4]; -- unsigned int pre_ms_len = 0, psk_len = 0; -- int psk_err = 1; -- -- n = 0; -- if (s->psk_client_callback == NULL) -- { -- SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -- SSL_R_PSK_NO_CLIENT_CB); -- goto err; -- } -- -- memset(identity, 0, sizeof(identity)); -- psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint, -- identity, sizeof(identity) - 1, -- psk_or_pre_ms, sizeof(psk_or_pre_ms)); -- if (psk_len > PSK_MAX_PSK_LEN) -- { -- SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -- ERR_R_INTERNAL_ERROR); -- goto psk_err; -- } -- else if (psk_len == 0) -- { -- SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -- SSL_R_PSK_IDENTITY_NOT_FOUND); -- goto psk_err; -- } -- identity[PSK_MAX_IDENTITY_LEN + 1] = '\0'; -- identity_len = strlen(identity); -- if (identity_len > PSK_MAX_IDENTITY_LEN) -- { -- SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -- ERR_R_INTERNAL_ERROR); -- goto psk_err; -- } -- /* create PSK pre_master_secret */ -- pre_ms_len = 2+psk_len+2+psk_len; -- t = psk_or_pre_ms; -- memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len); -- s2n(psk_len, t); -- memset(t, 0, psk_len); -- t+=psk_len; -- s2n(psk_len, t); -- -- if (s->session->psk_identity_hint != NULL) -- OPENSSL_free(s->session->psk_identity_hint); -- s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); -- if (s->ctx->psk_identity_hint != NULL && -- s->session->psk_identity_hint == NULL) -- { -- SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -- ERR_R_MALLOC_FAILURE); -- goto psk_err; -- } -- -- if (s->session->psk_identity != NULL) -- OPENSSL_free(s->session->psk_identity); -- s->session->psk_identity = BUF_strdup(identity); -- if (s->session->psk_identity == NULL) -- { -- SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, -- ERR_R_MALLOC_FAILURE); -- goto psk_err; -- } -- -- s->session->master_key_length = -- s->method->ssl3_enc->generate_master_secret(s, -- s->session->master_key, -- psk_or_pre_ms, pre_ms_len); -- s2n(identity_len, p); -- memcpy(p, identity, identity_len); -- n = 2 + identity_len; -- psk_err = 0; -- psk_err: -- OPENSSL_cleanse(identity, sizeof(identity)); -- OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); -- if (psk_err != 0) -- { -- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); -- goto err; -- } -- } --#endif -- else -+ else if (!(alg_k & SSL_kPSK) || ((alg_k & SSL_kPSK) && !(alg_a & SSL_aPSK))) - { - ssl3_send_alert(s, SSL3_AL_FATAL, - SSL_AD_HANDSHAKE_FAILURE); -diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c -index 6358e1b..0dac7e7 100644 ---- a/ssl/s3_enc.c -+++ b/ssl/s3_enc.c -@@ -734,7 +734,7 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send) - } - - t=EVP_MD_CTX_size(hash); -- if (t < 0) -+ if (t < 0 || t > 20) - return -1; - md_size=t; - npad=(48/md_size)*md_size; -diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c -index 1d87ac5..77244d3 100644 ---- a/ssl/s3_lib.c -+++ b/ssl/s3_lib.c -@@ -2827,6 +2827,42 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ - 256, - }, - -+#ifndef OPENSSL_NO_PSK -+ /* ECDH PSK ciphersuites from RFC 5489 */ -+ -+ /* Cipher C037 */ -+ { -+ 1, -+ TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA256, -+ TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA256, -+ SSL_kEECDH, -+ SSL_aPSK, -+ SSL_AES128, -+ SSL_SHA256, -+ SSL_TLSV1, -+ SSL_NOT_EXP|SSL_HIGH, -+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF_SHA256, -+ 128, -+ 128, -+ }, -+ -+ /* Cipher C038 */ -+ { -+ 1, -+ TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA384, -+ TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA384, -+ SSL_kEECDH, -+ SSL_aPSK, -+ SSL_AES256, -+ SSL_SHA384, -+ SSL_TLSV1, -+ SSL_NOT_EXP|SSL_HIGH, -+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF_SHA384, -+ 256, -+ 256, -+ }, -+#endif /* OPENSSL_NO_PSK */ -+ - #endif /* OPENSSL_NO_ECDH */ - - -@@ -3979,7 +3999,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, - #endif /* OPENSSL_NO_KRB5 */ - #ifndef OPENSSL_NO_PSK - /* with PSK there must be server callback set */ -- if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL) -+ if ((alg_a & SSL_aPSK) && s->psk_server_callback == NULL) - continue; - #endif /* OPENSSL_NO_PSK */ - -diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c -index 9335eda..fe70124 100644 ---- a/ssl/s3_srvr.c -+++ b/ssl/s3_srvr.c -@@ -217,6 +217,7 @@ int ssl3_accept(SSL *s) - { - BUF_MEM *buf; - unsigned long alg_k,Time=(unsigned long)time(NULL); -+ unsigned long alg_a; - void (*cb)(const SSL *ssl,int type,int val)=NULL; - int ret= -1; - int new_state,state,skip=0; -@@ -418,8 +419,10 @@ int ssl3_accept(SSL *s) - case SSL3_ST_SW_CERT_A: - case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH or anon ECDH, */ -- /* normal PSK or KRB5 or SRP */ -+ /* non-RSA PSK or KRB5 or SRP */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aKRB5|SSL_aSRP)) -- && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) -+ /* Among PSK ciphersuites only RSA_PSK uses server certificate */ -+ && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK && -+ !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kRSA))) - { - ret=ssl3_send_server_certificate(s); -@@ -449,6 +452,7 @@ int ssl3_accept(SSL *s) - case SSL3_ST_SW_KEY_EXCH_A: - case SSL3_ST_SW_KEY_EXCH_B: - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; -+ alg_a = s->s3->tmp.new_cipher->algorithm_auth; - - /* clear this, it may get reset by - * send_server_key_exchange */ -@@ -478,10 +482,12 @@ int ssl3_accept(SSL *s) - * public key for key exchange. - */ - if (0 -- /* PSK: send ServerKeyExchange if PSK identity -- * hint if provided */ -+ /* PSK: send ServerKeyExchange if either: -+ * - PSK identity hint is provided, or -+ * - the key exchange is kEECDH. -+ */ - #ifndef OPENSSL_NO_PSK -- || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) -+ || ((alg_a & SSL_aPSK) && ((alg_k & SSL_kEECDH) || s->ctx->psk_identity_hint)) - #endif - #ifndef OPENSSL_NO_SRP - /* SRP: send ServerKeyExchange */ -@@ -1658,7 +1664,8 @@ int ssl3_send_server_key_exchange(SSL *s) - const EVP_MD *md = NULL; - unsigned char *p,*d; - int al,i; -- unsigned long type; -+ unsigned long alg_k; -+ unsigned long alg_a; - int n; - CERT *cert; - BIGNUM *r[4]; -@@ -1669,15 +1676,25 @@ int ssl3_send_server_key_exchange(SSL *s) - EVP_MD_CTX_init(&md_ctx); - if (s->state == SSL3_ST_SW_KEY_EXCH_A) - { -- type=s->s3->tmp.new_cipher->algorithm_mkey; -+ alg_k=s->s3->tmp.new_cipher->algorithm_mkey; -+ alg_a=s->s3->tmp.new_cipher->algorithm_auth; - cert=s->cert; - - buf=s->init_buf; - - r[0]=r[1]=r[2]=r[3]=NULL; - n=0; -+#ifndef OPENSSL_NO_PSK -+ if (alg_a & SSL_aPSK) -+ { -+ /* size for PSK identity hint */ -+ n+=2; -+ if (s->ctx->psk_identity_hint) -+ n+=strlen(s->ctx->psk_identity_hint); -+ } -+#endif /* !OPENSSL_NO_PSK */ - #ifndef OPENSSL_NO_RSA -- if (type & SSL_kRSA) -+ if (alg_k & SSL_kRSA) - { - rsa=cert->rsa_tmp; - if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) -@@ -1704,10 +1721,9 @@ int ssl3_send_server_key_exchange(SSL *s) - r[1]=rsa->e; - s->s3->tmp.use_rsa_tmp=1; - } -- else - #endif - #ifndef OPENSSL_NO_DH -- if (type & SSL_kEDH) -+ else if (alg_k & SSL_kEDH) - { - dhp=cert->dh_tmp; - if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) -@@ -1760,10 +1776,9 @@ int ssl3_send_server_key_exchange(SSL *s) - r[1]=dh->g; - r[2]=dh->pub_key; - } -- else - #endif - #ifndef OPENSSL_NO_ECDH -- if (type & SSL_kEECDH) -+ else if (alg_k & SSL_kEECDH) - { - const EC_GROUP *group; - -@@ -1876,7 +1891,7 @@ int ssl3_send_server_key_exchange(SSL *s) - * to encode the entire ServerECDHParams - * structure. - */ -- n = 4 + encodedlen; -+ n += 4 + encodedlen; - - /* We'll generate the serverKeyExchange message - * explicitly so we can set these to NULLs -@@ -1886,18 +1901,9 @@ int ssl3_send_server_key_exchange(SSL *s) - r[2]=NULL; - r[3]=NULL; - } -- else - #endif /* !OPENSSL_NO_ECDH */ --#ifndef OPENSSL_NO_PSK -- if (type & SSL_kPSK) -- { -- /* reserve size for record length and PSK identity hint*/ -- n+=2+strlen(s->ctx->psk_identity_hint); -- } -- else --#endif /* !OPENSSL_NO_PSK */ - #ifndef OPENSSL_NO_SRP -- if (type & SSL_kSRP) -+ else if (alg_k & SSL_kSRP) - { - if ((s->srp_ctx.N == NULL) || - (s->srp_ctx.g == NULL) || -@@ -1912,8 +1918,8 @@ int ssl3_send_server_key_exchange(SSL *s) - r[2]=s->srp_ctx.s; - r[3]=s->srp_ctx.B; - } -- else - #endif -+ else if (!(alg_k & SSL_kPSK)) - { - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); -@@ -1923,15 +1929,16 @@ int ssl3_send_server_key_exchange(SSL *s) - { - nr[i]=BN_num_bytes(r[i]); - #ifndef OPENSSL_NO_SRP -- if ((i == 2) && (type & SSL_kSRP)) -+ if ((i == 2) && (alg_k & SSL_kSRP)) - n+=1+nr[i]; - else - #endif - n+=2+nr[i]; - } - -- if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) -- && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) -+ if (!(alg_a & (SSL_aNULL|SSL_aSRP)) -+ /* Among PSK ciphersuites only RSA uses a certificate */ -+ && !((alg_a & SSL_aPSK) && !(alg_k & SSL_kRSA))) - { - if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md)) - == NULL) -@@ -1958,7 +1965,7 @@ int ssl3_send_server_key_exchange(SSL *s) - for (i=0; i < 4 && r[i] != NULL; i++) - { - #ifndef OPENSSL_NO_SRP -- if ((i == 2) && (type & SSL_kSRP)) -+ if ((i == 2) && (alg_k & SSL_kSRP)) - { - *p = nr[i]; - p++; -@@ -1970,8 +1977,32 @@ int ssl3_send_server_key_exchange(SSL *s) - p+=nr[i]; - } - -+/* Note: ECDHE PSK ciphersuites use SSL_kEECDH and SSL_aPSK. -+ * When one of them is used, the server key exchange record needs to have both -+ * the psk_identity_hint and the ServerECDHParams. */ -+#ifndef OPENSSL_NO_PSK -+ if (alg_a & SSL_aPSK) -+ { -+ if (s->ctx->psk_identity_hint) -+ { -+ /* copy PSK identity hint */ -+ s2n(strlen(s->ctx->psk_identity_hint), p); -+ strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint)); -+ p+=strlen(s->ctx->psk_identity_hint); -+ } -+ else -+ { -+ /* No identity hint is provided. */ -+ *p = 0; -+ p += 1; -+ *p = 0; -+ p += 1; -+ } -+ } -+#endif /* OPENSSL_NO_PSK */ -+ - #ifndef OPENSSL_NO_ECDH -- if (type & SSL_kEECDH) -+ if (alg_k & SSL_kEECDH) - { - /* XXX: For now, we only support named (not generic) curves. - * In this situation, the serverKeyExchange message has: -@@ -1994,17 +2025,7 @@ int ssl3_send_server_key_exchange(SSL *s) - encodedPoint = NULL; - p += encodedlen; - } --#endif -- --#ifndef OPENSSL_NO_PSK -- if (type & SSL_kPSK) -- { -- /* copy PSK identity hint */ -- s2n(strlen(s->ctx->psk_identity_hint), p); -- strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint)); -- p+=strlen(s->ctx->psk_identity_hint); -- } --#endif -+#endif /* OPENSSL_NO_ECDH */ - - /* not anonymous */ - if (pkey != NULL) -@@ -2041,7 +2062,7 @@ int ssl3_send_server_key_exchange(SSL *s) - n+=u+2; - } - else --#endif -+#endif /* OPENSSL_NO_RSA */ - if (md) - { - /* For TLS1.2 and later send signature -@@ -2215,6 +2236,7 @@ int ssl3_get_client_key_exchange(SSL *s) - int i,al,ok; - long n; - unsigned long alg_k; -+ unsigned long alg_a; - unsigned char *p; - #ifndef OPENSSL_NO_RSA - RSA *rsa=NULL; -@@ -2232,7 +2254,11 @@ int ssl3_get_client_key_exchange(SSL *s) - EC_KEY *srvr_ecdh = NULL; - EVP_PKEY *clnt_pub_pkey = NULL; - EC_POINT *clnt_ecpoint = NULL; -- BN_CTX *bn_ctx = NULL; -+ BN_CTX *bn_ctx = NULL; -+#ifndef OPENSSL_NO_PSK -+ unsigned int psk_len = 0; -+ unsigned char psk[PSK_MAX_PSK_LEN]; -+#endif /* OPENSSL_NO_PSK */ - #endif - - n=s->method->ssl_get_message(s, -@@ -2246,7 +2272,106 @@ int ssl3_get_client_key_exchange(SSL *s) - p=(unsigned char *)s->init_msg; - - alg_k=s->s3->tmp.new_cipher->algorithm_mkey; -+ alg_a=s->s3->tmp.new_cipher->algorithm_auth; -+ -+#ifndef OPENSSL_NO_PSK -+ if (alg_a & SSL_aPSK) -+ { -+ unsigned char *t = NULL; -+ unsigned char pre_ms[PSK_MAX_PSK_LEN*2+4]; -+ unsigned int pre_ms_len = 0; -+ int psk_err = 1; -+ char tmp_id[PSK_MAX_IDENTITY_LEN+1]; -+ -+ al=SSL_AD_HANDSHAKE_FAILURE; -+ -+ n2s(p, i); -+ if (n != i+2 && !(alg_k & SSL_kEECDH)) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -+ SSL_R_LENGTH_MISMATCH); -+ goto psk_err; -+ } -+ if (i > PSK_MAX_IDENTITY_LEN) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -+ SSL_R_DATA_LENGTH_TOO_LONG); -+ goto psk_err; -+ } -+ if (s->psk_server_callback == NULL) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -+ SSL_R_PSK_NO_SERVER_CB); -+ goto psk_err; -+ } -+ -+ /* Create guaranteed NUL-terminated identity -+ * string for the callback */ -+ memcpy(tmp_id, p, i); -+ memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i); -+ psk_len = s->psk_server_callback(s, tmp_id, psk, sizeof(psk)); - -+ if (psk_len > PSK_MAX_PSK_LEN) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -+ ERR_R_INTERNAL_ERROR); -+ goto psk_err; -+ } -+ else if (psk_len == 0) -+ { -+ /* PSK related to the given identity not found */ -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -+ SSL_R_PSK_IDENTITY_NOT_FOUND); -+ al=SSL_AD_UNKNOWN_PSK_IDENTITY; -+ goto psk_err; -+ } -+ if (!(alg_k & SSL_kEECDH)) -+ { -+ /* Create the shared secret now if we're not using ECDHE-PSK.*/ -+ pre_ms_len=2+psk_len+2+psk_len; -+ t = pre_ms; -+ s2n(psk_len, t); -+ memset(t, 0, psk_len); -+ t+=psk_len; -+ s2n(psk_len, t); -+ memcpy(t, psk, psk_len); -+ -+ s->session->master_key_length= -+ s->method->ssl3_enc->generate_master_secret(s, -+ s->session->master_key, pre_ms, pre_ms_len); -+ } -+ if (s->session->psk_identity != NULL) -+ OPENSSL_free(s->session->psk_identity); -+ s->session->psk_identity = BUF_strdup(tmp_id); -+ OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1); -+ if (s->session->psk_identity == NULL) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -+ ERR_R_MALLOC_FAILURE); -+ goto psk_err; -+ } -+ -+ if (s->session->psk_identity_hint != NULL) -+ OPENSSL_free(s->session->psk_identity_hint); -+ s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); -+ if (s->ctx->psk_identity_hint != NULL && -+ s->session->psk_identity_hint == NULL) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -+ ERR_R_MALLOC_FAILURE); -+ goto psk_err; -+ } -+ -+ p += i; -+ n -= (i + 2); -+ psk_err = 0; -+ psk_err: -+ OPENSSL_cleanse(pre_ms, sizeof(pre_ms)); -+ if (psk_err != 0) -+ goto f_err; -+ } -+#endif /* OPENSSL_NO_PSK */ -+ if (0) {} - #ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) - { -@@ -2410,10 +2535,9 @@ int ssl3_get_client_key_exchange(SSL *s) - p,sizeof(rand_premaster_secret)); - OPENSSL_cleanse(p,sizeof(rand_premaster_secret)); - } -- else - #endif - #ifndef OPENSSL_NO_DH -- if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) -+ else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) - { - n2s(p,i); - if (n != i+2) -@@ -2474,10 +2598,9 @@ int ssl3_get_client_key_exchange(SSL *s) - s->session->master_key,p,i); - OPENSSL_cleanse(p,i); - } -- else - #endif - #ifndef OPENSSL_NO_KRB5 -- if (alg_k & SSL_kKRB5) -+ else if (alg_k & SSL_kKRB5) - { - krb5_error_code krb5rc; - krb5_data enc_ticket; -@@ -2666,17 +2789,20 @@ int ssl3_get_client_key_exchange(SSL *s) - ** if (s->kssl_ctx) s->kssl_ctx = NULL; - */ - } -- else - #endif /* OPENSSL_NO_KRB5 */ -- - #ifndef OPENSSL_NO_ECDH -- if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) -+ else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) - { - int ret = 1; - int field_size = 0; - const EC_KEY *tkey; - const EC_GROUP *group; - const BIGNUM *priv_key; -+#ifndef OPENSSL_NO_PSK -+ unsigned char *pre_ms; -+ unsigned int pre_ms_len; -+ unsigned char *t; -+#endif /* OPENSSL_NO_PSK */ - - /* initialize structures for server's ECDH key pair */ - if ((srvr_ecdh = EC_KEY_new()) == NULL) -@@ -2772,7 +2898,7 @@ int ssl3_get_client_key_exchange(SSL *s) - } - - /* Get encoded point length */ -- i = *p; -+ i = *p; - p += 1; - if (n != 1 + i) - { -@@ -2814,221 +2940,145 @@ int ssl3_get_client_key_exchange(SSL *s) - EC_KEY_free(srvr_ecdh); - BN_CTX_free(bn_ctx); - EC_KEY_free(s->s3->tmp.ecdh); -- s->s3->tmp.ecdh = NULL; -+ s->s3->tmp.ecdh = NULL; - -- /* Compute the master secret */ -- s->session->master_key_length = s->method->ssl3_enc-> \ -- generate_master_secret(s, s->session->master_key, p, i); -- -- OPENSSL_cleanse(p, i); -- return (ret); -- } -- else --#endif - #ifndef OPENSSL_NO_PSK -- if (alg_k & SSL_kPSK) -+ /* ECDHE PSK ciphersuites from RFC 5489 */ -+ if ((alg_a & SSL_aPSK) && psk_len != 0) - { -- unsigned char *t = NULL; -- unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4]; -- unsigned int pre_ms_len = 0, psk_len = 0; -- int psk_err = 1; -- char tmp_id[PSK_MAX_IDENTITY_LEN+1]; -- -- al=SSL_AD_HANDSHAKE_FAILURE; -- -- n2s(p,i); -- if (n != i+2) -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -- SSL_R_LENGTH_MISMATCH); -- goto psk_err; -- } -- if (i > PSK_MAX_IDENTITY_LEN) -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -- SSL_R_DATA_LENGTH_TOO_LONG); -- goto psk_err; -- } -- if (s->psk_server_callback == NULL) -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -- SSL_R_PSK_NO_SERVER_CB); -- goto psk_err; -- } -- -- /* Create guaranteed NULL-terminated identity -- * string for the callback */ -- memcpy(tmp_id, p, i); -- memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i); -- psk_len = s->psk_server_callback(s, tmp_id, -- psk_or_pre_ms, sizeof(psk_or_pre_ms)); -- OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1); -- -- if (psk_len > PSK_MAX_PSK_LEN) -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -- ERR_R_INTERNAL_ERROR); -- goto psk_err; -- } -- else if (psk_len == 0) -- { -- /* PSK related to the given identity not found */ -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -- SSL_R_PSK_IDENTITY_NOT_FOUND); -- al=SSL_AD_UNKNOWN_PSK_IDENTITY; -- goto psk_err; -- } -- -- /* create PSK pre_master_secret */ -- pre_ms_len=2+psk_len+2+psk_len; -- t = psk_or_pre_ms; -- memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len); -- s2n(psk_len, t); -- memset(t, 0, psk_len); -- t+=psk_len; -- s2n(psk_len, t); -- -- if (s->session->psk_identity != NULL) -- OPENSSL_free(s->session->psk_identity); -- s->session->psk_identity = BUF_strdup((char *)p); -- if (s->session->psk_identity == NULL) -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -- ERR_R_MALLOC_FAILURE); -- goto psk_err; -- } -- -- if (s->session->psk_identity_hint != NULL) -- OPENSSL_free(s->session->psk_identity_hint); -- s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); -- if (s->ctx->psk_identity_hint != NULL && -- s->session->psk_identity_hint == NULL) -+ pre_ms_len = 2+i+2+psk_len; -+ pre_ms = OPENSSL_malloc(pre_ms_len); -+ if (pre_ms == NULL) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); -- goto psk_err; -+ goto err; - } -- -- s->session->master_key_length= -- s->method->ssl3_enc->generate_master_secret(s, -- s->session->master_key, psk_or_pre_ms, pre_ms_len); -- psk_err = 0; -- psk_err: -- OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); -- if (psk_err != 0) -- goto f_err; -+ memset(pre_ms, 0, pre_ms_len); -+ t = pre_ms; -+ s2n(i, t); -+ memcpy(t, p, i); -+ t += i; -+ s2n(psk_len, t); -+ memcpy(t, psk, psk_len); -+ s->session->master_key_length = s->method->ssl3_enc \ -+ -> generate_master_secret(s, -+ s->session->master_key, pre_ms, pre_ms_len); -+ OPENSSL_cleanse(pre_ms, pre_ms_len); -+ OPENSSL_free(pre_ms); - } -- else --#endif --#ifndef OPENSSL_NO_SRP -- if (alg_k & SSL_kSRP) -+#endif /* OPENSSL_NO_PSK */ -+ if (!(alg_a & SSL_aPSK)) - { -- int param_len; -- -- n2s(p,i); -- param_len=i+2; -- if (param_len > n) -- { -- al=SSL_AD_DECODE_ERROR; -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH); -- goto f_err; -- } -- if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL))) -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB); -- goto err; -- } -- if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0 -- || BN_is_zero(s->srp_ctx.A)) -- { -- al=SSL_AD_ILLEGAL_PARAMETER; -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_PARAMETERS); -- goto f_err; -- } -- if (s->session->srp_username != NULL) -- OPENSSL_free(s->session->srp_username); -- s->session->srp_username = BUF_strdup(s->srp_ctx.login); -- if (s->session->srp_username == NULL) -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -- ERR_R_MALLOC_FAILURE); -- goto err; -- } -+ /* Compute the master secret */ -+ s->session->master_key_length = s->method->ssl3_enc \ -+ -> generate_master_secret(s, -+ s->session->master_key, p, i); -+ } - -- if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0) -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); -- goto err; -- } -+ OPENSSL_cleanse(p, i); -+ } -+#endif -+#ifndef OPENSSL_NO_SRP -+ else if (alg_k & SSL_kSRP) -+ { -+ int param_len; - -- p+=i; -+ n2s(p,i); -+ param_len=i+2; -+ if (param_len > n) -+ { -+ al=SSL_AD_DECODE_ERROR; -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH); -+ goto f_err; -+ } -+ if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL))) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB); -+ goto err; -+ } -+ if (s->session->srp_username != NULL) -+ OPENSSL_free(s->session->srp_username); -+ s->session->srp_username = BUF_strdup(s->srp_ctx.login); -+ if (s->session->srp_username == NULL) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -+ ERR_R_MALLOC_FAILURE); -+ goto err; - } -- else --#endif /* OPENSSL_NO_SRP */ -- if (alg_k & SSL_kGOST) -- { -- int ret = 0; -- EVP_PKEY_CTX *pkey_ctx; -- EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; -- unsigned char premaster_secret[32], *start; -- size_t outlen=32, inlen; -- unsigned long alg_a; -- int Ttag, Tclass; -- long Tlen; -- -- /* Get our certificate private key*/ -- alg_a = s->s3->tmp.new_cipher->algorithm_auth; -- if (alg_a & SSL_aGOST94) -- pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; -- else if (alg_a & SSL_aGOST01) -- pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; - -- pkey_ctx = EVP_PKEY_CTX_new(pk,NULL); -- EVP_PKEY_decrypt_init(pkey_ctx); -- /* If client certificate is present and is of the same type, maybe -- * use it for key exchange. Don't mind errors from -- * EVP_PKEY_derive_set_peer, because it is completely valid to use -- * a client certificate for authorization only. */ -- client_pub_pkey = X509_get_pubkey(s->session->peer); -- if (client_pub_pkey) -- { -- if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) -- ERR_clear_error(); -- } -- /* Decrypt session key */ -- if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED || -- Ttag != V_ASN1_SEQUENCE || -- Tclass != V_ASN1_UNIVERSAL) -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); -- goto gerr; -- } -- start = p; -- inlen = Tlen; -- if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) -+ if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); -+ goto err; -+ } - -- { -- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); -- goto gerr; -- } -- /* Generate master secret */ -- s->session->master_key_length= -- s->method->ssl3_enc->generate_master_secret(s, -- s->session->master_key,premaster_secret,32); -- /* Check if pubkey from client certificate was used */ -- if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) -- ret = 2; -- else -- ret = 1; -- gerr: -- EVP_PKEY_free(client_pub_pkey); -- EVP_PKEY_CTX_free(pkey_ctx); -- if (ret) -- return ret; -- else -- goto err; -+ p+=i; -+ } -+#endif /* OPENSSL_NO_SRP */ -+ else if (alg_k & SSL_kGOST) -+ { -+ int ret = 0; -+ EVP_PKEY_CTX *pkey_ctx; -+ EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; -+ unsigned char premaster_secret[32], *start; -+ size_t outlen=32, inlen; -+ unsigned long alg_a; -+ int Ttag, Tclass; -+ long Tlen; -+ -+ /* Get our certificate private key*/ -+ alg_a = s->s3->tmp.new_cipher->algorithm_auth; -+ if (alg_a & SSL_aGOST94) -+ pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; -+ else if (alg_a & SSL_aGOST01) -+ pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; -+ -+ pkey_ctx = EVP_PKEY_CTX_new(pk,NULL); -+ EVP_PKEY_decrypt_init(pkey_ctx); -+ /* If client certificate is present and is of the same type, maybe -+ * use it for key exchange. Don't mind errors from -+ * EVP_PKEY_derive_set_peer, because it is completely valid to use -+ * a client certificate for authorization only. */ -+ client_pub_pkey = X509_get_pubkey(s->session->peer); -+ if (client_pub_pkey) -+ { -+ if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) -+ ERR_clear_error(); -+ } -+ /* Decrypt session key */ -+ if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED || -+ Ttag != V_ASN1_SEQUENCE || -+ Tclass != V_ASN1_UNIVERSAL) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); -+ goto gerr; -+ } -+ start = p; -+ inlen = Tlen; -+ if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) -+ { -+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); -+ goto gerr; - } -+ /* Generate master secret */ -+ s->session->master_key_length= -+ s->method->ssl3_enc->generate_master_secret(s, -+ s->session->master_key,premaster_secret,32); -+ /* Check if pubkey from client certificate was used */ -+ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) -+ ret = 2; -+ else -+ ret = 1; -+ gerr: -+ EVP_PKEY_free(client_pub_pkey); -+ EVP_PKEY_CTX_free(pkey_ctx); -+ if (ret) -+ return ret; - else -+ goto err; -+ } -+ else if (!(alg_k & SSL_kPSK)) - { - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, -diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c -index 0fda4ca..6c57d2a 100644 ---- a/ssl/ssl_lib.c -+++ b/ssl/ssl_lib.c -@@ -1424,7 +1424,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, - #endif /* OPENSSL_NO_KRB5 */ - #ifndef OPENSSL_NO_PSK - /* with PSK there must be client callback set */ -- if (((c->algorithm_mkey & SSL_kPSK) || (c->algorithm_auth & SSL_aPSK)) && -+ if ((c->algorithm_auth & SSL_aPSK) && - s->psk_client_callback == NULL) - continue; - #endif /* OPENSSL_NO_PSK */ -diff --git a/ssl/tls1.h b/ssl/tls1.h -index 9e035fb..3e6b7c7 100644 ---- a/ssl/tls1.h -+++ b/ssl/tls1.h -@@ -536,6 +536,10 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) - #define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 0x0300CC14 - #define TLS1_CK_DHE_RSA_CHACHA20_POLY1305 0x0300CC15 - -+/* ECDHE PSK ciphersuites from RFC 5489 */ -+#define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0x0300C037 -+#define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0x0300C038 -+ - /* XXX - * Inconsistency alert: - * The OpenSSL names of ciphers with ephemeral DH here include the string -@@ -691,6 +698,10 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) - #define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "ECDHE-ECDSA-CHACHA20-POLY1305" - #define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305" - -+/* ECDHE PSK ciphersuites from RFC 5489 */ -+#define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA256 "ECDHE-PSK-WITH-AES-128-CBC-SHA256" -+#define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA384 "ECDHE-PSK-WITH-AES-256-CBC-SHA384" -+ - #define TLS_CT_RSA_SIGN 1 - #define TLS_CT_DSS_SIGN 2 - #define TLS_CT_RSA_FIXED_DH 3 -2.0.0.526.g5318336 - |