Move handshake_fragment, handshake_fragment_len, alert_fragment and
[openssl.git] / ssl / record / s3_pkt.c
index 376697f744c150958763ec6c0dbd05cc379b284c..fea7dbbb03c2754325b8a1798f2b99820c0c857c 100644 (file)
 # define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
 #endif
 
+void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s)
+{
+    rl->s = s;
+    SSL3_RECORD_clear(&rl->rrec);
+    SSL3_RECORD_clear(&rl->wrec);
+}
+
 void RECORD_LAYER_clear(RECORD_LAYER *rl)
 {
     unsigned char *rp, *wp;
@@ -156,6 +163,7 @@ void RECORD_LAYER_clear(RECORD_LAYER *rl)
      * that right?
      */
     rl->read_ahead = read_ahead;
+    rl->rstate = SSL_ST_READ_HEADER;
     rl->s = s;
 }
 
@@ -180,20 +188,80 @@ int RECORD_LAYER_write_pending(RECORD_LAYER *rl)
 
 int RECORD_LAYER_set_data(RECORD_LAYER *rl, const unsigned char *buf, int len)
 {
-    rl->s->packet_length = len;
+    rl->packet_length = len;
     if(len != 0) {
-        rl->s->rstate = SSL_ST_READ_HEADER;
+        rl->rstate = SSL_ST_READ_HEADER;
         if (!SSL3_BUFFER_is_initialised(&rl->rbuf))
             if (!ssl3_setup_read_buffer(rl->s))
                 return 0;
     }
 
-    rl->s->packet = SSL3_BUFFER_get_buf(&rl->rbuf);
+    rl->packet = SSL3_BUFFER_get_buf(&rl->rbuf);
     SSL3_BUFFER_set_data(&rl->rbuf, buf, len);
 
     return 1;
 }
 
+void RECORD_LAYER_dup(RECORD_LAYER *dst, RECORD_LAYER *src)
+{
+    /*
+     * Currently only called from SSL_dup...which only seems to expect the
+     * rstate to be duplicated and nothing else from the RECORD_LAYER???
+     */
+    dst->rstate = src->rstate;
+}
+
+int ssl3_pending(const SSL *s)
+{
+    if (s->rlayer.rstate == SSL_ST_READ_BODY)
+        return 0;
+
+    return (SSL3_RECORD_get_type(&s->rlayer.rrec) == SSL3_RT_APPLICATION_DATA)
+           ? SSL3_RECORD_get_length(&s->rlayer.rrec) : 0;
+}
+
+const char *SSL_rstate_string_long(const SSL *s)
+{
+    const char *str;
+
+    switch (s->rlayer.rstate) {
+    case SSL_ST_READ_HEADER:
+        str = "read header";
+        break;
+    case SSL_ST_READ_BODY:
+        str = "read body";
+        break;
+    case SSL_ST_READ_DONE:
+        str = "read done";
+        break;
+    default:
+        str = "unknown";
+        break;
+    }
+    return (str);
+}
+
+const char *SSL_rstate_string(const SSL *s)
+{
+    const char *str;
+
+    switch (s->rlayer.rstate) {
+    case SSL_ST_READ_HEADER:
+        str = "RH";
+        break;
+    case SSL_ST_READ_BODY:
+        str = "RB";
+        break;
+    case SSL_ST_READ_DONE:
+        str = "RD";
+        break;
+    default:
+        str = "unknown";
+        break;
+    }
+    return (str);
+}
+
 int ssl3_read_n(SSL *s, int n, int max, int extend)
 {
     /*
@@ -211,7 +279,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
     if (n <= 0)
         return n;
 
-    rb = RECORD_LAYER_get_rbuf(&s->rlayer);
+    rb = &s->rlayer.rbuf;
     if (rb->buf == NULL)
         if (!ssl3_setup_read_buffer(s))
             return -1;
@@ -245,8 +313,8 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
                 rb->offset = align;
             }
         }
-        s->packet = rb->buf + rb->offset;
-        s->packet_length = 0;
+        s->rlayer.packet = rb->buf + rb->offset;
+        s->rlayer.packet_length = 0;
         /* ... now we can act as if 'extend' was set */
     }
 
@@ -264,7 +332,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
 
     /* if there is enough in the buffer from a previous read, take some */
     if (left >= n) {
-        s->packet_length += n;
+        s->rlayer.packet_length += n;
         rb->left = left - n;
         rb->offset += n;
         return (n);
@@ -272,15 +340,15 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
 
     /* else we need to read more data */
 
-    len = s->packet_length;
+    len = s->rlayer.packet_length;
     pkt = rb->buf + align;
     /*
      * Move any available bytes to front of buffer: 'len' bytes already
      * pointed to by 'packet', 'left' extra ones at the end
      */
-    if (s->packet != pkt) {     /* len > 0 */
-        memmove(pkt, s->packet, len + left);
-        s->packet = pkt;
+    if (s->rlayer.packet != pkt) {     /* len > 0 */
+        memmove(pkt, s->rlayer.packet, len + left);
+        s->rlayer.packet = pkt;
         rb->offset = len + align;
     }
 
@@ -290,7 +358,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
     }
 
     /* We always act like read_ahead is set for DTLS */
-    if (!RECORD_LAYER_get_read_ahead(&s->rlayer) && !SSL_IS_DTLS(s))
+    if (&s->rlayer.read_ahead && !SSL_IS_DTLS(s))
         /* ignore max parameter */
         max = n;
     else {
@@ -338,7 +406,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
     /* done reading, now the book-keeping */
     rb->offset += n;
     rb->left = left - n;
-    s->packet_length += n;
+    s->rlayer.packet_length += n;
     s->rwstate = SSL_NOTHING;
     return (n);
 }
@@ -356,7 +424,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 = RECORD_LAYER_get_wbuf(&s->rlayer);
+    SSL3_BUFFER *wb = &s->rlayer.wbuf;
     int i;
     unsigned int u_len = (unsigned int)len;
 
@@ -366,9 +434,9 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
     }
 
     s->rwstate = SSL_NOTHING;
-    OPENSSL_assert(s->s3->wnum <= INT_MAX);
-    tot = s->s3->wnum;
-    s->s3->wnum = 0;
+    OPENSSL_assert(s->rlayer.wnum <= INT_MAX);
+    tot = s->rlayer.wnum;
+    s->rlayer.wnum = 0;
 
     if (SSL_in_init(s) && !s->in_handshake) {
         i = s->handshake_func(s);
@@ -402,7 +470,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
         i = ssl3_write_pending(s, type, &buf[tot], s->s3->wpend_tot);
         if (i <= 0) {
             /* XXX should we ssl3_release_write_buffer if i<0? */
-            s->s3->wnum = tot;
+            s->rlayer.wnum = tot;
             return i;
         }
         tot += i;               /* this might be last fragment */
@@ -463,7 +531,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
             if (s->s3->alert_dispatch) {
                 i = s->method->ssl_dispatch_alert(s);
                 if (i <= 0) {
-                    s->s3->wnum = tot;
+                    s->rlayer.wnum = tot;
                     return i;
                 }
             }
@@ -522,7 +590,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
                     OPENSSL_free(wb->buf);
                     wb->buf = NULL;
                 }
-                s->s3->wnum = tot;
+                s->rlayer.wnum = tot;
                 return i;
             }
             if (i == (int)n) {
@@ -552,7 +620,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
         i = do_ssl3_write(s, type, &(buf[tot]), nw, 0);
         if (i <= 0) {
             /* XXX should we ssl3_release_write_buffer if i<0? */
-            s->s3->wnum = tot;
+            s->rlayer.wnum = tot;
             return i;
         }
 
@@ -586,7 +654,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
     int eivlen;
     long align = 0;
     SSL3_RECORD *wr;
-    SSL3_BUFFER *wb = RECORD_LAYER_get_wbuf(&s->rlayer);
+    SSL3_BUFFER *wb = &s->rlayer.wbuf;
     SSL_SESSION *sess;
 
     /*
@@ -611,7 +679,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
     if (len == 0 && !create_empty_fragment)
         return 0;
 
-    wr = RECORD_LAYER_get_wrec(&s->rlayer);
+    wr = &s->rlayer.wrec;
     sess = s->session;
 
     if ((sess == NULL) ||
@@ -811,7 +879,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
                        unsigned int len)
 {
     int i;
-    SSL3_BUFFER *wb = RECORD_LAYER_get_wbuf(&s->rlayer);
+    SSL3_BUFFER *wb = &s->rlayer.wbuf;
 
 /* XXXX */
     if ((s->s3->wpend_tot > (int)len)
@@ -888,7 +956,7 @@ 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 (!SSL3_BUFFER_is_initialised(RECORD_LAYER_get_rbuf(&s->rlayer))) {
+    if (!SSL3_BUFFER_is_initialised(&s->rlayer.rbuf)) {
         /* Not initialized yet */
         if (!ssl3_setup_read_buffer(s))
             return (-1);
@@ -902,29 +970,29 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
         return -1;
     }
 
-    if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0))
+    if ((type == SSL3_RT_HANDSHAKE) && (s->rlayer.handshake_fragment_len > 0))
         /* (partially) satisfy request from storage */
     {
-        unsigned char *src = s->s3->handshake_fragment;
+        unsigned char *src = s->rlayer.handshake_fragment;
         unsigned char *dst = buf;
         unsigned int k;
 
         /* peek == 0 */
         n = 0;
-        while ((len > 0) && (s->s3->handshake_fragment_len > 0)) {
+        while ((len > 0) && (s->rlayer.handshake_fragment_len > 0)) {
             *dst++ = *src++;
             len--;
-            s->s3->handshake_fragment_len--;
+            s->rlayer.handshake_fragment_len--;
             n++;
         }
         /* move any remaining fragment bytes: */
-        for (k = 0; k < s->s3->handshake_fragment_len; k++)
-            s->s3->handshake_fragment[k] = *src++;
+        for (k = 0; k < s->rlayer.handshake_fragment_len; k++)
+            s->rlayer.handshake_fragment[k] = *src++;
         return n;
     }
 
     /*
-     * Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE.
+     * Now s->rlayer.handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE.
      */
 
     if (!s->in_handshake && SSL_in_init(s)) {
@@ -946,10 +1014,10 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
      * s->s3->rrec.off,     - offset into 'data' for next read
      * s->s3->rrec.length,  - number of bytes.
      */
-    rr = RECORD_LAYER_get_rrec(&s->rlayer);
+    rr = &s->rlayer.rrec;
 
     /* get new packet if necessary */
-    if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) {
+    if ((rr->length == 0) || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
         ret = ssl3_get_record(s);
         if (ret <= 0)
             return (ret);
@@ -1001,11 +1069,10 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
             rr->length -= n;
             rr->off += n;
             if (rr->length == 0) {
-                s->rstate = SSL_ST_READ_HEADER;
+                s->rlayer.rstate = SSL_ST_READ_HEADER;
                 rr->off = 0;
                 if (s->mode & SSL_MODE_RELEASE_BUFFERS
-                    && SSL3_BUFFER_get_left(
-                        RECORD_LAYER_get_rbuf(&s->rlayer)) == 0)
+                    && SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0)
                     ssl3_release_read_buffer(s);
             }
         }
@@ -1027,18 +1094,19 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
         unsigned int *dest_len = NULL;
 
         if (rr->type == SSL3_RT_HANDSHAKE) {
-            dest_maxlen = sizeof s->s3->handshake_fragment;
-            dest = s->s3->handshake_fragment;
-            dest_len = &s->s3->handshake_fragment_len;
+            dest_maxlen = sizeof s->rlayer.handshake_fragment;
+            dest = s->rlayer.handshake_fragment;
+            dest_len = &s->rlayer.handshake_fragment_len;
         } else if (rr->type == SSL3_RT_ALERT) {
-            dest_maxlen = sizeof s->s3->alert_fragment;
-            dest = s->s3->alert_fragment;
-            dest_len = &s->s3->alert_fragment_len;
+            dest_maxlen = sizeof s->rlayer.alert_fragment;
+            dest = s->rlayer.alert_fragment;
+            dest_len = &s->rlayer.alert_fragment_len;
         }
 #ifndef OPENSSL_NO_HEARTBEATS
         else if (rr->type == TLS1_RT_HEARTBEAT) {
             /* We can ignore 0 return values */
-            if(tls1_process_heartbeat(s) < 0) {
+            if(tls1_process_heartbeat(s, SSL3_RECORD_get_data(&s->rlayer.rrec),
+                    SSL3_RECORD_get_length(&s->rlayer.rrec)) < 0) {
                 return -1;
             }
 
@@ -1068,21 +1136,21 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
     }
 
     /*-
-     * s->s3->handshake_fragment_len == 4  iff  rr->type == SSL3_RT_HANDSHAKE;
-     * s->s3->alert_fragment_len == 2      iff  rr->type == SSL3_RT_ALERT.
+     * s->rlayer.handshake_fragment_len == 4  iff  rr->type == SSL3_RT_HANDSHAKE;
+     * s->rlayer.alert_fragment_len == 2      iff  rr->type == SSL3_RT_ALERT.
      * (Possibly rr is 'empty' now, i.e. rr->length may be 0.)
      */
 
     /* If we are a client, check for an incoming 'Hello Request': */
     if ((!s->server) &&
-        (s->s3->handshake_fragment_len >= 4) &&
-        (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
+        (s->rlayer.handshake_fragment_len >= 4) &&
+        (s->rlayer.handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
         (s->session != NULL) && (s->session->cipher != NULL)) {
-        s->s3->handshake_fragment_len = 0;
+        s->rlayer.handshake_fragment_len = 0;
 
-        if ((s->s3->handshake_fragment[1] != 0) ||
-            (s->s3->handshake_fragment[2] != 0) ||
-            (s->s3->handshake_fragment[3] != 0)) {
+        if ((s->rlayer.handshake_fragment[1] != 0) ||
+            (s->rlayer.handshake_fragment[2] != 0) ||
+            (s->rlayer.handshake_fragment[3] != 0)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST);
             goto f_err;
@@ -1090,7 +1158,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
 
         if (s->msg_callback)
             s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
-                            s->s3->handshake_fragment, 4, s,
+                            s->rlayer.handshake_fragment, 4, s,
                             s->msg_callback_arg);
 
         if (SSL_is_init_finished(s) &&
@@ -1108,8 +1176,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
                 }
 
                 if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
-                    if (SSL3_BUFFER_get_left(
-                        RECORD_LAYER_get_rbuf(&s->rlayer)) == 0) {
+                    if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
                         /* no read-ahead left? */
                         BIO *bio;
                         /*
@@ -1142,26 +1209,24 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
         SSL_is_init_finished(s) &&
         !s->s3->send_connection_binding &&
         (s->version > SSL3_VERSION) &&
-        (s->s3->handshake_fragment_len >= 4) &&
-        (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
+        (s->rlayer.handshake_fragment_len >= 4) &&
+        (s->rlayer.handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
         (s->session != NULL) && (s->session->cipher != NULL) &&
         !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
-        /*
-         * s->s3->handshake_fragment_len = 0;
-         */
         rr->length = 0;
         ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
         goto start;
     }
-    if (s->s3->alert_fragment_len >= 2) {
-        int alert_level = s->s3->alert_fragment[0];
-        int alert_descr = s->s3->alert_fragment[1];
+    if (s->rlayer.alert_fragment_len >= 2) {
+        int alert_level = s->rlayer.alert_fragment[0];
+        int alert_descr = s->rlayer.alert_fragment[1];
 
-        s->s3->alert_fragment_len = 0;
+        s->rlayer.alert_fragment_len = 0;
 
         if (s->msg_callback)
             s->msg_callback(0, s->version, SSL3_RT_ALERT,
-                            s->s3->alert_fragment, 2, s, s->msg_callback_arg);
+                            s->rlayer.alert_fragment, 2, s,
+                            s->msg_callback_arg);
 
         if (s->info_callback != NULL)
             cb = s->info_callback;
@@ -1266,7 +1331,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
     /*
      * Unexpected handshake message (Client Hello, or protocol violation)
      */
-    if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) {
+    if ((s->rlayer.handshake_fragment_len >= 4) && !s->in_handshake) {
         if (((s->state & SSL_ST_MASK) == SSL_ST_OK) &&
             !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
             s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
@@ -1282,7 +1347,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
         }
 
         if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
-            if (SSL3_BUFFER_get_left(RECORD_LAYER_get_rbuf(&s->rlayer)) == 0) {
+            if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
                 /* no read-ahead left? */
                 BIO *bio;
                 /*