summaryrefslogtreecommitdiff
path: root/main/openssl/ssl/s3_clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/openssl/ssl/s3_clnt.c')
-rw-r--r--main/openssl/ssl/s3_clnt.c359
1 files changed, 207 insertions, 152 deletions
diff --git a/main/openssl/ssl/s3_clnt.c b/main/openssl/ssl/s3_clnt.c
index f71470a3..b65b12d9 100644
--- a/main/openssl/ssl/s3_clnt.c
+++ b/main/openssl/ssl/s3_clnt.c
@@ -345,9 +345,10 @@ int ssl3_connect(SSL *s)
}
#endif
/* Check if it is anon DH/ECDH */
- /* or PSK */
+ /* or non-RSA PSK */
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
- !(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;
@@ -1377,12 +1378,14 @@ int ssl3_get_key_exchange(SSL *s)
omitted if no identity hint is sent. Set
session->sess_cert anyway to avoid problems
later.*/
- if (s->s3->tmp.new_cipher->algorithm_mkey & 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)
- OPENSSL_free(s->ctx->psk_identity_hint);
- s->ctx->psk_identity_hint = NULL;
+ if (s->session->psk_identity_hint)
+ {
+ OPENSSL_free(s->session->psk_identity_hint);
+ s->session->psk_identity_hint = NULL;
+ }
}
#endif
s->s3->tmp.reuse_message=1;
@@ -1425,52 +1428,58 @@ 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];
al=SSL_AD_HANDSHAKE_FAILURE;
n2s(p,i);
param_len=i+2;
- /* 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)
- {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
- SSL_R_DATA_LENGTH_TOO_LONG);
- goto f_err;
+ if (s->session->psk_identity_hint)
+ {
+ OPENSSL_free(s->session->psk_identity_hint);
+ s->session->psk_identity_hint = NULL;
}
- if (param_len > n)
+ if (i != 0)
{
- al=SSL_AD_DECODE_ERROR;
- 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)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_DATA_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
+ goto f_err;
+ }
+ /* 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);
+ s->session->psk_identity_hint = BUF_strdup(tmp_id_hint);
+ if (s->session->psk_identity_hint == NULL)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
}
- /* 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)
- {
- 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;
@@ -1547,10 +1556,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)
{
@@ -1599,9 +1607,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)
@@ -1782,14 +1787,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 */
@@ -1894,8 +1899,9 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
}
else
{
- if (!(alg_a & SSL_aNULL) && !(alg_k & SSL_kPSK))
- /* aNULL or kPSK do not need public keys */
+ if (!(alg_a & SSL_aNULL) &&
+ /* 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;
@@ -2297,6 +2303,7 @@ int ssl3_send_client_key_exchange(SSL *s)
unsigned char *p,*d;
int n;
unsigned long alg_k;
+ unsigned long alg_a;
#ifndef OPENSSL_NO_RSA
unsigned char *q;
EVP_PKEY *pkey=NULL;
@@ -2311,7 +2318,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)
{
@@ -2319,7 +2330,89 @@ 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)
+ {
+ char identity[PSK_MAX_IDENTITY_LEN + 1];
+ 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;
+ }
+
+ memset(identity, 0, sizeof(identity));
+ psk_len = s->psk_client_callback(s, s->session->psk_identity_hint,
+ identity, sizeof(identity), 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_len = strnlen(identity, sizeof(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 != 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, PSK_MAX_IDENTITY_LEN);
+ 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
@@ -2580,14 +2673,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
/* Did we send out the client's
* ECDH share for use in premaster
@@ -2708,15 +2806,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+psk_len+2+n;
+ 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(psk_len, t);
+ memcpy(t, psk, psk_len);
+ t += psk_len;
+ s2n(n, t);
+ memcpy(t, p, n);
+ 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;
@@ -2744,29 +2868,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;
@@ -2889,89 +3026,7 @@ int ssl3_send_client_key_exchange(SSL *s)
}
}
#endif
-#ifndef OPENSSL_NO_PSK
- else if (alg_k & SSL_kPSK)
- {
- char identity[PSK_MAX_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;
- }
-
- psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
- identity, PSK_MAX_IDENTITY_LEN,
- 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;
- }
-
- /* 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);
- n = strlen(identity);
- s2n(n, p);
- memcpy(p, identity, n);
- n+=2;
- psk_err = 0;
- psk_err:
- OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
- 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))
{
ssl3_send_alert(s, SSL3_AL_FATAL,
SSL_AD_HANDSHAKE_FAILURE);
@@ -3276,7 +3331,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
alg_a=s->s3->tmp.new_cipher->algorithm_auth;
/* we don't have a certificate */
- if ((alg_a & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) || (alg_k & SSL_kPSK))
+ if ((alg_a & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) || ((alg_a & SSL_aPSK) && !(alg_k & SSL_kRSA)))
return(1);
sc=s->session->sess_cert;