X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Fs2_clnt.c;h=33ea7592c489b72847a91241550c69fdb11f70e3;hb=1385ddbb14286dba10e0cca41546986ffc8ea645;hp=3a990e42cc68eb3972e53e8a6497abd47f0e0603;hpb=cf82191d77a0a8f77894a65185b6f7a4b3855d6c;p=openssl.git diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c index 3a990e42cc..33ea7592c4 100644 --- a/ssl/s2_clnt.c +++ b/ssl/s2_clnt.c @@ -144,11 +144,18 @@ SSL_METHOD *SSLv2_client_method(void) if (init) { - memcpy((char *)&SSLv2_client_data,(char *)sslv2_base_method(), - sizeof(SSL_METHOD)); - SSLv2_client_data.ssl_connect=ssl2_connect; - SSLv2_client_data.get_ssl_method=ssl2_get_client_method; - init=0; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&SSLv2_client_data,(char *)sslv2_base_method(), + sizeof(SSL_METHOD)); + SSLv2_client_data.ssl_connect=ssl2_connect; + SSLv2_client_data.get_ssl_method=ssl2_get_client_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } return(&SSLv2_client_data); } @@ -158,7 +165,7 @@ int ssl2_connect(SSL *s) unsigned long l=time(NULL); BUF_MEM *buf=NULL; int ret= -1; - void (*cb)()=NULL; + void (*cb)(const SSL *ssl,int type,int val)=NULL; int new_state,state; RAND_add(&l,sizeof(l),0); @@ -200,10 +207,13 @@ int ssl2_connect(SSL *s) if (!BUF_MEM_grow(buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { + if (buf == s->init_buf) + buf=NULL; ret= -1; goto end; } s->init_buf=buf; + buf=NULL; s->init_num=0; s->state=SSL2_ST_SEND_CLIENT_HELLO_A; s->ctx->stats.sess_connect++; @@ -330,6 +340,8 @@ int ssl2_connect(SSL *s) } end: s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); if (cb != NULL) cb(s,SSL_CB_CONNECT_EXIT,ret); return(ret); @@ -535,6 +547,12 @@ static int get_server_hello(SSL *s) } s->s2->conn_id_length=s->s2->tmp.conn_id_length; + if (s->s2->conn_id_length > sizeof s->s2->conn_id) + { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG); + return -1; + } memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length); return(1); } @@ -566,7 +584,7 @@ static int client_hello(SSL *s) s2n(SSL2_VERSION,p); /* version */ n=j=0; - n=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),d); + n=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),d,0); d+=n; if (n == 0) @@ -594,7 +612,8 @@ static int client_hello(SSL *s) s->s2->challenge_length=SSL2_CHALLENGE_LENGTH; s2n(SSL2_CHALLENGE_LENGTH,p); /* challenge length */ /*challenge id data*/ - RAND_pseudo_bytes(s->s2->challenge,SSL2_CHALLENGE_LENGTH); + if (RAND_pseudo_bytes(s->s2->challenge,SSL2_CHALLENGE_LENGTH) <= 0) + return -1; memcpy(d,s->s2->challenge,SSL2_CHALLENGE_LENGTH); d+=SSL2_CHALLENGE_LENGTH; @@ -636,13 +655,27 @@ static int client_master_key(SSL *s) /* make key_arg data */ i=EVP_CIPHER_iv_length(c); sess->key_arg_length=i; - if (i > 0) RAND_pseudo_bytes(sess->key_arg,i); + if (i > SSL_MAX_KEY_ARG_LENGTH) + { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + if (i > 0) + if (RAND_pseudo_bytes(sess->key_arg,i) <= 0) + return -1; /* make a master key */ i=EVP_CIPHER_key_length(c); sess->master_key_length=i; if (i > 0) { + if (i > (int)sizeof(sess->master_key)) + { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } if (RAND_bytes(sess->master_key,i) <= 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); @@ -657,7 +690,7 @@ static int client_master_key(SSL *s) else enc=i; - if (i < enc) + if ((int)i < enc) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_CIPHER_TABLE_SRC_ERROR); @@ -686,6 +719,12 @@ static int client_master_key(SSL *s) d+=enc; karg=sess->key_arg_length; s2n(karg,p); /* key arg size */ + if (karg > (int)sizeof(sess->key_arg)) + { + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } memcpy(d,sess->key_arg,(unsigned int)karg); d+=karg; @@ -706,6 +745,11 @@ static int client_finished(SSL *s) { p=(unsigned char *)s->init_buf->data; *(p++)=SSL2_MT_CLIENT_FINISHED; + if (s->s2->conn_id_length > sizeof s->s2->conn_id) + { + SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); + return -1; + } memcpy(p,s->s2->conn_id,(unsigned int)s->s2->conn_id_length); s->state=SSL2_ST_SEND_CLIENT_FINISHED_B; @@ -733,8 +777,8 @@ static int client_certificate(SSL *s) if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A) { i=ssl2_read(s,(char *)&(buf[s->init_num]), - SSL2_MAX_CERT_CHALLENGE_LENGTH+1-s->init_num); - if (i<(SSL2_MIN_CERT_CHALLENGE_LENGTH+1-s->init_num)) + SSL2_MAX_CERT_CHALLENGE_LENGTH+2-s->init_num); + if (i<(SSL2_MIN_CERT_CHALLENGE_LENGTH+2-s->init_num)) return(ssl2_part_read(s,SSL_F_CLIENT_CERTIFICATE,i)); s->init_num += i; if (s->msg_callback) @@ -834,7 +878,7 @@ static int client_certificate(SSL *s) EVP_MD_CTX_init(&ctx); EVP_SignInit_ex(&ctx,s->ctx->rsa_md5, NULL); EVP_SignUpdate(&ctx,s->s2->key_material, - (unsigned int)s->s2->key_material_length); + s->s2->key_material_length); EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len); n=i2d_X509(s->session->sess_cert->peer_key->x509,&p); EVP_SignUpdate(&ctx,buf,(unsigned int)n); @@ -873,8 +917,8 @@ static int get_server_verify(SSL *s) p=(unsigned char *)s->init_buf->data; if (s->state == SSL2_ST_GET_SERVER_VERIFY_A) { - i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num); - if (i < (3-s->init_num)) + i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num); + if (i < (1-s->init_num)) return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i)); s->init_num += i; @@ -888,8 +932,12 @@ static int get_server_verify(SSL *s) SSL_R_READ_WRONG_PACKET_TYPE); } else - SSLerr(SSL_F_GET_SERVER_VERIFY, - SSL_R_PEER_ERROR); + { + SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_PEER_ERROR); + /* try to read the error message */ + i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num); + return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i); + } return(-1); } } @@ -904,7 +952,7 @@ static int get_server_verify(SSL *s) s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */ p += 1; - if (memcmp(p,s->s2->challenge,(unsigned int)s->s2->challenge_length) != 0) + if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT); @@ -923,8 +971,8 @@ static int get_server_finished(SSL *s) p=buf; if (s->state == SSL2_ST_GET_SERVER_FINISHED_A) { - i=ssl2_read(s,(char *)&(buf[s->init_num]),3-s->init_num); - if (i < (3-s->init_num)) + i=ssl2_read(s,(char *)&(buf[s->init_num]),1-s->init_num); + if (i < (1-s->init_num)) return(ssl2_part_read(s,SSL_F_GET_SERVER_FINISHED,i)); s->init_num += i; @@ -941,7 +989,12 @@ static int get_server_finished(SSL *s) SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE); } else + { SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_PEER_ERROR); + /* try to read the error message */ + i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num); + return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i); + } return(-1); } s->state=SSL2_ST_GET_SERVER_FINISHED_B; @@ -963,14 +1016,15 @@ static int get_server_finished(SSL *s) * or bad things can happen */ /* ZZZZZZZZZZZZZ */ s->session->session_id_length=SSL2_SSL_SESSION_ID_LENGTH; - memcpy(s->session->session_id,p,SSL2_SSL_SESSION_ID_LENGTH); + memcpy(s->session->session_id,p+1,SSL2_SSL_SESSION_ID_LENGTH); } else { if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG)) { - if (memcmp(buf,s->session->session_id, - (unsigned int)s->session->session_id_length) != 0) + if ((s->session->session_id_length > sizeof s->session->session_id) + || (0 != memcmp(buf + 1, s->session->session_id, + (unsigned int)s->session->session_id_length))) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_SSL_SESSION_ID_IS_DIFFERENT); @@ -983,7 +1037,7 @@ static int get_server_finished(SSL *s) } /* loads in the certificate from the server */ -int ssl2_set_certificate(SSL *s, int type, int len, unsigned char *data) +int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data) { STACK_OF(X509) *sk=NULL; EVP_PKEY *pkey=NULL;