*** openssl/ssl/s3_clnt.c Fri Apr 28 11:01:13 2000 --- privador/src/openssl/ssl/s3_clnt.c Tue Jun 6 15:20:44 2000 *************** *** 1302,1307 **** --- 1302,1340 ---- return(ret); } + /* compares two DHparams. returns 0 if they are equal */ + static int DHparams_cmp(DH* a, DH* b) + { + int lena; + int lenb; + unsigned char* ptra= 0; + unsigned char* ptrb= 0; + unsigned char* p; + int retval= 1; + + lena= i2d_DHparams(a, NULL); + lenb= i2d_DHparams(b, NULL); + if(lena != lenb) + goto err; + if((ptra= (unsigned char *)Malloc(lena)) == NULL) + goto err; + if((ptrb= (unsigned char *)Malloc(lenb)) == NULL) + goto err; + p= ptra; + i2d_DHparams(a, &p); + p= ptrb; + i2d_DHparams(b, &p); + if(memcmp(ptra, ptrb, lena) == 0) + retval= 0; + + err: + if(ptra) + Free(ptra); + if(ptrb) + Free(ptrb); + return(retval); + } + static int ssl3_send_client_key_exchange(SSL *s) { unsigned char *p,*d; *************** *** 1311,1316 **** --- 1344,1352 ---- unsigned char *q; EVP_PKEY *pkey=NULL; #endif + #ifndef NO_DH + DH* dhp; + #endif if (s->state == SSL3_ST_CW_KEY_EXCH_A) { *************** *** 1394,1436 **** goto err; } ! /* generate a new random key */ ! if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) { ! SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); ! goto err; } ! if (!DH_generate_key(dh_clnt)) { ! SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); ! goto err; ! } ! /* use the 'p' output buffer for the DH key, but ! * make sure to clear it out afterwards */ ! n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt); ! if (n <= 0) ! { ! SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); ! 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); ! /* clean up */ ! memset(p,0,n); ! ! /* send off the data */ ! n=BN_num_bytes(dh_clnt->pub_key); ! s2n(n,p); ! BN_bn2bin(dh_clnt->pub_key,p); ! n+=2; ! DH_free(dh_clnt); /* perhaps clean things up a bit EAY EAY EAY EAY*/ } --- 1430,1517 ---- goto err; } ! /* if client nows server's DH parameters in advance he ! can pregenerate DH key. we try to get pregenerated DH key ! like server does and then compare parameters. if parameters ! match, we duplicate existing key and use it. if not, we ! generate new key using parameters which server sent. ! ! this is useful when one client connects many servers and ! DH parameters for system centraly managed */ ! ! dhp=s->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 && dhp->pub_key != NULL && dhp->priv_key != NULL && ! DHparams_cmp(dhp, dh_srvr) == 0) { ! /* use the 'p' output buffer for the DH key, but ! * make sure to clear it out afterwards */ ! ! n=DH_compute_key(p,dh_srvr->pub_key,dhp); ! ! if (n <= 0) ! { ! SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); ! 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); ! /* clean up */ ! memset(p,0,n); ! ! /* send off the data */ ! n=BN_num_bytes(dhp->pub_key); ! s2n(n,p); ! BN_bn2bin(dhp->pub_key,p); ! n+=2; } ! else { ! /* generate a new random key */ ! if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) ! { ! SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); ! goto err; ! } ! if (!DH_generate_key(dh_clnt)) ! { ! SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); ! goto err; ! } ! /* use the 'p' output buffer for the DH key, but ! * make sure to clear it out afterwards */ ! n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt); ! if (n <= 0) ! { ! SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); ! 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); ! /* clean up */ ! memset(p,0,n); ! ! /* send off the data */ ! n=BN_num_bytes(dh_clnt->pub_key); ! s2n(n,p); ! BN_bn2bin(dh_clnt->pub_key,p); ! n+=2; ! DH_free(dh_clnt); ! } /* perhaps clean things up a bit EAY EAY EAY EAY*/ }