diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index 1ccdc35e4db01a3273a5ddef5b5c754716297b9d..55d37e78b05775c35b12e3077e353c6acd9a3ada 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c @@ -655,17 +655,19 @@ int dtls1_accept(SSL *s) s->init_num = 0; if (!s->session->peer) break; - /* - * For sigalgs freeze the handshake buffer at this point and - * digest cached records. - */ if (!s->s3->handshake_buffer) { SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); return -1; } - s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; - if (!ssl3_digest_cached_records(s)) - return -1; + /* + * For sigalgs freeze the handshake buffer. If we support + * extms we've done this already. + */ + if (!(s->s3->flags & SSL_SESS_FLAG_EXTMS)) { + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + if (!ssl3_digest_cached_records(s)) + return -1; + } } else { s->state = SSL3_ST_SR_CERT_VRFY_A; s->init_num = 0; diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index a90c9f9a6e482f9012e7c6801605673d85302860..5e2b543e6b8d703ab7ffce91ef90928b01a97b01 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -3150,7 +3150,15 @@ int ssl3_send_client_verify(SSL *s) } s2n(u, p); n = u + 4; - if (!ssl3_digest_cached_records(s)) + /* + * For extended master secret we've already digested cached + * records. + */ + if (s->session->flags & SSL_SESS_FLAG_EXTMS) { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; + } else if (!ssl3_digest_cached_records(s)) goto err; } else #ifndef OPENSSL_NO_RSA diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index e92965879871a06e1ff0e80d6c490f72aec8c7d2..f31b76a96ab9f1e4c19c7b208782af94cbc013e7 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -620,17 +620,19 @@ int ssl3_accept(SSL *s) s->init_num = 0; if (!s->session->peer) break; - /* - * For sigalgs freeze the handshake buffer at this point and - * digest cached records. - */ if (!s->s3->handshake_buffer) { SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); return -1; } - s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; - if (!ssl3_digest_cached_records(s)) - return -1; + /* + * For sigalgs freeze the handshake buffer. If we support + * extms we've done this already. + */ + if (!(s->s3->flags & SSL_SESS_FLAG_EXTMS)) { + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + if (!ssl3_digest_cached_records(s)) + return -1; + } } else { int offset = 0; int dgst_num; diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 666864e85c72c3c8049e6b140cb70b10174b3b8b..ff6273f1503196e664b7a1dc0c31317214cb7435 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -1070,13 +1070,41 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, len); #endif /* KSSL_DEBUG */ - - tls1_PRF(ssl_get_algorithm2(s), - TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, - s->s3->client_random, SSL3_RANDOM_SIZE, - co, col, - s->s3->server_random, SSL3_RANDOM_SIZE, - so, sol, p, len, s->session->master_key, buff, sizeof buff); + if (s->session->flags & SSL_SESS_FLAG_EXTMS) { + unsigned char hash[EVP_MAX_MD_SIZE * 2]; + int hashlen; + /* If we don't have any digests cache records */ + if (s->s3->handshake_buffer) { + /* + * keep record buffer: this wont affect client auth because we're + * freezing the buffer at the same point (after client key + * exchange and before certificate verify) + */ + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + ssl3_digest_cached_records(s); + } + hashlen = ssl_handshake_hash(s, hash, sizeof(hash)); +#ifdef SSL_DEBUG + fprintf(stderr, "Handshake hashes:\n"); + BIO_dump_fp(stderr, (char *)hash, hashlen); +#endif + tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_EXTENDED_MASTER_SECRET_CONST, + TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, + hash, hashlen, + co, col, + NULL, 0, + so, sol, p, len, s->session->master_key, buff, sizeof buff); + OPENSSL_cleanse(hash, hashlen); + } else { + tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_MASTER_SECRET_CONST, + TLS_MD_MASTER_SECRET_CONST_SIZE, + s->s3->client_random, SSL3_RANDOM_SIZE, + co, col, + s->s3->server_random, SSL3_RANDOM_SIZE, + so, sol, p, len, s->session->master_key, buff, sizeof buff); + } #ifdef SSL_DEBUG fprintf(stderr, "Premaster Secret:\n"); BIO_dump_fp(stderr, (char *)p, len); @@ -1175,6 +1203,9 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, if (memcmp(val, TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) goto err1; + if (memcmp(val, TLS_MD_EXTENDED_MASTER_SECRET_CONST, + TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE) == 0) + goto err1; if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1; diff --git a/ssl/tls1.h b/ssl/tls1.h index b33c917e33d2d11e0d50e33021532a6712a69cb0..af03f13938ad12e09cd3c891f443a981a8432fb7 100644 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -782,7 +782,7 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) # define TLS1_FINISH_MAC_LENGTH 12 -# define TLS_MD_MAX_CONST_SIZE 20 +# define TLS_MD_MAX_CONST_SIZE 22 # define TLS_MD_CLIENT_FINISH_CONST "client finished" # define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 # define TLS_MD_SERVER_FINISH_CONST "server finished" @@ -797,6 +797,8 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) # define TLS_MD_IV_BLOCK_CONST_SIZE 8 # define TLS_MD_MASTER_SECRET_CONST "master secret" # define TLS_MD_MASTER_SECRET_CONST_SIZE 13 +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "extended master secret" +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE 22 # ifdef CHARSET_EBCDIC # undef TLS_MD_CLIENT_FINISH_CONST @@ -846,6 +848,11 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) * master secret */ # define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# undef TLS_MD_EXTENDED_MASTER_SECRET_CONST +/* + * extended master secret + */ +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "\x65\x78\x74\x65\x63\x64\x65\x64\x20\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" # endif /* TLS Session Ticket extension struct */