Convert libssl writing for size_t
authorMatt Caswell <matt@openssl.org>
Wed, 7 Sep 2016 10:34:39 +0000 (11:34 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 4 Nov 2016 12:09:45 +0000 (12:09 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
17 files changed:
include/openssl/ssl.h
ssl/d1_lib.c
ssl/d1_msg.c
ssl/record/rec_layer_d1.c
ssl/record/rec_layer_s3.c
ssl/record/record.h
ssl/record/record_locl.h
ssl/record/ssl3_buffer.c
ssl/s3_enc.c
ssl/s3_lib.c
ssl/s3_msg.c
ssl/ssl_err.c
ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/statem/statem_dtls.c
ssl/statem/statem_lib.c
util/libssl.num

index 3dc3f78657f4cfe98782462045d8306635ca20d9..6f326d6258eaec309e32c0771e99b2e27f960dee 100644 (file)
@@ -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
index e7a6650afffd776ab23f583a7f169dd3f3154ed2..72673863cbf8467c1987880190a13d19603447f3 100644 (file)
 
 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));
 }
index ae7aff69599da4a89d4190e46e70452a96b01221..ac6d28421c6fce8d845eb876644699b3895eae18 100644 (file)
@@ -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;
 }
index 7b35d590dc654e55c541353e95bcabf4e0a42b4d..14f9fc1020098e7c5ede32caae5337cc90c4e472 100644 (file)
@@ -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;
 }
index 6415f4882defa563b54fbb416b2f59987733377d..9c3a097420d89c7bd3025f18b4c6453eaf6a002c 100644 (file)
@@ -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);
     }
 }
 
index fc70f8d848c8aa7e6f6c9a189397e10e38606f24..1fe7e3db8f7be6c1b61752faf7fef2e745890f01 100644 (file)
@@ -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);
index ffd1e51dfaf9b2d7e489b7f1c79289e2af3cbbb3..0c9df3e6b04a58504e9bff2277e0419bd0bf698c 100644 (file)
@@ -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);
 
index 8a2a6e473da6e4bb441145136f5101e215456f6d..1252310394aaec7f17173d30e567498dd9759c49 100644 (file)
@@ -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;
 
index 56bd34a3d11fe5e3a329ccf7f63300bd8c478686..f32b68a0b3d62f1b65f0212a96075f67285086b0 100644 (file)
@@ -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)
index 37dea73b2426496a9dc3ecddcf7bae1845c6819f..52f9214c3d8ef2193a6835cdf018fb00e8c40087 100644 (file)
@@ -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,
index 82513d259086de5315cac974058b363fcef81319..a39994eaff27fa311eab2e9a363a677096ccf514 100644 (file)
@@ -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;
 }
index eac03a4ac525c8b3c020f2286eb270765f40f651..5c2e9610964eff03d58fcaf3fe3f2a3fefd6f0c4 100644 (file)
@@ -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"},
index 30b1d6b860bc16b1bb7fa6f7bd8d7f10da2c9b07..a26e352b29baf7b2bba45cac8a8c405760dfdaa8 100644 (file)
@@ -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;
index 4aea4571d453ca9072e2e4fe3b6efe8776e88a3e..8b6b1405d36531f4a357e5448c9febb82b91e31b 100644 (file)
@@ -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);
 
index 828118833f54813f69a0ff3e8d4383391058bd47..0e54ea5ddb035bd3f8f01d16fd4cc3d4302c3452 100644 (file)
@@ -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;
 
index e7ea4c6a4df5740149aed9cb353e4703d0e69df0..90a81fa2566944bccad6c1806dcc196c09896326 100644 (file)
 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);
 }
 
index f15c50351423b098bea583376804157f6d9063d8..7d1e8d88dd44b394602bd72e7e6060d6ebd74799 100644 (file)
@@ -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: