Newer
Older
{
if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al))
{
/* 'al' set by ssl_parse_clienthello_tlsext */
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT);
if (ssl_check_clienthello_tlsext(s) <= 0) {
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
/* Check if we want to use external pre-shared secret for this
* handshake for not reused session only. We need to generate
* server_random before calling tls_session_secret_cb in order to allow
* SessionTicket processing to use it in key derivation. */
{
unsigned long Time;
unsigned char *pos;
Time=(unsigned long)time(NULL); /* Time */
pos=s->s3->server_random;
l2n(Time,pos);
if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
{
al=SSL_AD_INTERNAL_ERROR;
goto f_err;
}
}
if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
{
SSL_CIPHER *pref_cipher=NULL;
s->session->master_key_length=sizeof(s->session->master_key);
if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
{
s->hit=1;
s->session->ciphers=ciphers;
s->session->verify_result=X509_V_OK;
ciphers=NULL;
/* check if some cipher was preferred by call back */
pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
if (pref_cipher == NULL)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
goto f_err;
}
s->session->cipher=pref_cipher;
if (s->cipher_list)
sk_SSL_CIPHER_free(s->cipher_list);
if (s->cipher_list_by_id)
sk_SSL_CIPHER_free(s->cipher_list_by_id);
s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
}
}
/* Worst case, we will use the NULL compression, but if we have other
* options, we will now look for them. We have i-1 compression
* algorithms from the client, starting at q. */
s->s3->tmp.new_compression=NULL;
if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods)
{ /* See if we have a match */
int m,nn,o,v,done=0;
comp=sk_SSL_COMP_value(s->ctx->comp_methods,m);
v=comp->id;
for (o=0; o<i; o++)
{
if (v == q[o])
{
done=1;
break;
}
}
if (done) break;
}
if (done)
s->s3->tmp.new_compression=comp;
else
comp=NULL;
}
Lutz Jänicke
committed
/* Given s->session->ciphers and SSL_get_ciphers, we must
* pick a cipher */
if (!s->hit)
{
#ifdef OPENSSL_NO_COMP
s->session->compress_meth=0;
#else
s->session->compress_meth=(comp == NULL)?0:comp->id;
if (s->session->ciphers != NULL)
s->session->ciphers=ciphers;
if (ciphers == NULL)
{
al=SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_PASSED);
goto f_err;
}
ciphers=NULL;
c=ssl3_choose_cipher(s,s->session->ciphers,
Lutz Jänicke
committed
SSL_get_ciphers(s));
if (c == NULL)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
goto f_err;
}
s->s3->tmp.new_cipher=c;
}
else
{
/* Session-id reuse */
#ifdef REUSE_CIPHER_BUG
SSL_CIPHER *nc=NULL;
SSL_CIPHER *ec=NULL;
if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG)
{
sk=s->session->ciphers;
if (c->algorithm_enc & SSL_eNULL)
ec=c;
}
if (nc != NULL)
s->s3->tmp.new_cipher=nc;
else if (ec != NULL)
s->s3->tmp.new_cipher=ec;
else
s->s3->tmp.new_cipher=s->session->cipher;
}
else
#endif
s->s3->tmp.new_cipher=s->session->cipher;
}
ssl3_digest_cached_records(s);
/* we now have the following setup.
* client_random
* cipher_list - our prefered list of ciphers
* ciphers - the clients prefered list of ciphers
* compression - basically ignored right now
* ssl version is set - sslv3
* s->session - The ssl session has been setup.
* s->tmp.new_cipher - the new cipher to use.
*/
ret=1;
if (0)
{
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
}
err:
if (ciphers != NULL) sk_SSL_CIPHER_free(ciphers);
return(ret);
}
{
unsigned char *buf;
unsigned char *p,*d;
int i,sl;
unsigned long l;
#ifdef OPENSSL_NO_TLSEXT
unsigned long Time;
#endif
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
{
buf=(unsigned char *)s->init_buf->data;
p=s->s3->server_random;
/* Generate server_random if it was not needed previously */
Time=(unsigned long)time(NULL); /* Time */
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
return -1;
/* Do the message type and length last */
d=p= &(buf[4]);
*(p++)=s->version>>8;
*(p++)=s->version&0xff;
/* Random stuff */
memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
p+=SSL3_RANDOM_SIZE;
/* now in theory we have 3 options to sending back the
* session id. If it is a re-use, we send back the
* old session-id, if it is a new session, we send
* back the new session-id or we send back a 0 length
* session-id if we want it to be single use.
* Currently I will not implement the '0' length session-id
* 12-Jan-98 - I'll now support the '0' length stuff.
*
* We also have an additional case where stateless session
* resumption is successful: we always send back the old
* session id. In this case s->hit is non zero: this can
* only happen if stateless session resumption is succesful
* if session caching is disabled so existing functionality
* is unaffected.
if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
&& !s->hit)
s->session->session_id_length=0;
sl=s->session->session_id_length;
if (sl > (int)sizeof(s->session->session_id))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
return -1;
}
*(p++)=sl;
memcpy(p,s->session->session_id,sl);
p+=sl;
/* put the cipher */
i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p);
p+=i;
/* put the compression method */
#ifdef OPENSSL_NO_COMP
*(p++)=0;
#else
if (s->s3->tmp.new_compression == NULL)
*(p++)=0;
else
*(p++)=s->s3->tmp.new_compression->id;
#ifndef OPENSSL_NO_TLSEXT
if (ssl_prepare_serverhello_tlsext(s) <= 0)
{
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
return -1;
}
if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
{
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
return -1;
}
/* do the header */
l=(p-d);
d=buf;
*(d++)=SSL3_MT_SERVER_HELLO;
l2n3(l,d);
/* number of bytes to write */
s->init_num=p-buf;
s->init_off=0;
}
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
}
{
unsigned char *p;
if (s->state == SSL3_ST_SW_SRVR_DONE_A)
{
p=(unsigned char *)s->init_buf->data;
/* do the header */
*(p++)=SSL3_MT_SERVER_DONE;
*(p++)=0;
*(p++)=0;
*(p++)=0;
s->state=SSL3_ST_SW_SRVR_DONE_B;
/* number of bytes to write */
s->init_num=4;
s->init_off=0;
}
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
}
#ifndef OPENSSL_NO_RSA
unsigned char *q;
int j,num;
RSA *rsa;
unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
#ifndef OPENSSL_NO_DH
DH *dh=NULL,*dhp;
#endif
#ifndef OPENSSL_NO_ECDH
EC_KEY *ecdh=NULL, *ecdhp;
unsigned char *encodedPoint = NULL;
int encodedlen = 0;
int curve_id = 0;
BN_CTX *bn_ctx = NULL;
#endif
EVP_PKEY *pkey;
unsigned char *p,*d;
int al,i;
unsigned long type;
int n;
CERT *cert;
BIGNUM *r[4];
int nr[4],kn;
BUF_MEM *buf;
EVP_MD_CTX md_ctx;
if (s->state == SSL3_ST_SW_KEY_EXCH_A)
{
type=s->s3->tmp.new_cipher->algorithm_mkey;
cert=s->cert;
buf=s->init_buf;
r[0]=r[1]=r[2]=r[3]=NULL;
n=0;
#ifndef OPENSSL_NO_RSA
if (type & SSL_kRSA)
{
rsa=cert->rsa_tmp;
if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))
rsa=s->cert->rsa_tmp_cb(s,
SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
if(rsa == NULL)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
goto f_err;
}
RSA_up_ref(rsa);
cert->rsa_tmp=rsa;
}
if (rsa == NULL)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);
goto f_err;
}
r[0]=rsa->n;
r[1]=rsa->e;
s->s3->tmp.use_rsa_tmp=1;
}
else
#endif
#ifndef OPENSSL_NO_DH
if (type & SSL_kEDH)
{
dhp=cert->dh_tmp;
if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
dhp=s->cert->dh_tmp_cb(s,
SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
if (dhp == NULL)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
goto f_err;
}
if (s->s3->tmp.dh != NULL)
{
DH_free(dh);
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto err;
}
if ((dh=DHparams_dup(dhp)) == NULL)
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
goto err;
}
s->s3->tmp.dh=dh;
if ((dhp->pub_key == NULL ||
dhp->priv_key == NULL ||
(s->options & SSL_OP_SINGLE_DH_USE)))
if(!DH_generate_key(dh))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
ERR_R_DH_LIB);
goto err;
}
}
else
{
dh->pub_key=BN_dup(dhp->pub_key);
dh->priv_key=BN_dup(dhp->priv_key);
if ((dh->pub_key == NULL) ||
(dh->priv_key == NULL))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
goto err;
}
}
r[0]=dh->p;
r[1]=dh->g;
r[2]=dh->pub_key;
}
else
#endif
if (type & SSL_kEECDH)
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
ecdhp=cert->ecdh_tmp;
if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL))
{
ecdhp=s->cert->ecdh_tmp_cb(s,
SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
}
if (ecdhp == NULL)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
goto f_err;
}
if (s->s3->tmp.ecdh != NULL)
{
EC_KEY_free(s->s3->tmp.ecdh);
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto err;
}
/* Duplicate the ECDH structure. */
if (ecdhp == NULL)
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
goto err;
}
if (!EC_KEY_up_ref(ecdhp))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
goto err;
}
ecdh = ecdhp;
s->s3->tmp.ecdh=ecdh;
if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
(EC_KEY_get0_private_key(ecdh) == NULL) ||
(s->options & SSL_OP_SINGLE_ECDH_USE))
{
if(!EC_KEY_generate_key(ecdh))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
goto err;
}
}
if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
(EC_KEY_get0_public_key(ecdh) == NULL) ||
(EC_KEY_get0_private_key(ecdh) == NULL))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
goto err;
}
if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
goto err;
}
/* XXX: For now, we only support ephemeral ECDH
* keys over named (not generic) curves. For
* supported named curves, curve_id is non-zero.
*/
if ((curve_id =
tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
== 0)
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
goto err;
}
/* Encode the public key.
* First check the size of encoding and
* allocate memory accordingly.
*/
encodedlen = EC_POINT_point2oct(group,
EC_KEY_get0_public_key(ecdh),
POINT_CONVERSION_UNCOMPRESSED,
NULL, 0, NULL);
encodedPoint = (unsigned char *)
OPENSSL_malloc(encodedlen*sizeof(unsigned char));
bn_ctx = BN_CTX_new();
if ((encodedPoint == NULL) || (bn_ctx == NULL))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
goto err;
}
encodedlen = EC_POINT_point2oct(group,
EC_KEY_get0_public_key(ecdh),
POINT_CONVERSION_UNCOMPRESSED,
encodedPoint, encodedlen, bn_ctx);
if (encodedlen == 0)
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
goto err;
}
BN_CTX_free(bn_ctx); bn_ctx=NULL;
/* XXX: For now, we only support named (not
* generic) curves in ECDH ephemeral key exchanges.
* to encode the entire ServerECDHParams
* structure.
*/
/* We'll generate the serverKeyExchange message
* explicitly so we can set these to NULLs
*/
r[0]=NULL;
r[1]=NULL;
r[2]=NULL;
#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 */
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
goto f_err;
}
for (i=0; r[i] != NULL; i++)
{
nr[i]=BN_num_bytes(r[i]);
n+=2+nr[i];
}
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
{
if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
== NULL)
{
al=SSL_AD_DECODE_ERROR;
goto f_err;
}
kn=EVP_PKEY_size(pkey);
}
else
{
pkey=NULL;
kn=0;
}
if (!BUF_MEM_grow_clean(buf,n+4+kn))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
goto err;
}
d=(unsigned char *)s->init_buf->data;
p= &(d[4]);
for (i=0; r[i] != NULL; i++)
{
s2n(nr[i],p);
BN_bn2bin(r[i],p);
p+=nr[i];
}
if (type & SSL_kEECDH)
{
/* XXX: For now, we only support named (not generic) curves.
* In this situation, the serverKeyExchange message has:
* [1 byte length of encoded point], followed by
* the actual encoded point itself
*/
*p = NAMED_CURVE_TYPE;
p += 1;
*p = curve_id;
p += 1;
*p = encodedlen;
p += 1;
memcpy((unsigned char*)p,
(unsigned char *)encodedPoint,
encodedlen);
OPENSSL_free(encodedPoint);
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
/* not anonymous */
if (pkey != NULL)
{
/* n is the length of the params, they start at &(d[4])
* and p points to the space at the end. */
#ifndef OPENSSL_NO_RSA
if (pkey->type == EVP_PKEY_RSA)
{
q=md_buf;
j=0;
for (num=2; num > 0; num--)
{
EVP_DigestInit_ex(&md_ctx,(num == 2)
?s->ctx->md5:s->ctx->sha1, NULL);
EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_DigestUpdate(&md_ctx,&(d[4]),n);
(unsigned int *)&i);
q+=i;
j+=i;
}
Dr. Stephen Henson
committed
if (RSA_sign(NID_md5_sha1, md_buf, j,
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
goto err;
}
}
else
#endif
#if !defined(OPENSSL_NO_DSA)
if (pkey->type == EVP_PKEY_DSA)
{
/* lets do DSS */
EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_SignUpdate(&md_ctx,&(d[4]),n);
if (!EVP_SignFinal(&md_ctx,&(p[2]),
(unsigned int *)&i,pkey))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
goto err;
}
s2n(i,p);
n+=i+2;
}
else
if (pkey->type == EVP_PKEY_EC)
{
/* let's do ECDSA */
EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_SignUpdate(&md_ctx,&(d[4]),n);
if (!EVP_SignFinal(&md_ctx,&(p[2]),
(unsigned int *)&i,pkey))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA);
goto err;
}
s2n(i,p);
n+=i+2;
}
else
#endif
{
/* Is this error check actually needed? */
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);
goto f_err;
}
}
*(d++)=SSL3_MT_SERVER_KEY_EXCHANGE;
l2n3(n,d);
/* we should now have things packed up, so lets send
* it off */
s->init_num=n+4;
s->init_off=0;
}
s->state = SSL3_ST_SW_KEY_EXCH_B;
EVP_MD_CTX_cleanup(&md_ctx);
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
#ifndef OPENSSL_NO_ECDH
if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
BN_CTX_free(bn_ctx);
#endif
EVP_MD_CTX_cleanup(&md_ctx);
return(-1);
}
{
unsigned char *p,*d;
int i,j,nl,off,n;
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
X509_NAME *name;
BUF_MEM *buf;
if (s->state == SSL3_ST_SW_CERT_REQ_A)
{
buf=s->init_buf;
d=p=(unsigned char *)&(buf->data[4]);
/* get the list of acceptable cert types */
p++;
n=ssl3_get_req_cert_type(s,p);
d[0]=n;
p+=n;
n++;
off=n;
p+=2;
n+=2;
sk=SSL_get_client_CA_list(s);
nl=0;
if (sk != NULL)
{
j=i2d_X509_NAME(name,NULL);
if (!BUF_MEM_grow_clean(buf,4+n+j+2))
{
SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
goto err;
}
p=(unsigned char *)&(buf->data[4+n]);
if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
{
s2n(j,p);
i2d_X509_NAME(name,&p);
n+=2+j;
nl+=2+j;
}
else
{
d=p;
i2d_X509_NAME(name,&p);
j-=2; s2n(j,d); j+=2;
n+=j;
nl+=j;
}
}
}
/* else no CA names */
p=(unsigned char *)&(buf->data[4+off]);
s2n(nl,p);
d=(unsigned char *)buf->data;
*(d++)=SSL3_MT_CERTIFICATE_REQUEST;
l2n3(n,d);
/* we should now have things packed up, so lets send
* it off */
s->init_num=n+4;
s->init_off=0;
#ifdef NETSCAPE_HANG_BUG
p=(unsigned char *)s->init_buf->data + s->init_num;
/* do the header */
*(p++)=SSL3_MT_SERVER_DONE;
*(p++)=0;
*(p++)=0;
*(p++)=0;
s->init_num += 4;
#endif
Richard Levitte
committed
s->state = SSL3_ST_SW_CERT_REQ_B;
}
/* SSL3_ST_SW_CERT_REQ_B */
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
err:
return(-1);
}
{
int i,al,ok;
long n;
unsigned long alg_k;
#ifndef OPENSSL_NO_RSA
RSA *rsa=NULL;
EVP_PKEY *pkey=NULL;
#ifndef OPENSSL_NO_DH
#ifndef OPENSSL_NO_KRB5
KSSL_ERR kssl_err;
#endif /* OPENSSL_NO_KRB5 */
#ifndef OPENSSL_NO_ECDH
EC_KEY *srvr_ecdh = NULL;
EVP_PKEY *clnt_pub_pkey = NULL;
EC_POINT *clnt_ecpoint = NULL;
BN_CTX *bn_ctx = NULL;
#endif
SSL3_ST_SR_KEY_EXCH_A,
SSL3_ST_SR_KEY_EXCH_B,
SSL3_MT_CLIENT_KEY_EXCHANGE,
&ok);
if (!ok) return((int)n);
p=(unsigned char *)s->init_msg;
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA)
{
/* FIX THIS UP EAY EAY EAY EAY */
if (s->s3->tmp.use_rsa_tmp)
{
if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
rsa=s->cert->rsa_tmp;
/* Don't do a callback because rsa_tmp should
* be sent already */
if (rsa == NULL)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_PKEY);
goto f_err;
}
}
else
{
pkey=s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
if ( (pkey == NULL) ||
(pkey->type != EVP_PKEY_RSA) ||
(pkey->pkey.rsa == NULL))
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_RSA_CERTIFICATE);
goto f_err;
}
rsa=pkey->pkey.rsa;
}
/* TLS and [incidentally] DTLS{0xFEFF} */
if (s->version > SSL3_VERSION)
{
n2s(p,i);
if (n != i+2)
{
if (!(s->options & SSL_OP_TLS_D5_BUG))
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
goto err;
}
else
p-=2;
}
else
n=i;
}
i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
if (i != SSL_MAX_MASTER_KEY_LENGTH)
{
al=SSL_AD_DECODE_ERROR;
/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
/* The premaster secret must contain the same version number as the
* ClientHello to detect version rollback attacks (strangely, the
* protocol does not offer such protection for DH ciphersuites).
* However, buggy clients exist that send the negotiated protocol
* protocol version.
* If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
(p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
{
al=SSL_AD_DECODE_ERROR;
/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
/* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
* (http://eprint.iacr.org/2003/052/) exploits the version
* number check as a "bad version oracle" -- an alert would
* reveal that the plaintext corresponding to some ciphertext
* made up by the adversary is properly formatted except
* that the version number is wrong. To avoid such attacks,
* we should treat this just like any other decryption error. */
if (al != -1)
{
/* Some decryption failure -- use random value instead as countermeasure
* against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
* (see RFC 2246, section 7.4.7.1). */
ERR_clear_error();
i = SSL_MAX_MASTER_KEY_LENGTH;
p[0] = s->client_version >> 8;
p[1] = s->client_version & 0xff;
if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
goto err;
s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,
p,i);
OPENSSL_cleanse(p,i);
#ifndef OPENSSL_NO_DH
if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
{
n2s(p,i);
if (n != i+2)
{
if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG))