From 7ee8627f6eb7cf63b34d2701d76bb66f6db811e5 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 7 Sep 2016 11:34:39 +0100 Subject: [PATCH] Convert libssl writing for size_t Reviewed-by: Rich Salz --- include/openssl/ssl.h | 2 + ssl/d1_lib.c | 38 +++++----- ssl/d1_msg.c | 11 +-- ssl/record/rec_layer_d1.c | 20 +++--- ssl/record/rec_layer_s3.c | 114 ++++++++++++++++-------------- ssl/record/record.h | 28 ++++---- ssl/record/record_locl.h | 2 +- ssl/record/ssl3_buffer.c | 4 +- ssl/s3_enc.c | 13 ++-- ssl/s3_lib.c | 5 +- ssl/s3_msg.c | 8 ++- ssl/ssl_err.c | 1 + ssl/ssl_lib.c | 47 ++++++++++--- ssl/ssl_locl.h | 39 ++++++----- ssl/statem/statem_dtls.c | 142 +++++++++++++++++++------------------- ssl/statem/statem_lib.c | 11 +-- util/libssl.num | 1 + 17 files changed, 270 insertions(+), 216 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 3dc3f78657..6f326d6258 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1572,6 +1572,7 @@ __owur int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *read); __owur int SSL_peek(SSL *ssl, void *buf, int num); __owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *read); __owur int SSL_write(SSL *ssl, const void *buf, int num); +__owur int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written); long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); long SSL_callback_ctrl(SSL *, int, void (*)(void)); long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); @@ -2220,6 +2221,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL_VALIDATE_CT 400 # define SSL_F_SSL_VERIFY_CERT_CHAIN 207 # define SSL_F_SSL_WRITE 208 +# define SSL_F_SSL_WRITE_EX 427 # define SSL_F_STATE_MACHINE 353 # define SSL_F_TLS12_CHECK_PEER_SIGALG 333 # define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index e7a6650aff..72673863cb 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -23,10 +23,10 @@ static void get_current_time(struct timeval *t); static int dtls1_handshake_write(SSL *s); -static unsigned int dtls1_link_min_mtu(void); +static size_t dtls1_link_min_mtu(void); /* XDTLS: figure out the right values */ -static const unsigned int g_probable_mtu[] = { 1500, 512, 256 }; +static const size_t g_probable_mtu[] = { 1500, 512, 256 }; const SSL3_ENC_METHOD DTLSv1_enc_data = { tls1_enc, @@ -164,8 +164,8 @@ void dtls1_clear(SSL *s) { pqueue *buffered_messages; pqueue *sent_messages; - unsigned int mtu; - unsigned int link_mtu; + size_t mtu; + size_t link_mtu; DTLS_RECORD_LAYER_clear(&s->rlayer); @@ -344,7 +344,7 @@ void dtls1_stop_timer(SSL *s) int dtls1_check_timeout_num(SSL *s) { - unsigned int mtu; + size_t mtu; s->d1->timeout.num_alerts++; @@ -872,12 +872,13 @@ static int dtls1_handshake_write(SSL *s) # define HEARTBEAT_SIZE_STD(payload) HEARTBEAT_SIZE(payload, 16) -int dtls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length) +int dtls1_process_heartbeat(SSL *s, unsigned char *p, size_t length) { unsigned char *pl; unsigned short hbtype; unsigned int payload; unsigned int padding = 16; /* Use minimum padding */ + size_t written; if (s->msg_callback) s->msg_callback(0, s->version, DTLS1_RT_HEARTBEAT, @@ -897,7 +898,7 @@ int dtls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length) if (hbtype == TLS1_HB_REQUEST) { unsigned char *buffer, *bp; - unsigned int write_length = HEARTBEAT_SIZE(payload, padding); + size_t write_length = HEARTBEAT_SIZE(payload, padding); int r; if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) @@ -920,16 +921,17 @@ int dtls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length) return -1; } - r = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buffer, write_length); + r = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buffer, write_length, + &written); - if (r >= 0 && s->msg_callback) + if (r > 0 && s->msg_callback) s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT, buffer, write_length, s, s->msg_callback_arg); OPENSSL_free(buffer); - if (r < 0) - return r; + if (r <= 0) + return -1; } else if (hbtype == TLS1_HB_RESPONSE) { unsigned int seq; @@ -953,9 +955,9 @@ int dtls1_heartbeat(SSL *s) { unsigned char *buf, *p; int ret = -1; - unsigned int payload = 18; /* Sequence number + random bytes */ - unsigned int padding = 16; /* Use minimum padding */ - unsigned int size; + size_t payload = 18; /* Sequence number + random bytes */ + size_t padding = 16; /* Use minimum padding */ + size_t size, written; /* Only send if peer supports and accepts HB requests... */ if (!(s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED) || @@ -1006,8 +1008,8 @@ int dtls1_heartbeat(SSL *s) goto err; } - ret = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buf, size); - if (ret >= 0) { + ret = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buf, size, &written); + if (ret > 0) { if (s->msg_callback) s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT, buf, size, s, s->msg_callback_arg); @@ -1078,13 +1080,13 @@ int dtls1_query_mtu(SSL *s) return 1; } -static unsigned int dtls1_link_min_mtu(void) +static size_t dtls1_link_min_mtu(void) { return (g_probable_mtu[(sizeof(g_probable_mtu) / sizeof(g_probable_mtu[0])) - 1]); } -unsigned int dtls1_min_mtu(SSL *s) +size_t dtls1_min_mtu(SSL *s) { return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); } diff --git a/ssl/d1_msg.c b/ssl/d1_msg.c index ae7aff6959..ac6d28421c 100644 --- a/ssl/d1_msg.c +++ b/ssl/d1_msg.c @@ -10,7 +10,8 @@ #define USE_SOCKETS #include "ssl_locl.h" -int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) +int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, size_t len, + size_t *written) { int i; @@ -41,8 +42,7 @@ int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) return -1; } - i = dtls1_write_bytes(s, type, buf_, len); - return i; + return dtls1_write_bytes(s, type, buf_, len, written); } int dtls1_dispatch_alert(SSL *s) @@ -51,6 +51,7 @@ int dtls1_dispatch_alert(SSL *s) void (*cb) (const SSL *ssl, int type, int val) = NULL; unsigned char buf[DTLS1_AL_HEADER_LENGTH]; unsigned char *ptr = &buf[0]; + size_t written; s->s3->alert_dispatch = 0; @@ -65,7 +66,7 @@ int dtls1_dispatch_alert(SSL *s) } #endif - i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); + i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0, &written); if (i <= 0) { s->s3->alert_dispatch = 1; /* fprintf( stderr, "not done with alert\n" ); */ @@ -91,5 +92,5 @@ int dtls1_dispatch_alert(SSL *s) cb(s, SSL_CB_WRITE_ALERT, j); } } - return (i); + return i; } diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index 7b35d590dc..14f9fc1020 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -971,22 +971,23 @@ static size_t have_handshake_fragment(SSL *s, int type, unsigned char *buf, * Call this to write data in records of type 'type' It will return <= 0 if * not all data has been sent or non-blocking IO. */ -int dtls1_write_bytes(SSL *s, int type, const void *buf, int len) +int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len, + size_t *written) { int i; OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); s->rwstate = SSL_NOTHING; - i = do_dtls1_write(s, type, buf, len, 0); + i = do_dtls1_write(s, type, buf, len, 0, written); return i; } int do_dtls1_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragment) + size_t len, int create_empty_fragment, size_t *written) { unsigned char *p, *pseq; int i, mac_size, clear = 0; - int prefix_len = 0; + size_t prefix_len = 0; int eivlen; SSL3_RECORD wr; SSL3_BUFFER *wb; @@ -1000,14 +1001,14 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, */ if (SSL3_BUFFER_get_left(wb) != 0) { OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ - return (ssl3_write_pending(s, type, buf, len)); + return ssl3_write_pending(s, type, buf, len, written); } /* If we have an alert to send, lets send it */ if (s->s3->alert_dispatch) { i = s->method->ssl_dispatch_alert(s); if (i <= 0) - return (i); + return i; /* if it went, fall through and send more stuff */ } @@ -1072,7 +1073,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, /* lets setup the record stuff. */ SSL3_RECORD_set_data(&wr, p + eivlen); /* make room for IV in case of CBC */ - SSL3_RECORD_set_length(&wr, (int)len); + SSL3_RECORD_set_length(&wr, len); SSL3_RECORD_set_input(&wr, (unsigned char *)buf); /* @@ -1160,7 +1161,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, * we are in a recursive call; just return the length, don't write * out anything here */ - return wr.length; + *written = wr.length; + return 1; } /* now let's set up wb */ @@ -1177,7 +1179,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, s->rlayer.wpend_ret = len; /* we now just need to write the buffer */ - return ssl3_write_pending(s, type, buf, len); + return ssl3_write_pending(s, type, buf, len, written); err: return -1; } diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 6415f4882d..9c3a097420 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -347,22 +347,18 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, * Call this to write data in records of type 'type' It will return <= 0 if * not all data has been sent or non-blocking IO. */ -int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) +int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, + size_t *written) { const unsigned char *buf = buf_; - int tot; - unsigned int n, split_send_fragment, maxpipes; + size_t tot; + size_t n, split_send_fragment, maxpipes; #if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - unsigned int max_send_fragment, nw; - unsigned int u_len = (unsigned int)len; + size_t max_send_fragment, nw; #endif SSL3_BUFFER *wb = &s->rlayer.wbuf[0]; int i; - - if (len < 0) { - SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_NEGATIVE_LENGTH); - return -1; - } + size_t tmpwrit; s->rwstate = SSL_NOTHING; tot = s->rlayer.wnum; @@ -375,7 +371,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) * promptly send beyond the end of the users buffer ... so we trap and * report the error in a way the user will notice */ - if ((unsigned int)len < s->rlayer.wnum) { + if (len < s->rlayer.wnum) { SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH); return -1; } @@ -385,7 +381,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s)) { i = s->handshake_func(s); if (i < 0) - return (i); + return i; if (i == 0) { SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); return -1; @@ -397,13 +393,14 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) * will happen with non blocking IO */ if (wb->left != 0) { - i = ssl3_write_pending(s, type, &buf[tot], s->rlayer.wpend_tot); + i = ssl3_write_pending(s, type, &buf[tot], s->rlayer.wpend_tot, + &tmpwrit); if (i <= 0) { /* XXX should we ssl3_release_write_buffer if i<0? */ s->rlayer.wnum = tot; return i; } - tot += i; /* this might be last fragment */ + tot += tmpwrit; /* this might be last fragment */ } #if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK /* @@ -413,7 +410,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) * compromise is considered worthy. */ if (type == SSL3_RT_APPLICATION_DATA && - u_len >= 4 * (max_send_fragment = s->max_send_fragment) && + len >= 4 * (max_send_fragment = s->max_send_fragment) && s->compress == NULL && s->msg_callback == NULL && !SSL_USE_ETM(s) && SSL_USE_EXPLICIT_IV(s) && EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) & @@ -433,7 +430,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE, max_send_fragment, NULL); - if (u_len >= 8 * max_send_fragment) + if (len >= 8 * max_send_fragment) packlen *= 8; else packlen *= 4; @@ -513,7 +510,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) s->rlayer.wpend_type = type; s->rlayer.wpend_ret = nw; - i = ssl3_write_pending(s, type, &buf[tot], nw); + i = ssl3_write_pending(s, type, &buf[tot], nw, &tmpwrit); if (i <= 0) { if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) { /* free jumbo buffer */ @@ -522,13 +519,14 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) s->rlayer.wnum = tot; return i; } - if (i == (int)n) { + if (tmpwrit == n) { /* free jumbo buffer */ ssl3_release_write_buffer(s); - return tot + i; + *written = tot + tmpwrit; + return 1; } - n -= i; - tot += i; + n -= tmpwrit; + tot += tmpwrit; } } else #endif @@ -536,7 +534,8 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) ssl3_release_write_buffer(s); - return tot; + *written = tot; + return 1; } n = (len - tot); @@ -574,8 +573,8 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) } for (;;) { - unsigned int pipelens[SSL_MAX_PIPELINES], tmppipelen, remain; - unsigned int numpipes, j; + size_t pipelens[SSL_MAX_PIPELINES], tmppipelen, remain; + size_t numpipes, j; if (n == 0) numpipes = 1; @@ -603,14 +602,15 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) } } - i = do_ssl3_write(s, type, &(buf[tot]), pipelens, numpipes, 0); + i = do_ssl3_write(s, type, &(buf[tot]), pipelens, numpipes, 0, + &tmpwrit); if (i <= 0) { /* XXX should we ssl3_release_write_buffer if i<0? */ s->rlayer.wnum = tot; return i; } - if ((i == (int)n) || + if ((tmpwrit == n) || (type == SSL3_RT_APPLICATION_DATA && (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { /* @@ -623,29 +623,29 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) !SSL_IS_DTLS(s)) ssl3_release_write_buffer(s); - return tot + i; + *written = tot + tmpwrit; + return 1; } - n -= i; - tot += i; + n -= tmpwrit; + tot += tmpwrit; } } -/* TODO(size_t): convert me */ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - unsigned int *pipelens, unsigned int numpipes, - int create_empty_fragment) + size_t *pipelens, size_t numpipes, + int create_empty_fragment, size_t *written) { unsigned char *outbuf[SSL_MAX_PIPELINES], *plen[SSL_MAX_PIPELINES]; SSL3_RECORD wr[SSL_MAX_PIPELINES]; int i, mac_size, clear = 0; - int prefix_len = 0; + size_t prefix_len = 0; int eivlen; size_t align = 0; SSL3_BUFFER *wb; SSL_SESSION *sess; - unsigned int totlen = 0; - unsigned int j; + size_t totlen = 0; + size_t j; for (j = 0; j < numpipes; j++) totlen += pipelens[j]; @@ -654,7 +654,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, * will happen with non blocking IO */ if (RECORD_LAYER_write_pending(&s->rlayer)) - return (ssl3_write_pending(s, type, buf, totlen)); + return ssl3_write_pending(s, type, buf, totlen, written); /* If we have an alert to send, lets send it */ if (s->s3->alert_dispatch) { @@ -678,6 +678,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ mac_size = 0; } else { + /* TODO(siz_t): Convert me */ mac_size = EVP_MD_CTX_size(s->write_hash); if (mac_size < 0) goto err; @@ -699,10 +700,11 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, * 'prefix_len' bytes are sent out later together with the actual * payload) */ - unsigned int tmppipelen = 0; + size_t tmppipelen = 0; + int ret; - prefix_len = do_ssl3_write(s, type, buf, &tmppipelen, 1, 1); - if (prefix_len <= 0) + ret = do_ssl3_write(s, type, buf, &tmppipelen, 1, 1, &prefix_len); + if (ret <= 0) goto err; if (prefix_len > @@ -749,6 +751,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); if (mode == EVP_CIPH_CBC_MODE) { + /* TODO(size_t): Convert me */ eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); if (eivlen <= 1) eivlen = 0; @@ -868,7 +871,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); goto err; } - return SSL3_RECORD_get_length(wr); + *written = SSL3_RECORD_get_length(wr); + return 1; } /* now let's set up wb */ @@ -886,7 +890,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, s->rlayer.wpend_ret = totlen; /* we now just need to write the buffer */ - return ssl3_write_pending(s, type, buf, totlen); + return ssl3_write_pending(s, type, buf, totlen, written); err: return -1; } @@ -894,24 +898,24 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* if s->s3->wbuf.left != 0, we need to call this * * Return values are as per SSL_read(), i.e. - * >0 The number of read bytes + * 1 Success * 0 Failure (not retryable) * <0 Failure (may be retryable) */ -int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, - unsigned int len) +int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, + size_t *written) { int i; SSL3_BUFFER *wb = s->rlayer.wbuf; - unsigned int currbuf = 0; + size_t currbuf = 0; + size_t tmpwrit; -/* XXXX */ - if ((s->rlayer.wpend_tot > (int)len) + if ((s->rlayer.wpend_tot > len) || ((s->rlayer.wpend_buf != buf) && !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) || (s->rlayer.wpend_type != type)) { SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); - return (-1); + return -1; } for (;;) { @@ -924,21 +928,25 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, clear_sys_error(); if (s->wbio != NULL) { s->rwstate = SSL_WRITING; + /* TODO(size_t): Convert this call */ i = BIO_write(s->wbio, (char *) &(SSL3_BUFFER_get_buf(&wb[currbuf]) [SSL3_BUFFER_get_offset(&wb[currbuf])]), (unsigned int)SSL3_BUFFER_get_left(&wb[currbuf])); + if (i >= 0) + tmpwrit = i; } else { SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET); i = -1; } - if (i == (int)SSL3_BUFFER_get_left(&wb[currbuf])) { + if (i > 0 && tmpwrit == SSL3_BUFFER_get_left(&wb[currbuf])) { SSL3_BUFFER_set_left(&wb[currbuf], 0); - SSL3_BUFFER_add_offset(&wb[currbuf], i); + SSL3_BUFFER_add_offset(&wb[currbuf], tmpwrit); if (currbuf + 1 < s->rlayer.numwpipes) continue; s->rwstate = SSL_NOTHING; - return (s->rlayer.wpend_ret); + *written = s->rlayer.wpend_ret; + return 1; } else if (i <= 0) { if (SSL_IS_DTLS(s)) { /* @@ -949,8 +957,8 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, } return -1; } - SSL3_BUFFER_add_offset(&wb[currbuf], i); - SSL3_BUFFER_sub_left(&wb[currbuf], i); + SSL3_BUFFER_add_offset(&wb[currbuf], tmpwrit); + SSL3_BUFFER_sub_left(&wb[currbuf], tmpwrit); } } diff --git a/ssl/record/record.h b/ssl/record/record.h index fc70f8d848..1fe7e3db8f 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -145,7 +145,7 @@ typedef struct record_layer_st { /* How many pipelines can be used to read data */ size_t numrpipes; /* How many pipelines can be used to write data */ - unsigned int numwpipes; + size_t numwpipes; /* read IO goes into here */ SSL3_BUFFER rbuf; /* write IO goes into here */ @@ -156,7 +156,7 @@ typedef struct record_layer_st { unsigned char *packet; size_t packet_length; /* number of bytes sent so far */ - unsigned int wnum; + size_t wnum; /* * storage for Alert/Handshake protocol data received but not yet * processed by ssl3_read_bytes: @@ -169,10 +169,10 @@ typedef struct record_layer_st { size_t empty_record_count; /* partial write - check the numbers match */ /* number bytes written */ - int wpend_tot; + size_t wpend_tot; int wpend_type; /* number of bytes submitted */ - int wpend_ret; + size_t wpend_ret; const unsigned char *wpend_buf; unsigned char read_sequence[SEQ_NUM_SIZE]; unsigned char write_sequence[SEQ_NUM_SIZE]; @@ -215,18 +215,19 @@ void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl); int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl); size_t RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl); __owur int ssl3_pending(const SSL *s); -__owur int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); -__owur int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - unsigned int *pipelens, unsigned int numpipes, - int create_empty_fragment); +__owur int ssl3_write_bytes(SSL *s, int type, const void *buf, size_t len, + size_t *written); +int do_ssl3_write(SSL *s, int type, const unsigned char *buf, + size_t *pipelens, size_t numpipes, + int create_empty_fragment, size_t *written); __owur int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, size_t len, int peek, size_t *read); __owur int ssl3_setup_buffers(SSL *s); __owur int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, unsigned int n_recs, int send); __owur int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send); -__owur int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, - unsigned int len); +__owur int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, + size_t *written); __owur int tls1_enc(SSL *s, SSL3_RECORD *recs, unsigned int n_recs, int send); __owur int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send); int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl); @@ -239,7 +240,8 @@ void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq); __owur int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, size_t len, int peek, size_t *read); -__owur int dtls1_write_bytes(SSL *s, int type, const void *buf, int len); -__owur int do_dtls1_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragement); +__owur int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len, + size_t *written); +int do_dtls1_write(SSL *s, int type, const unsigned char *buf, + size_t len, int create_empty_fragment, size_t *written); void dtls1_reset_seq_numbers(SSL *s, int rw); diff --git a/ssl/record/record_locl.h b/ssl/record/record_locl.h index ffd1e51dfa..0c9df3e6b0 100644 --- a/ssl/record/record_locl.h +++ b/ssl/record/record_locl.h @@ -73,7 +73,7 @@ void SSL3_BUFFER_clear(SSL3_BUFFER *b); void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, size_t n); void SSL3_BUFFER_release(SSL3_BUFFER *b); __owur int ssl3_setup_read_buffer(SSL *s); -__owur int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes, size_t len); +__owur int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len); int ssl3_release_read_buffer(SSL *s); int ssl3_release_write_buffer(SSL *s); diff --git a/ssl/record/ssl3_buffer.c b/ssl/record/ssl3_buffer.c index 8a2a6e473d..1252310394 100644 --- a/ssl/record/ssl3_buffer.c +++ b/ssl/record/ssl3_buffer.c @@ -74,12 +74,12 @@ int ssl3_setup_read_buffer(SSL *s) return 0; } -int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes, size_t len) +int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len) { unsigned char *p; size_t align = 0, headerlen; SSL3_BUFFER *wb; - unsigned int currpipe; + size_t currpipe; s->rlayer.numwpipes = numwpipes; diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 56bd34a3d1..f32b68a0b3 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -356,13 +356,18 @@ void ssl3_free_digest_list(SSL *s) s->s3->handshake_dgst = NULL; } -int ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) +int ssl3_finish_mac(SSL *s, const unsigned char *buf, size_t len) { - if (s->s3->handshake_dgst == NULL) + if (s->s3->handshake_dgst == NULL) { + int ret; /* Note: this writes to a memory BIO so a failure is a fatal error */ - return BIO_write(s->s3->handshake_buffer, (void *)buf, len) == len; - else + if (len > INT_MAX) + return 0; + ret = BIO_write(s->s3->handshake_buffer, (void *)buf, (int)len); + return ret > 0 && ret == (int)len; + } else { return EVP_DigestUpdate(s->s3->handshake_dgst, buf, len); + } } int ssl3_digest_cached_records(SSL *s, int keep) diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 37dea73b24..52f9214c3d 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3829,13 +3829,14 @@ int ssl3_shutdown(SSL *s) return (0); } -int ssl3_write(SSL *s, const void *buf, int len) +int ssl3_write(SSL *s, const void *buf, size_t len, size_t *written) { clear_sys_error(); if (s->s3->renegotiate) ssl3_renegotiate_check(s); - return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len); + return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, + written); } static int ssl3_read_internal(SSL *s, void *buf, size_t len, int peek, diff --git a/ssl/s3_msg.c b/ssl/s3_msg.c index 82513d2590..a39994eaff 100644 --- a/ssl/s3_msg.c +++ b/ssl/s3_msg.c @@ -90,12 +90,14 @@ int ssl3_send_alert(SSL *s, int level, int desc) int ssl3_dispatch_alert(SSL *s) { int i, j; - unsigned int alertlen; + size_t alertlen; void (*cb) (const SSL *ssl, int type, int val) = NULL; + size_t written; s->s3->alert_dispatch = 0; alertlen = 2; - i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], &alertlen, 1, 0); + i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], &alertlen, 1, 0, + &written); if (i <= 0) { s->s3->alert_dispatch = 1; } else { @@ -121,5 +123,5 @@ int ssl3_dispatch_alert(SSL *s) cb(s, SSL_CB_WRITE_ALERT, j); } } - return (i); + return i; } diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index eac03a4ac5..5c2e961096 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -229,6 +229,7 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_SSL_VALIDATE_CT), "ssl_validate_ct"}, {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "ssl_verify_cert_chain"}, {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"}, + {ERR_FUNC(SSL_F_SSL_WRITE_EX), "SSL_write_ex"}, {ERR_FUNC(SSL_F_STATE_MACHINE), "state_machine"}, {ERR_FUNC(SSL_F_TLS12_CHECK_PEER_SIGALG), "tls12_check_peer_sigalg"}, {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "tls1_change_cipher_state"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 30b1d6b860..a26e352b29 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -85,7 +85,7 @@ struct ssl_async_args { enum { READFUNC, WRITEFUNC, OTHERFUNC } type; union { int (*func_read) (SSL *, void *, size_t, size_t *); - int (*func_write) (SSL *, const void *, int); + int (*func_write) (SSL *, const void *, size_t, size_t *); int (*func_other) (SSL *); } f; }; @@ -1517,9 +1517,9 @@ static int ssl_io_intern(void *vargs) num = args->num; switch (args->type) { case READFUNC: - return args->f.func_read(s, buf, num, &s->asyncread); + return args->f.func_read(s, buf, num, &s->asyncrw); case WRITEFUNC: - return args->f.func_write(s, buf, num); + return args->f.func_write(s, buf, num, &s->asyncrw); case OTHERFUNC: return args->f.func_other(s); } @@ -1571,7 +1571,7 @@ int SSL_read_ex(SSL *s, void *buf, size_t num, size_t *read) args.f.func_read = s->method->ssl_read; ret = ssl_start_async_job(s, &args, ssl_io_intern); - *read = s->asyncread; + *read = s->asyncrw; return ret; } else { return s->method->ssl_read(s, buf, num, read); @@ -1621,7 +1621,7 @@ int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *read) args.f.func_read = s->method->ssl_peek; ret = ssl_start_async_job(s, &args, ssl_io_intern); - *read = s->asyncread; + *read = s->asyncrw; return ret; } else { return s->method->ssl_peek(s, buf, num, read); @@ -1629,19 +1629,42 @@ int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *read) } int SSL_write(SSL *s, const void *buf, int num) +{ + int ret; + size_t written; + + if (num < 0) { + SSLerr(SSL_F_SSL_WRITE, SSL_R_BAD_LENGTH); + return -1; + } + + ret = SSL_write_ex(s, buf, (size_t)num, &written); + + /* + * The cast is safe here because ret should be <= INT_MAX because num is + * <= INT_MAX + */ + if (ret > 0) + ret = (int)written; + + return ret; +} + +int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written) { if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED); + SSLerr(SSL_F_SSL_WRITE_EX, SSL_R_UNINITIALIZED); return -1; } if (s->shutdown & SSL_SENT_SHUTDOWN) { s->rwstate = SSL_NOTHING; - SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN); + SSLerr(SSL_F_SSL_WRITE_EX, SSL_R_PROTOCOL_IS_SHUTDOWN); return (-1); } if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { + int ret; struct ssl_async_args args; args.s = s; @@ -1650,9 +1673,11 @@ int SSL_write(SSL *s, const void *buf, int num) args.type = WRITEFUNC; args.f.func_write = s->method->ssl_write; - return ssl_start_async_job(s, &args, ssl_io_intern); + ret = ssl_start_async_job(s, &args, ssl_io_intern); + *written = s->asyncrw; + return ret; } else { - return s->method->ssl_write(s, buf, num); + return s->method->ssl_write(s, buf, num, written); } } @@ -1751,7 +1776,7 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) s->split_send_fragment = s->max_send_fragment; return 1; case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT: - if ((unsigned int)larg > s->max_send_fragment || larg == 0) + if ((size_t)larg > s->max_send_fragment || larg == 0) return 0; s->split_send_fragment = larg; return 1; @@ -1905,7 +1930,7 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) ctx->split_send_fragment = ctx->max_send_fragment; return 1; case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT: - if ((unsigned int)larg > ctx->max_send_fragment || larg == 0) + if ((size_t)larg > ctx->max_send_fragment || larg == 0) return 0; ctx->split_send_fragment = larg; return 1; diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 4aea4571d4..8b6b1405d3 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -446,14 +446,15 @@ struct ssl_method_st { int (*ssl_connect) (SSL *s); int (*ssl_read) (SSL *s, void *buf, size_t len, size_t *read); int (*ssl_peek) (SSL *s, void *buf, size_t len, size_t *read); - int (*ssl_write) (SSL *s, const void *buf, int len); + int (*ssl_write) (SSL *s, const void *buf, size_t len, size_t *written); int (*ssl_shutdown) (SSL *s); int (*ssl_renegotiate) (SSL *s); int (*ssl_renegotiate_check) (SSL *s); int (*ssl_read_bytes) (SSL *s, int type, int *recvd_type, unsigned char *buf, size_t len, int peek, size_t *read); - int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len); + int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, size_t len, + size_t *written); int (*ssl_dispatch_alert) (SSL *s); long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg); long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg); @@ -747,15 +748,15 @@ struct ssl_ctx_st { * If we're using more than one pipeline how should we divide the data * up between the pipes? */ - unsigned int split_send_fragment; + size_t split_send_fragment; /* * Maximum amount of data to send in one fragment. actual record size can * be more than this due to padding and MAC overheads. */ - unsigned int max_send_fragment; + size_t max_send_fragment; /* Up to how many pipelines should we use? If 0 then 1 is assumed */ - unsigned int max_pipelines; + size_t max_pipelines; /* The default read buffer length to use (0 means not set) */ size_t default_read_buf_len; @@ -1010,14 +1011,14 @@ struct ssl_st { * If we're using more than one pipeline how should we divide the data * up between the pipes? */ - unsigned int split_send_fragment; + size_t split_send_fragment; /* * Maximum amount of data to send in one fragment. actual record size can * be more than this due to padding and MAC overheads. */ - unsigned int max_send_fragment; + size_t max_send_fragment; /* Up to how many pipelines should we use? If 0 then 1 is assumed */ - unsigned int max_pipelines; + size_t max_pipelines; /* TLS extension debug callback */ void (*tlsext_debug_cb) (SSL *s, int client_server, int type, const unsigned char *data, int len, void *arg); @@ -1136,7 +1137,7 @@ struct ssl_st { /* Async Job info */ ASYNC_JOB *job; ASYNC_WAIT_CTX *waitctx; - size_t asyncread; + size_t asyncrw; CRYPTO_RWLOCK *lock; }; @@ -1329,10 +1330,10 @@ struct dtls1_retransmit_state { struct hm_header_st { unsigned char type; - unsigned long msg_len; + size_t msg_len; unsigned short seq; - unsigned long frag_off; - unsigned long frag_len; + size_t frag_off; + size_t frag_len; unsigned int is_ccs; struct dtls1_retransmit_state saved_retransmit_state; }; @@ -1387,8 +1388,8 @@ typedef struct dtls1_state_st { pqueue *buffered_messages; /* Buffered (sent) handshake records */ pqueue *sent_messages; - unsigned int link_mtu; /* max on-the-wire DTLS packet size */ - unsigned int mtu; /* max DTLS packet size */ + size_t link_mtu; /* max on-the-wire DTLS packet size */ + size_t mtu; /* max DTLS packet size */ struct hm_header_st w_msg_hdr; struct hm_header_st r_msg_hdr; struct dtls1_timeout_st timeout; @@ -1887,7 +1888,7 @@ int ssl3_renegotiate_check(SSL *ssl); __owur int ssl3_dispatch_alert(SSL *s); __owur int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, unsigned char *p); -__owur int ssl3_finish_mac(SSL *s, const unsigned char *buf, int len); +__owur int ssl3_finish_mac(SSL *s, const unsigned char *buf, size_t len); void ssl3_free_digest_list(SSL *s); __owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk); @@ -1899,7 +1900,7 @@ __owur int ssl3_new(SSL *s); void ssl3_free(SSL *s); __owur int ssl3_read(SSL *s, void *buf, size_t len, size_t *read); __owur int ssl3_peek(SSL *s, void *buf, size_t len, size_t *read); -__owur int ssl3_write(SSL *s, const void *buf, int len); +__owur int ssl3_write(SSL *s, const void *buf, size_t len, size_t *written); __owur int ssl3_shutdown(SSL *s); void ssl3_clear(SSL *s); __owur long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg); @@ -1935,8 +1936,8 @@ void dtls1_set_message_header(SSL *s, unsigned long len, unsigned long frag_off, unsigned long frag_len); -__owur int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, - int len); +int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, size_t len, + size_t *written); __owur int dtls1_read_failed(SSL *s, int code); __owur int dtls1_buffer_message(SSL *s, int ccs); @@ -1958,7 +1959,7 @@ void dtls1_double_timeout(SSL *s); __owur int dtls_raw_hello_verify_request(WPACKET *pkt, unsigned char *cookie, unsigned char cookie_len); __owur int dtls1_send_newsession_ticket(SSL *s); -__owur unsigned int dtls1_min_mtu(SSL *s); +__owur size_t dtls1_min_mtu(SSL *s); void dtls1_hm_fragment_free(hm_fragment *frag); __owur int dtls1_query_mtu(SSL *s); diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c index 828118833f..0e54ea5ddb 100644 --- a/ssl/statem/statem_dtls.c +++ b/ssl/statem/statem_dtls.c @@ -43,18 +43,17 @@ static unsigned char bitmask_start_values[] = static unsigned char bitmask_end_values[] = { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; -static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, - unsigned long frag_len); +static void dtls1_fix_message_header(SSL *s, size_t frag_off, + size_t frag_len); static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p); static void dtls1_set_message_header_int(SSL *s, unsigned char mt, - unsigned long len, + size_t len, unsigned short seq_num, - unsigned long frag_off, - unsigned long frag_len); -static int dtls_get_reassembled_message(SSL *s, long *len); + size_t frag_off, + size_t frag_len); +static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len); -static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len, - int reassembly) +static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) { hm_fragment *frag = NULL; unsigned char *buf = NULL; @@ -111,9 +110,10 @@ void dtls1_hm_fragment_free(hm_fragment *frag) int dtls1_do_write(SSL *s, int type) { int ret; - unsigned int curr_mtu; + size_t written; + size_t curr_mtu; int retry = 1; - unsigned int len, frag_off, mac_size, blocksize, used_len; + size_t len, frag_off, mac_size, blocksize, used_len; if (!dtls1_query_mtu(s)) return -1; @@ -215,6 +215,7 @@ int dtls1_do_write(SSL *s, int type) len = s->init_num; /* Shouldn't ever happen */ + /* TODO(size_t): can this go now? */ if (len > INT_MAX) len = INT_MAX; @@ -236,7 +237,8 @@ int dtls1_do_write(SSL *s, int type) data[s->init_off]); } - ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len); + ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len, + &written); if (ret < 0) { /* * might need to update MTU here, but we don't know which @@ -262,7 +264,7 @@ int dtls1_do_write(SSL *s, int type) * bad if this assert fails, only part of the handshake message * got sent. but why would this happen? */ - OPENSSL_assert(len == (unsigned int)ret); + OPENSSL_assert(len == written); if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) { /* @@ -272,7 +274,7 @@ int dtls1_do_write(SSL *s, int type) unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off]; const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - int xlen; + size_t xlen; if (frag_off == 0 && s->version != DTLS1_BAD_VER) { /* @@ -285,17 +287,17 @@ int dtls1_do_write(SSL *s, int type) l2n3(0, p); l2n3(msg_hdr->msg_len, p); p -= DTLS1_HM_HEADER_LENGTH; - xlen = ret; + xlen = written; } else { p += DTLS1_HM_HEADER_LENGTH; - xlen = ret - DTLS1_HM_HEADER_LENGTH; + xlen = written - DTLS1_HM_HEADER_LENGTH; } if (!ssl3_finish_mac(s, p, xlen)) return -1; } - if (ret == (int)s->init_num) { + if (written == s->init_num) { if (s->msg_callback) s->msg_callback(1, s->version, type, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, @@ -304,12 +306,12 @@ int dtls1_do_write(SSL *s, int type) s->init_off = 0; /* done writing this message */ s->init_num = 0; - return (1); + return 1; } - s->init_off += ret; - s->init_num -= ret; - ret -= DTLS1_HM_HEADER_LENGTH; - frag_off += ret; + s->init_off += written; + s->init_num -= written; + written -= DTLS1_HM_HEADER_LENGTH; + frag_off += written; /* * We save the fragment offset for the next fragment so we have it @@ -320,32 +322,34 @@ int dtls1_do_write(SSL *s, int type) dtls1_fix_message_header(s, frag_off, 0); } } - return (0); + return 0; } int dtls_get_message(SSL *s, int *mt, size_t *len) { struct hm_header_st *msg_hdr; unsigned char *p; - unsigned long msg_len; - int ok; - long tmplen; + size_t msg_len; + size_t tmplen; + int errtype; msg_hdr = &s->d1->r_msg_hdr; memset(msg_hdr, 0, sizeof(*msg_hdr)); again: - ok = dtls_get_reassembled_message(s, &tmplen); - if (tmplen == DTLS1_HM_BAD_FRAGMENT || tmplen == DTLS1_HM_FRAGMENT_RETRY) { - /* bad fragment received */ - goto again; - } else if (tmplen <= 0 && !ok) { + if (!dtls_get_reassembled_message(s, &errtype, &tmplen)) { + if (errtype == DTLS1_HM_BAD_FRAGMENT + || errtype == DTLS1_HM_FRAGMENT_RETRY) { + /* bad fragment received */ + goto again; + } return 0; } *mt = s->s3->tmp.message_type; p = (unsigned char *)s->init_buf->data; + *len = s->init_num; if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) { if (s->msg_callback) { @@ -355,7 +359,6 @@ int dtls_get_message(SSL *s, int *mt, size_t *len) /* * This isn't a real handshake message so skip the processing below. */ - *len = (unsigned long)tmplen; return 1; } @@ -383,7 +386,6 @@ int dtls_get_message(SSL *s, int *mt, size_t *len) s->d1->handshake_read_seq++; s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - *len = s->init_num; return 1; } @@ -444,7 +446,7 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr) return 0; /* no error */ } -static int dtls1_retrieve_buffered_fragment(SSL *s, int *ok) +static int dtls1_retrieve_buffered_fragment(SSL *s, size_t *len) { /*- * (0) check whether the desired fragment is available @@ -456,8 +458,6 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, int *ok) hm_fragment *frag; int al; - *ok = 0; - do { item = pqueue_peek(s->d1->buffered_messages); if (item == NULL) @@ -480,7 +480,7 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, int *ok) return 0; if (s->d1->handshake_read_seq == frag->msg_header.seq) { - unsigned long frag_len = frag->msg_header.frag_len; + size_t frag_len = frag->msg_header.frag_len; pqueue_pop(s->d1->buffered_messages); al = dtls1_preprocess_fragment(s, &frag->msg_header); @@ -496,34 +496,35 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, int *ok) pitem_free(item); if (al == 0) { - *ok = 1; - return frag_len; + *len = frag_len; + return 1; } ssl3_send_alert(s, SSL3_AL_FATAL, al); s->init_num = 0; - *ok = 0; - return -1; - } else return 0; + } else { + return 0; + } } static int -dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok) +dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr) { hm_fragment *frag = NULL; pitem *item = NULL; int i = -1, is_complete; unsigned char seq64be[8]; - unsigned long frag_len = msg_hdr->frag_len; + size_t frag_len = msg_hdr->frag_len; size_t read; if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) goto err; - if (frag_len == 0) + if (frag_len == 0) { return DTLS1_HM_FRAGMENT_RETRY; + } /* Try to find item in queue */ memset(seq64be, 0, sizeof(seq64be)); @@ -610,19 +611,17 @@ dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok) err: if (item == NULL) dtls1_hm_fragment_free(frag); - *ok = 0; - return i; + return -1; } static int -dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr, - int *ok) +dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr) { int i = -1; hm_fragment *frag = NULL; pitem *item = NULL; unsigned char seq64be[8]; - unsigned long frag_len = msg_hdr->frag_len; + size_t frag_len = msg_hdr->frag_len; size_t read; if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) @@ -662,8 +661,9 @@ dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr, frag_len -= read; } } else { - if (frag_len != msg_hdr->msg_len) - return dtls1_reassemble_fragment(s, msg_hdr, ok); + if (frag_len != msg_hdr->msg_len) { + return dtls1_reassemble_fragment(s, msg_hdr);; + } if (frag_len > dtls1_max_handshake_message_len(s)) goto err; @@ -707,26 +707,25 @@ dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr, err: if (item == NULL) dtls1_hm_fragment_free(frag); - *ok = 0; - return i; + return 0; } -static int dtls_get_reassembled_message(SSL *s, long *len) +static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) { unsigned char wire[DTLS1_HM_HEADER_LENGTH]; - unsigned long mlen, frag_off, frag_len; + size_t mlen, frag_off, frag_len; int i, al, recvd_type; struct hm_header_st msg_hdr; - int ok; size_t read; + *errtype = 0; + redo: /* see if we have the required fragment already */ - if ((frag_len = dtls1_retrieve_buffered_fragment(s, &ok)) || ok) { - if (ok) - s->init_num = frag_len; + if (dtls1_retrieve_buffered_fragment(s, &frag_len)) { + s->init_num = frag_len; *len = frag_len; - return ok; + return 1; } /* read handshake message header */ @@ -734,7 +733,7 @@ static int dtls_get_reassembled_message(SSL *s, long *len) DTLS1_HM_HEADER_LENGTH, 0, &read); if (i <= 0) { /* nbio, or an error */ s->rwstate = SSL_READING; - *len = i; + *len = 0; return 0; } if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) { @@ -785,13 +784,13 @@ static int dtls_get_reassembled_message(SSL *s, long *len) * although we're still expecting seq 0 (ClientHello) */ if (msg_hdr.seq != s->d1->handshake_read_seq) { - *len = dtls1_process_out_of_seq_message(s, &msg_hdr, &ok); - return ok; + *errtype = dtls1_process_out_of_seq_message(s, &msg_hdr); + return 0; } if (frag_len && frag_len < mlen) { - *len = dtls1_reassemble_fragment(s, &msg_hdr, &ok); - return ok; + *errtype = dtls1_reassemble_fragment(s, &msg_hdr); + return 0; } if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && @@ -834,11 +833,12 @@ static int dtls_get_reassembled_message(SSL *s, long *len) */ if (i <= 0) { s->rwstate = SSL_READING; - *len = i; + *len = 0; return 0; } - } else + } else { read = 0; + } /* * XDTLS: an incorrectly formatted fragment should cause the handshake @@ -862,7 +862,7 @@ static int dtls_get_reassembled_message(SSL *s, long *len) f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); s->init_num = 0; - *len = -1; + *len = 0; return 0; } @@ -1134,8 +1134,8 @@ void dtls1_set_message_header(SSL *s, /* don't actually do the writing, wait till the MTU has been retrieved */ static void dtls1_set_message_header_int(SSL *s, unsigned char mt, - unsigned long len, unsigned short seq_num, - unsigned long frag_off, unsigned long frag_len) + size_t len, unsigned short seq_num, + size_t frag_off, size_t frag_len) { struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; @@ -1147,7 +1147,7 @@ dtls1_set_message_header_int(SSL *s, unsigned char mt, } static void -dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len) +dtls1_fix_message_header(SSL *s, size_t frag_off, size_t frag_len) { struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index e7ea4c6a4d..90a81fa256 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -30,9 +30,10 @@ int ssl3_do_write(SSL *s, int type) { int ret; + size_t written = 0; ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], - s->init_num); + s->init_num, &written); if (ret < 0) return (-1); if (type == SSL3_RT_HANDSHAKE) @@ -42,18 +43,18 @@ int ssl3_do_write(SSL *s, int type) */ if (!ssl3_finish_mac(s, (unsigned char *)&s->init_buf->data[s->init_off], - ret)) + written)) return -1; - if (ret == (int)s->init_num) { + if (written == s->init_num) { if (s->msg_callback) s->msg_callback(1, s->version, type, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg); return (1); } - s->init_off += ret; - s->init_num -= ret; + s->init_off += written; + s->init_num -= written; return (0); } diff --git a/util/libssl.num b/util/libssl.num index f15c503514..7d1e8d88dd 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -407,3 +407,4 @@ SSL_CTX_set1_cert_store 407 1_1_1 EXIST::FUNCTION: DTLS_get_data_mtu 408 1_1_1 EXIST::FUNCTION: SSL_read_ex 409 1_1_1 EXIST::FUNCTION: SSL_peek_ex 410 1_1_1 EXIST::FUNCTION: +SSL_write_ex 411 1_1_1 EXIST::FUNCTION: