Rename ssl_set_handshake_header2()
[openssl.git] / ssl / statem / statem_srvr.c
index eae0e3cadcfc3ebde6e29daaf9fe406829ed683a..cc737ba846a1214d1282014431e849c451690d0d 100644 (file)
@@ -834,7 +834,7 @@ int tls_construct_hello_request(SSL *s)
     WPACKET pkt;
 
     if (!WPACKET_init(&pkt, s->init_buf)
-            || !ssl_set_handshake_header2(s, &pkt, SSL3_MT_HELLO_REQUEST)
+            || !ssl_set_handshake_header(s, &pkt, SSL3_MT_HELLO_REQUEST)
             || !ssl_close_construct_packet(s, &pkt)) {
         SSLerr(SSL_F_TLS_CONSTRUCT_HELLO_REQUEST, ERR_R_INTERNAL_ERROR);
         ossl_statem_set_error(s);
@@ -872,8 +872,8 @@ int dtls_construct_hello_verify_request(SSL *s)
     }
 
     if (!WPACKET_init(&pkt, s->init_buf)
-            || !ssl_set_handshake_header2(s, &pkt,
-                                          DTLS1_MT_HELLO_VERIFY_REQUEST)
+            || !ssl_set_handshake_header(s, &pkt,
+                                         DTLS1_MT_HELLO_VERIFY_REQUEST)
             || !dtls_raw_hello_verify_request(&pkt, s->d1->cookie,
                                               s->d1->cookie_len)
                /*
@@ -1504,7 +1504,7 @@ int tls_construct_server_hello(SSL *s)
     WPACKET pkt;
 
     if (!WPACKET_init(&pkt, s->init_buf)
-            || !ssl_set_handshake_header2(s, &pkt, SSL3_MT_SERVER_HELLO)
+            || !ssl_set_handshake_header(s, &pkt, SSL3_MT_SERVER_HELLO)
             || !WPACKET_put_bytes_u16(&pkt, s->version)
                /*
                 * Random stuff. Filling of the server_random takes place in
@@ -1572,19 +1572,26 @@ int tls_construct_server_hello(SSL *s)
 
 int tls_construct_server_done(SSL *s)
 {
-    if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) {
+    WPACKET pkt;
+
+    if (!WPACKET_init(&pkt, s->init_buf)
+            || !ssl_set_handshake_header(s, &pkt, SSL3_MT_SERVER_DONE)
+            || !ssl_close_construct_packet(s, &pkt)) {
         SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_DONE, ERR_R_INTERNAL_ERROR);
-        ossl_statem_set_error(s);
-        return 0;
+        goto err;
     }
 
     if (!s->s3->tmp.cert_request) {
-        if (!ssl3_digest_cached_records(s, 0)) {
-            ossl_statem_set_error(s);
-        }
+        if (!ssl3_digest_cached_records(s, 0))
+            goto err;
     }
-
     return 1;
+
+ err:
+    WPACKET_cleanup(&pkt);
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+    ossl_statem_set_error(s);
+    return 0;
 }
 
 int tls_construct_server_key_exchange(SSL *s)
@@ -1607,8 +1614,8 @@ int tls_construct_server_key_exchange(SSL *s)
     size_t paramlen, paramoffset;
 
     if (!WPACKET_init(&pkt, s->init_buf)
-            || !ssl_set_handshake_header2(s, &pkt,
-                                          SSL3_MT_SERVER_KEY_EXCHANGE)
+            || !ssl_set_handshake_header(s, &pkt,
+                                         SSL3_MT_SERVER_KEY_EXCHANGE)
             || !WPACKET_get_total_written(&pkt, &paramoffset)) {
         SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
         goto f_err;
@@ -1943,8 +1950,8 @@ int tls_construct_certificate_request(SSL *s)
     WPACKET pkt;
 
     if (!WPACKET_init(&pkt, s->init_buf)
-            || !ssl_set_handshake_header2(s, &pkt,
-                                          SSL3_MT_CERTIFICATE_REQUEST)) {
+            || !ssl_set_handshake_header(s, &pkt,
+                                         SSL3_MT_CERTIFICATE_REQUEST)) {
         SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
         goto err;
     }
@@ -2949,15 +2956,17 @@ int tls_construct_new_session_ticket(SSL *s)
     unsigned char *senc = NULL;
     EVP_CIPHER_CTX *ctx = NULL;
     HMAC_CTX *hctx = NULL;
-    unsigned char *p, *macstart;
+    unsigned char *p, *encdata1, *encdata2, *macdata1, *macdata2;
     const unsigned char *const_p;
-    int len, slen_full, slen;
+    int len, slen_full, slen, lenfinal;
     SSL_SESSION *sess;
     unsigned int hlen;
     SSL_CTX *tctx = s->initial_ctx;
     unsigned char iv[EVP_MAX_IV_LENGTH];
     unsigned char key_name[TLSEXT_KEYNAME_LENGTH];
     int iv_len;
+    size_t macoffset, macendoffset;
+    WPACKET pkt;
 
     /* get session encoding length */
     slen_full = i2d_SSL_SESSION(s->session, NULL);
@@ -2975,6 +2984,12 @@ int tls_construct_new_session_ticket(SSL *s)
         return 0;
     }
 
+    if (!WPACKET_init(&pkt, s->init_buf)
+            || !ssl_set_handshake_header(s, &pkt, SSL3_MT_NEWSESSION_TICKET)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
     ctx = EVP_CIPHER_CTX_new();
     hctx = HMAC_CTX_new();
     if (ctx == NULL || hctx == NULL) {
@@ -3007,21 +3022,6 @@ int tls_construct_new_session_ticket(SSL *s)
     }
     SSL_SESSION_free(sess);
 
-    /*-
-     * Grow buffer if need be: the length calculation is as
-     * follows handshake_header_length +
-     * 4 (ticket lifetime hint) + 2 (ticket length) +
-     * sizeof(keyname) + max_iv_len (iv length) +
-     * max_enc_block_size (max encrypted session * length) +
-     * max_md_size (HMAC) + session_length.
-     */
-    if (!BUF_MEM_grow(s->init_buf,
-                      SSL_HM_HEADER_LENGTH(s) + 6 + sizeof(key_name) +
-                      EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
-                      EVP_MAX_MD_SIZE + slen))
-        goto err;
-
-    p = ssl_handshake_start(s);
     /*
      * Initialize HMAC and cipher contexts. If callback present it does
      * all the work otherwise use generated values from parent ctx.
@@ -3032,11 +3032,15 @@ int tls_construct_new_session_ticket(SSL *s)
                                              hctx, 1);
 
         if (ret == 0) {
-            l2n(0, p);          /* timeout */
-            s2n(0, p);          /* length */
-            if (!ssl_set_handshake_header
-                (s, SSL3_MT_NEWSESSION_TICKET, p - ssl_handshake_start(s)))
+
+            /* Put timeout and length */
+            if (!WPACKET_put_bytes_u32(&pkt, 0)
+                    || !WPACKET_put_bytes_u16(&pkt, 0)
+                    || !ssl_close_construct_packet(s, &pkt)) {
+                SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
+                       ERR_R_INTERNAL_ERROR);
                 goto err;
+            }
             OPENSSL_free(senc);
             EVP_CIPHER_CTX_free(ctx);
             HMAC_CTX_free(hctx);
@@ -3067,44 +3071,40 @@ int tls_construct_new_session_ticket(SSL *s)
      * for resumed session (for simplicity), and guess that tickets for
      * new sessions will live as long as their sessions.
      */
-    l2n(s->hit ? 0 : s->session->timeout, p);
-
-    /* Skip ticket length for now */
-    p += 2;
-    /* Output key name */
-    macstart = p;
-    memcpy(p, key_name, sizeof(key_name));
-    p += sizeof(key_name);
-    /* output IV */
-    memcpy(p, iv, iv_len);
-    p += iv_len;
-    /* Encrypt session data */
-    if (!EVP_EncryptUpdate(ctx, p, &len, senc, slen))
-        goto err;
-    p += len;
-    if (!EVP_EncryptFinal(ctx, p, &len))
-        goto err;
-    p += len;
-
-    if (!HMAC_Update(hctx, macstart, p - macstart))
-        goto err;
-    if (!HMAC_Final(hctx, p, &hlen))
+    if (!WPACKET_put_bytes_u32(&pkt, s->hit ? 0 : s->session->timeout)
+               /* Now the actual ticket data */
+            || !WPACKET_start_sub_packet_u16(&pkt)
+            || !WPACKET_get_total_written(&pkt, &macoffset)
+               /* Output key name */
+            || !WPACKET_memcpy(&pkt, key_name, sizeof(key_name))
+               /* output IV */
+            || !WPACKET_memcpy(&pkt, iv, iv_len)
+            || !WPACKET_reserve_bytes(&pkt, slen + EVP_MAX_BLOCK_LENGTH,
+                                      &encdata1)
+               /* Encrypt session data */
+            || !EVP_EncryptUpdate(ctx, encdata1, &len, senc, slen)
+            || !WPACKET_allocate_bytes(&pkt, len, &encdata2)
+            || encdata1 != encdata2
+            || !EVP_EncryptFinal(ctx, encdata1 + len, &lenfinal)
+            || !WPACKET_allocate_bytes(&pkt, lenfinal, &encdata2)
+            || encdata1 + len != encdata2
+            || len + lenfinal > slen + EVP_MAX_BLOCK_LENGTH
+            || !WPACKET_get_total_written(&pkt, &macendoffset)
+            || !HMAC_Update(hctx,
+                            (unsigned char *)s->init_buf->data + macoffset,
+                            macendoffset - macoffset)
+            || !WPACKET_reserve_bytes(&pkt, EVP_MAX_MD_SIZE, &macdata1)
+            || !HMAC_Final(hctx, macdata1, &hlen)
+            || hlen > EVP_MAX_MD_SIZE
+            || !WPACKET_allocate_bytes(&pkt, hlen, &macdata2)
+            || macdata1 != macdata2
+            || !WPACKET_close(&pkt)
+            || !ssl_close_construct_packet(s, &pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
         goto err;
-
+    }
     EVP_CIPHER_CTX_free(ctx);
     HMAC_CTX_free(hctx);
-    ctx = NULL;
-    hctx = NULL;
-
-    p += hlen;
-    /* Now write out lengths: p points to end of data written */
-    /* Total length */
-    len = p - ssl_handshake_start(s);
-    /* Skip ticket lifetime hint */
-    p = ssl_handshake_start(s) + 4;
-    s2n(len - 6, p);
-    if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len))
-        goto err;
     OPENSSL_free(senc);
 
     return 1;
@@ -3112,42 +3112,30 @@ int tls_construct_new_session_ticket(SSL *s)
     OPENSSL_free(senc);
     EVP_CIPHER_CTX_free(ctx);
     HMAC_CTX_free(hctx);
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
     ossl_statem_set_error(s);
+    WPACKET_cleanup(&pkt);
     return 0;
 }
 
 int tls_construct_cert_status(SSL *s)
 {
-    unsigned char *p;
-    size_t msglen;
-
-    /*-
-     * Grow buffer if need be: the length calculation is as
-     * follows handshake_header_length +
-     * 1 (ocsp response type) + 3 (ocsp response length)
-     * + (ocsp response)
-     */
-    msglen = 4 + s->tlsext_ocsp_resplen;
-    if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + msglen))
-        goto err;
-
-    p = ssl_handshake_start(s);
-
-    /* status type */
-    *(p++) = s->tlsext_status_type;
-    /* length of OCSP response */
-    l2n3(s->tlsext_ocsp_resplen, p);
-    /* actual response */
-    memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen);
+    WPACKET pkt;
 
-    if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_STATUS, msglen))
-        goto err;
+    if (!WPACKET_init(&pkt, s->init_buf)
+            || !ssl_set_handshake_header(s, &pkt, SSL3_MT_CERTIFICATE_STATUS)
+            || !WPACKET_put_bytes_u8(&pkt, s->tlsext_status_type)
+            || !WPACKET_sub_memcpy_u24(&pkt, s->tlsext_ocsp_resp,
+                                       s->tlsext_ocsp_resplen)
+            || !ssl_close_construct_packet(s, &pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CERT_STATUS, ERR_R_INTERNAL_ERROR);
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+        ossl_statem_set_error(s);
+        WPACKET_cleanup(&pkt);
+        return 0;
+    }
 
     return 1;
-
- err:
-    ossl_statem_set_error(s);
-    return 0;
 }
 
 #ifndef OPENSSL_NO_NEXTPROTONEG