X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=src%2Fssl%2Fssl_engine.c;h=529b10733b24ea204c210a1db541bb85ab3d5fd4;hp=32bc406269151d1e839d7da1c622a1a6c606e93f;hb=4aac1cd5c65462d5ad13e377705a00eab8c80d81;hpb=d16eee962a72a600c370f18f2ae25b36b4f532df diff --git a/src/ssl/ssl_engine.c b/src/ssl/ssl_engine.c index 32bc406..529b107 100644 --- a/src/ssl/ssl_engine.c +++ b/src/ssl/ssl_engine.c @@ -1091,6 +1091,9 @@ jump_handshake(br_ssl_engine_context *cc, int action) cc->hlen_out = hlen_out; cc->action = action; cc->hsrun(&cc->cpu); + if (br_ssl_engine_closed(cc)) { + return; + } if (cc->hbuf_out != cc->saved_hbuf_out) { sendpld_ack(cc, cc->hbuf_out - cc->saved_hbuf_out); } @@ -1129,7 +1132,7 @@ br_ssl_engine_flush_record(br_ssl_engine_context *cc) unsigned char * br_ssl_engine_sendapp_buf(const br_ssl_engine_context *cc, size_t *len) { - if (!cc->application_data) { + if (!(cc->application_data & 1)) { *len = 0; return NULL; } @@ -1147,7 +1150,7 @@ br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len) unsigned char * br_ssl_engine_recvapp_buf(const br_ssl_engine_context *cc, size_t *len) { - if (!cc->application_data + if (!(cc->application_data & 1) || cc->record_type_in != BR_SSL_APPLICATION_DATA) { *len = 0; @@ -1177,7 +1180,7 @@ br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len) sendrec_ack(cc, len); if (len != 0 && !has_rec_tosend(cc) && (cc->record_type_out != BR_SSL_APPLICATION_DATA - || cc->application_data == 0)) + || (cc->application_data & 1) == 0)) { jump_handshake(cc, 0); } @@ -1215,9 +1218,20 @@ br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len) jump_handshake(cc, 0); break; case BR_SSL_APPLICATION_DATA: - if (cc->application_data) { + if (cc->application_data == 1) { + break; + } + + /* + * If we are currently closing, and waiting for + * a close_notify from the peer, then incoming + * application data should be discarded. + */ + if (cc->application_data == 2) { + recvpld_ack(cc, len); break; } + /* Fall through */ default: br_ssl_engine_fail(cc, BR_ERR_UNEXPECTED); @@ -1239,8 +1253,11 @@ br_ssl_engine_close(br_ssl_engine_context *cc) int br_ssl_engine_renegotiate(br_ssl_engine_context *cc) { + size_t len; + if (br_ssl_engine_closed(cc) || cc->reneg == 1 - || (cc->flags & BR_OPT_NO_RENEGOTIATION) != 0) + || (cc->flags & BR_OPT_NO_RENEGOTIATION) != 0 + || br_ssl_engine_recvapp_buf(cc, &len) != NULL) { return 0; } @@ -1279,7 +1296,7 @@ br_ssl_engine_current_state(const br_ssl_engine_context *cc) void br_ssl_engine_flush(br_ssl_engine_context *cc, int force) { - if (!br_ssl_engine_closed(cc) && cc->application_data) { + if (!br_ssl_engine_closed(cc) && (cc->application_data & 1) != 0) { sendpld_flush(cc, force); } } @@ -1296,6 +1313,7 @@ br_ssl_engine_hs_reset(br_ssl_engine_context *cc, cc->hsrun = hsrun; cc->shutdown_recv = 0; cc->application_data = 0; + cc->alert = 0; jump_handshake(cc, 0); } @@ -1320,13 +1338,14 @@ br_ssl_engine_compute_master(br_ssl_engine_context *cc, int prf_id, const void *pms, size_t pms_len) { br_tls_prf_impl iprf; - unsigned char seed[64]; + br_tls_prf_seed_chunk seed[2] = { + { cc->client_random, sizeof cc->client_random }, + { cc->server_random, sizeof cc->server_random } + }; iprf = br_ssl_engine_get_PRF(cc, prf_id); - memcpy(seed, cc->client_random, 32); - memcpy(seed + 32, cc->server_random, 32); iprf(cc->session.master_secret, sizeof cc->session.master_secret, - pms, pms_len, "master secret", seed, sizeof seed); + pms, pms_len, "master secret", 2, seed); } /* @@ -1337,14 +1356,15 @@ compute_key_block(br_ssl_engine_context *cc, int prf_id, size_t half_len, unsigned char *kb) { br_tls_prf_impl iprf; - unsigned char seed[64]; + br_tls_prf_seed_chunk seed[2] = { + { cc->server_random, sizeof cc->server_random }, + { cc->client_random, sizeof cc->client_random } + }; iprf = br_ssl_engine_get_PRF(cc, prf_id); - memcpy(seed, cc->server_random, 32); - memcpy(seed + 32, cc->client_random, 32); iprf(kb, half_len << 1, cc->session.master_secret, sizeof cc->session.master_secret, - "key expansion", seed, sizeof seed); + "key expansion", 2, seed); } /* see inner.h */ @@ -1474,3 +1494,44 @@ br_ssl_engine_switch_gcm_out(br_ssl_engine_context *cc, cc->igcm_out->init(&cc->out.gcm.vtable.out, bc_impl, cipher_key, cipher_key_len, cc->ighash, iv); } + +/* see inner.h */ +void +br_ssl_engine_switch_chapol_in(br_ssl_engine_context *cc, + int is_client, int prf_id) +{ + unsigned char kb[88]; + unsigned char *cipher_key, *iv; + + compute_key_block(cc, prf_id, 44, kb); + if (is_client) { + cipher_key = &kb[32]; + iv = &kb[76]; + } else { + cipher_key = &kb[0]; + iv = &kb[64]; + } + cc->ichapol_in->init(&cc->in.chapol.vtable.in, + cc->ichacha, cc->ipoly, cipher_key, iv); + cc->incrypt = 1; +} + +/* see inner.h */ +void +br_ssl_engine_switch_chapol_out(br_ssl_engine_context *cc, + int is_client, int prf_id) +{ + unsigned char kb[88]; + unsigned char *cipher_key, *iv; + + compute_key_block(cc, prf_id, 44, kb); + if (is_client) { + cipher_key = &kb[0]; + iv = &kb[64]; + } else { + cipher_key = &kb[32]; + iv = &kb[76]; + } + cc->ichapol_out->init(&cc->out.chapol.vtable.out, + cc->ichacha, cc->ipoly, cipher_key, iv); +}