summaryrefslogtreecommitdiff
path: root/main/openssl/ssl/s3_srvr.c
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2014-06-05 18:34:09 +0200
committerArne Schwabe <arne@rfc2549.org>2014-06-05 18:34:09 +0200
commit626c2706b1f7abdc6af1216873b7687e59025d1f (patch)
tree0617ebb1e49364082071482aa9a977dd1da45940 /main/openssl/ssl/s3_srvr.c
parent614b8790e5fc0bb3864eb2e3dd8c15016333d016 (diff)
Update OpenSSL to aosp/masterc0.6.13
--HG-- extra : rebase_source : a2f70c1a7529c7fcfc88f8dd1882e66e6ba42167
Diffstat (limited to 'main/openssl/ssl/s3_srvr.c')
-rw-r--r--main/openssl/ssl/s3_srvr.c540
1 files changed, 293 insertions, 247 deletions
diff --git a/main/openssl/ssl/s3_srvr.c b/main/openssl/ssl/s3_srvr.c
index 8692f149..0ee781f1 100644
--- a/main/openssl/ssl/s3_srvr.c
+++ b/main/openssl/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;
@@ -412,9 +413,11 @@ 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)
- && !(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))
&& !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
{
ret=ssl3_send_server_certificate(s);
@@ -443,6 +446,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 */
@@ -472,10 +476,12 @@ int ssl3_accept(SSL *s)
* public key for key exchange.
*/
if (s->s3->tmp.use_rsa_tmp
- /* 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->session->psk_identity_hint))
#endif
#ifndef OPENSSL_NO_SRP
/* SRP: send ServerKeyExchange */
@@ -1589,11 +1595,16 @@ int ssl3_send_server_key_exchange(SSL *s)
int curve_id = 0;
BN_CTX *bn_ctx = NULL;
#endif
+#ifndef OPENSSL_NO_PSK
+ const char* psk_identity_hint;
+ size_t psk_identity_hint_len;
+#endif
EVP_PKEY *pkey;
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];
@@ -1604,15 +1615,28 @@ 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 */
+ psk_identity_hint = s->session->psk_identity_hint;
+ if (psk_identity_hint)
+ psk_identity_hint_len = strlen(psk_identity_hint);
+ else
+ psk_identity_hint_len = 0;
+ n+=2+psk_identity_hint_len;
+ }
+#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))
@@ -1639,10 +1663,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))
@@ -1695,10 +1718,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;
@@ -1811,7 +1833,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
@@ -1821,18 +1843,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) ||
@@ -1847,8 +1860,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);
@@ -1858,15 +1871,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)
- && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
+ if (!(alg_a & SSL_aNULL)
+ /* 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)
@@ -1893,7 +1907,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++;
@@ -1905,8 +1919,24 @@ 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)
+ {
+ /* copy PSK identity hint (if provided) */
+ s2n(psk_identity_hint_len, p);
+ if (psk_identity_hint_len > 0)
+ {
+ memcpy(p, psk_identity_hint, psk_identity_hint_len);
+ p+=psk_identity_hint_len;
+ }
+ }
+#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:
@@ -1929,17 +1959,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)
@@ -1976,7 +1996,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
@@ -2145,6 +2165,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;
@@ -2162,7 +2183,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,
@@ -2176,7 +2201,95 @@ 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;
+ }
+
+ 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)
{
@@ -2281,10 +2394,9 @@ int ssl3_get_client_key_exchange(SSL *s)
p,i);
OPENSSL_cleanse(p,i);
}
- 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)
@@ -2345,10 +2457,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;
@@ -2537,17 +2648,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)
@@ -2643,7 +2757,7 @@ int ssl3_get_client_key_exchange(SSL *s)
}
/* Get encoded point length */
- i = *p;
+ i = *p;
p += 1;
if (n != 1 + i)
{
@@ -2685,223 +2799,155 @@ 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+psk_len+2+i;
+ 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(psk_len, t);
+ memcpy(t, psk, psk_len);
+ t += psk_len;
+ s2n(i, t);
+ memcpy(t, p, i);
+ 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 /* OPENSSL_NO_PSK */
+ if (!(alg_a & SSL_aPSK))
+ {
+ /* 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);
+ }
#endif
#ifndef OPENSSL_NO_SRP
- if (alg_k & SSL_kSRP)
+ else if (alg_k & SSL_kSRP)
+ {
+ 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)))
{
- int param_len;
+ 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;
+ }
- 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;
- }
+ 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;
+ }
- 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;
- }
+ 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;
+
+ /* 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;
- p+=i;
+ 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 ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED)))
+ {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
+ goto gerr;
+ }
+ if (p[1] == 0x81)
+ {
+ start = p+3;
+ inlen = p[2];
+ }
+ else if (p[1] < 0x80)
+ {
+ start = p+2;
+ inlen = p[1];
}
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;
-
- /* 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 ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED)))
- {
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
- goto gerr;
- }
- if (p[1] == 0x81)
- {
- start = p+3;
- inlen = p[2];
- }
- else if (p[1] < 0x80)
- {
- start = p+2;
- inlen = p[1];
- }
- else
- {
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
- goto gerr;
- }
- 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;
+ }
+ 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;
+ {
+ 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,