Encapsulate access to s->s3->wbuf
[openssl.git] / ssl / s3_pkt.c
index a8fd16c096e9839449bde61758565af7405471cb..eb25f34ad4c6577d9636ee2737c2ca156e25571d 100644 (file)
@@ -142,7 +142,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
      * If extend == 0, obtain new n-byte packet; if extend == 1, increase
      * packet by another n bytes. The packet will be in the sub-array of
      * s->s3->rbuf.buf specified by s->packet and s->packet_length. (If
-     * s->read_ahead is set, 'max' bytes may be stored in rbuf [plus
+     * s->rlayer.read_ahead is set, 'max' bytes may be stored in rbuf [plus
      * s->packet_length bytes if extend == 1].)
      */
     int i, len, left;
@@ -153,7 +153,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
     if (n <= 0)
         return n;
 
-    rb = &(s->s3->rbuf);
+    rb = RECORD_LAYER_get_rbuf(&s->rlayer);
     if (rb->buf == NULL)
         if (!ssl3_setup_read_buffer(s))
             return -1;
@@ -232,7 +232,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
     }
 
     /* We always act like read_ahead is set for DTLS */
-    if (!s->read_ahead && !SSL_IS_DTLS(s))
+    if (!RECORD_LAYER_get_read_ahead(&s->rlayer) && !SSL_IS_DTLS(s))
         /* ignore max parameter */
         max = n;
     else {
@@ -336,7 +336,8 @@ static int ssl3_get_record(SSL *s)
     /* check if we have the header */
     if ((s->rstate != SSL_ST_READ_BODY) ||
         (s->packet_length < SSL3_RT_HEADER_LENGTH)) {
-        n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
+        n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH,
+            SSL3_BUFFER_get_len(RECORD_LAYER_get_rbuf(&s->rlayer)), 0);
         if (n <= 0)
             return (n);         /* error or non-blocking */
         s->rstate = SSL_ST_READ_BODY;
@@ -352,9 +353,6 @@ static int ssl3_get_record(SSL *s)
         ssl_minor = *(p++);
         version = (ssl_major << 8) | ssl_minor;
         n2s(p, rr->length);
-#if 0
-        fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
-#endif
 
         /* Lets check version */
         if (!s->first_packet) {
@@ -376,7 +374,9 @@ static int ssl3_get_record(SSL *s)
             goto err;
         }
 
-        if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) {
+        if (rr->length >
+                SSL3_BUFFER_get_len(RECORD_LAYER_get_rbuf(&s->rlayer))
+                - SSL3_RT_HEADER_LENGTH) {
             al = SSL_AD_RECORD_OVERFLOW;
             SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
             goto f_err;
@@ -585,10 +585,6 @@ static int ssl3_get_record(SSL *s)
         }
         goto again;
     }
-#if 0
-    fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type,
-            rr->length);
-#endif
 
     return (1);
 
@@ -649,7 +645,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
 #if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
     unsigned int max_send_fragment;
 #endif
-    SSL3_BUFFER *wb = &(s->s3->wbuf);
+    SSL3_BUFFER *wb = RECORD_LAYER_get_wbuf(&s->rlayer);
     int i;
     unsigned int u_len = (unsigned int)len;
 
@@ -734,6 +730,10 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
                 packlen *= 4;
 
             wb->buf = OPENSSL_malloc(packlen);
+            if(!wb->buf) {
+                SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_MALLOC_FAILURE);
+                return -1;
+            }
             wb->len = packlen;
         } else if (tot == len) { /* done? */
             OPENSSL_free(wb->buf); /* free jumbo buffer */
@@ -807,7 +807,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
 
             i = ssl3_write_pending(s, type, &buf[tot], nw);
             if (i <= 0) {
-                if (i < 0) {
+                if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) {
                     OPENSSL_free(wb->buf);
                     wb->buf = NULL;
                 }
@@ -875,7 +875,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
     int eivlen;
     long align = 0;
     SSL3_RECORD *wr;
-    SSL3_BUFFER *wb = &(s->s3->wbuf);
+    SSL3_BUFFER *wb = RECORD_LAYER_get_wbuf(&s->rlayer);
     SSL_SESSION *sess;
 
     /*
@@ -906,11 +906,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
     if ((sess == NULL) ||
         (s->enc_write_ctx == NULL) ||
         (EVP_MD_CTX_md(s->write_hash) == NULL)) {
-#if 1
         clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */
-#else
-        clear = 1;
-#endif
         mac_size = 0;
     } else {
         mac_size = EVP_MD_CTX_size(s->write_hash);
@@ -918,60 +914,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
             goto err;
     }
 
-#if 0 && !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
-    if (type == SSL3_RT_APPLICATION_DATA && s->compress == NULL &&
-        !SSL_USE_ETM(s) && SSL_USE_EXPLICIT_IV(s) &&
-        EVP_CIPHER_flags(s->enc_write_ctx->cipher) &
-        EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)
-        do {
-            unsigned char aad[13];
-            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param =
-                { NULL, aad, sizeof(aad), 0 };
-            int packlen;
-
-            memcpy(aad, s->s3->write_sequence, 8);
-            aad[8] = type;
-            aad[9] = (unsigned char)(s->version >> 8);
-            aad[10] = (unsigned char)(s->version);
-            aad[11] = (unsigned char)(len >> 8);
-            aad[12] = (unsigned char)len;
-            packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
-                                          EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
-                                          sizeof(mb_param), &mb_param);
-
-            if (packlen == 0 || packlen > wb->len)
-                break;
-
-            mb_param.out = wb->buf;
-            mb_param.inp = buf;
-            mb_param.len = len;
-            EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
-                                EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
-                                sizeof(mb_param), &mb_param);
-
-            s->s3->write_sequence[7] += mb_param.interleave;
-            if (s->s3->write_sequence[7] < mb_param.interleave) {
-                int j = 6;
-                while (j >= 0 && (++s->s3->write_sequence[j--]) == 0) ;
-            }
-
-            wb->offset = 0;
-            wb->left = packlen;
-
-            /*
-             * memorize arguments so that ssl3_write_pending can detect bad
-             * write retries later
-             */
-            s->s3->wpend_tot = len;
-            s->s3->wpend_buf = buf;
-            s->s3->wpend_type = type;
-            s->s3->wpend_ret = len;
-
-            /* we now just need to write the buffer */
-            return ssl3_write_pending(s, type, buf, len);
-        } while (0);
-#endif
-
     /*
      * 'create_empty_fragment' is true only when this function calls itself
      */
@@ -1158,7 +1100,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
                        unsigned int len)
 {
     int i;
-    SSL3_BUFFER *wb = &(s->s3->wbuf);
+    SSL3_BUFFER *wb = RECORD_LAYER_get_wbuf(&s->rlayer);
 
 /* XXXX */
     if ((s->s3->wpend_tot > (int)len)
@@ -1235,9 +1177,11 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
     SSL3_RECORD *rr;
     void (*cb) (const SSL *ssl, int type2, int val) = NULL;
 
-    if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
+    if (!SSL3_BUFFER_is_initialised(RECORD_LAYER_get_rbuf(&s->rlayer))) {
+        /* Not initialized yet */
         if (!ssl3_setup_read_buffer(s))
             return (-1);
+    }
 
     if ((type && (type != SSL3_RT_APPLICATION_DATA)
          && (type != SSL3_RT_HANDSHAKE)) || (peek
@@ -1349,7 +1293,8 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
                 s->rstate = SSL_ST_READ_HEADER;
                 rr->off = 0;
                 if (s->mode & SSL_MODE_RELEASE_BUFFERS
-                    && s->s3->rbuf.left == 0)
+                    && SSL3_BUFFER_get_left(
+                        RECORD_LAYER_get_rbuf(&s->rlayer)) == 0)
                     ssl3_release_read_buffer(s);
             }
         }
@@ -1381,7 +1326,10 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
         }
 #ifndef OPENSSL_NO_HEARTBEATS
         else if (rr->type == TLS1_RT_HEARTBEAT) {
-            tls1_process_heartbeat(s);
+            /* We can ignore 0 return values */
+            if(tls1_process_heartbeat(s) < 0) {
+                return -1;
+            }
 
             /* Exit and notify application to read again */
             rr->length = 0;
@@ -1449,7 +1397,9 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
                 }
 
                 if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
-                    if (s->s3->rbuf.left == 0) { /* no read-ahead left? */
+                    if (SSL3_BUFFER_get_left(
+                        RECORD_LAYER_get_rbuf(&s->rlayer)) == 0) {
+                        /* no read-ahead left? */
                         BIO *bio;
                         /*
                          * In the case where we try to read application data,
@@ -1512,7 +1462,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
             cb(s, SSL_CB_READ_ALERT, j);
         }
 
-        if (alert_level == 1) { /* warning */
+        if (alert_level == SSL3_AL_WARNING) {
             s->s3->warn_alert = alert_descr;
             if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
                 s->shutdown |= SSL_RECEIVED_SHUTDOWN;
@@ -1535,7 +1485,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
             else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
                 return (0);
 #endif
-        } else if (alert_level == 2) { /* fatal */
+        } else if (alert_level == SSL3_AL_FATAL) {
             char tmp[16];
 
             s->rwstate = SSL_NOTHING;
@@ -1608,15 +1558,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
     if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) {
         if (((s->state & SSL_ST_MASK) == SSL_ST_OK) &&
             !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
-#if 0                           /* worked only because C operator preferences
-                                 * are not as expected (and because this is
-                                 * not really needed for clients except for
-                                 * detecting protocol violations): */
-            s->state = SSL_ST_BEFORE | (s->server)
-                ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
-#else
             s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
-#endif
             s->renegotiate = 1;
             s->new_session = 1;
         }
@@ -1629,7 +1571,8 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
         }
 
         if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
-            if (s->s3->rbuf.left == 0) { /* no read-ahead left? */
+            if (SSL3_BUFFER_get_left(RECORD_LAYER_get_rbuf(&s->rlayer)) == 0) {
+                /* no read-ahead left? */
                 BIO *bio;
                 /*
                  * In the case where we try to read application data, but we
@@ -1772,8 +1715,10 @@ int ssl3_send_alert(SSL *s, int level, int desc)
     s->s3->alert_dispatch = 1;
     s->s3->send_alert[0] = level;
     s->s3->send_alert[1] = desc;
-    if (s->s3->wbuf.left == 0)  /* data still being written out? */
+    if (SSL3_BUFFER_get_left(RECORD_LAYER_get_wbuf(&s->rlayer)) == 0) {
+        /* data still being written out? */
         return s->method->ssl_dispatch_alert(s);
+    }
     /*
      * else data is still being written out, we will get written some time in
      * the future