X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=ssl%2Fs3_both.c;h=be766aac6ab78993dda237c39883b413c9ee52bc;hb=f55f5f775e69f853e8753aff94ee621ba14af40c;hp=d757c4dd58e0cc1af2cc9951a64bfddcdcc05436;hpb=70dc09ebe439f181e8472b2a8dcd4092591b5db4;p=openssl.git diff --git a/ssl/s3_both.c b/ssl/s3_both.c index d757c4dd58..be766aac6a 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -166,6 +166,23 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) p+=i; l=i; + /* Copy the finished so we can use it for + renegotiation checks */ + if(s->type == SSL_ST_CONNECT) + { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_client_finished, + s->s3->tmp.finish_md, i); + s->s3->previous_client_finished_len=i; + } + else + { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_server_finished, + s->s3->tmp.finish_md, i); + s->s3->previous_server_finished_len=i; + } + #ifdef OPENSSL_SYS_WIN16 /* MSVC 1.5 does not clear the top bytes of the word unless * I do this. @@ -185,15 +202,40 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } +#ifndef OPENSSL_NO_NEXTPROTONEG +/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */ +static void ssl3_take_mac(SSL *s) + { + const char *sender; + int slen; + + if (s->state & SSL_ST_CONNECT) + { + sender=s->method->ssl3_enc->server_finished_label; + slen=s->method->ssl3_enc->server_finished_label_len; + } + else + { + sender=s->method->ssl3_enc->client_finished_label; + slen=s->method->ssl3_enc->client_finished_label_len; + } + + s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, + sender,slen,s->s3->tmp.peer_finish_md); + } +#endif + int ssl3_get_finished(SSL *s, int a, int b) { int al,i,ok; long n; unsigned char *p; +#ifdef OPENSSL_NO_NEXTPROTONEG /* the mac has already been generated when we received the * change cipher spec message and is in s->s3->tmp.peer_finish_md */ +#endif n=s->method->ssl_get_message(s, a, @@ -230,6 +272,23 @@ int ssl3_get_finished(SSL *s, int a, int b) goto f_err; } + /* Copy the finished so we can use it for + renegotiation checks */ + if(s->type == SSL_ST_ACCEPT) + { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_client_finished, + s->s3->tmp.peer_finish_md, i); + s->s3->previous_client_finished_len=i; + } + else + { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_server_finished, + s->s3->tmp.peer_finish_md, i); + s->s3->previous_server_finished_len=i; + } + return(1); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); @@ -318,6 +377,8 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x) return(0); } X509_verify_cert(&xs_ctx); + /* Don't leave errors in the queue */ + ERR_clear_error(); for (i=0; i < sk_X509_num(xs_ctx.chain); i++) { x = sk_X509_value(xs_ctx.chain, i); @@ -478,6 +539,15 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) s->init_num += i; n -= i; } + +#ifndef OPENSSL_NO_NEXTPROTONEG + /* If receiving Finished, record MAC of prior handshake messages for + * Finished verification. */ + if (*s->init_buf->data == SSL3_MT_FINISHED) + ssl3_take_mac(s); +#endif + + /* Feed this message into MAC computation. */ ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4); if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);