Commit 0217dd19 authored by Matt Caswell's avatar Matt Caswell
Browse files

Move from explicit sub-packets to implicit ones



No need to declare an explicit sub-packet. Just start one.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent ae2f7b37
Loading
Loading
Loading
Loading
+111 −117
Original line number Diff line number Diff line
@@ -10,33 +10,35 @@
#include "packet_locl.h"

/*
 * Allocate bytes in the WPACKET_BUF for the output. This reserves the bytes
 * Allocate bytes in the WPACKET for the output. This reserves the bytes
 * and count them as "written", but doesn't actually do the writing.
 */
static unsigned char *WPACKET_BUF_allocate(WPACKET_BUF *wbuf, size_t len)
int WPACKET_allocate_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
{
    unsigned char *ret = wbuf->curr;
    if (pkt->subs == NULL || len == 0)
        return 0;

    if (SIZE_MAX - wbuf->written < len)
    if (SIZE_MAX - pkt->written < len)
        return 0;

    if (wbuf->maxsize > 0 && wbuf->written + len > wbuf->maxsize)
    if (pkt->maxsize > 0 && pkt->written + len > pkt->maxsize)
        return 0;

    if (wbuf->buf->length - wbuf->written < len) {
    if (pkt->buf->length - pkt->written < len) {
        size_t newlen;

        if (wbuf->buf->length > SIZE_MAX / 2)
        if (pkt->buf->length > SIZE_MAX / 2)
            newlen = SIZE_MAX;
        else
            newlen = wbuf->buf->length * 2;
        if (BUF_MEM_grow(wbuf->buf, newlen) == 0)
            return NULL;
            newlen = pkt->buf->length * 2;
        if (BUF_MEM_grow(pkt->buf, newlen) == 0)
            return 0;
    }
    wbuf->written += len;
    wbuf->curr += len;
    pkt->written += len;
    *allocbytes = pkt->curr;
    pkt->curr += len;

    return ret;
    return 1;
}

/*
@@ -47,39 +49,28 @@ static unsigned char *WPACKET_BUF_allocate(WPACKET_BUF *wbuf, size_t len)
 */
int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes)
{
    WPACKET_BUF *wbuf;
    /* Sanity check */
    if (buf == NULL)
        return 0;

    wbuf = OPENSSL_zalloc(sizeof(WPACKET_BUF));
    if (wbuf == NULL) {
        pkt->isclosed = 1;
        return 0;
    }

    wbuf->buf = buf;
    wbuf->curr = (unsigned char *)buf->data;
    wbuf->written = 0;
    wbuf->maxsize = 0;
    pkt->buf = buf;
    pkt->curr = (unsigned char *)buf->data;
    pkt->written = 0;
    pkt->maxsize = 0;

    pkt->parent = NULL;
    pkt->wbuf = wbuf;
    pkt->pwritten = lenbytes;
    pkt->lenbytes = lenbytes;
    pkt->haschild = 0;
    pkt->isclosed = 0;
    pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs));
    if (pkt->subs == NULL)
        return 0;

    if (lenbytes == 0) {
        pkt->packet_len = NULL;
    if (lenbytes == 0)
        return 1;
    }

    pkt->packet_len = WPACKET_BUF_allocate(wbuf, lenbytes);
    if (pkt->packet_len == NULL) {
        OPENSSL_free(wbuf);
        pkt->wbuf = NULL;
        pkt->isclosed = 1;
    pkt->subs->pwritten = lenbytes;
    pkt->subs->lenbytes = lenbytes;

    if (!WPACKET_allocate_bytes(pkt, lenbytes, &(pkt->subs->packet_len))) {
        OPENSSL_free(pkt->subs);
        pkt->subs = NULL;
        return 0;
    }

@@ -107,59 +98,61 @@ int WPACKET_set_packet_len(WPACKET *pkt, unsigned char *packet_len,
                           size_t lenbytes)
{
    /* We only allow this to be set once */
    if (pkt->isclosed || pkt->packet_len != NULL)
    if (pkt->subs == NULL)
        return 0;

    pkt->lenbytes = lenbytes;
    pkt->packet_len = packet_len;
    pkt->subs->lenbytes = lenbytes;
    pkt->subs->packet_len = packet_len;

    return 1;
}

int WPACKET_set_flags(WPACKET *pkt, unsigned int flags)
{
    pkt->flags = flags;
    if (pkt->subs == NULL)
        return 0;

    pkt->subs->flags = flags;

    return 1;
}


/*
 * Closes the WPACKET and marks it as invalid for future writes. It also writes
 * out the length of the packet to the required location (normally the start
 * of the WPACKET) if appropriate. A WPACKET cannot be closed if it has an
 * active sub-packet.
 * Internal helper function used by WPACKET_close() and WPACKET_finish() to
 * close a sub-packet and write out its length if necessary.
 */
int WPACKET_close(WPACKET *pkt)
static int wpacket_intern_close(WPACKET *pkt)
{
    size_t packlen;
    WPACKET_SUB *sub = pkt->subs;

    if (pkt->isclosed || pkt->haschild)
        return 0;

    packlen = pkt->wbuf->written - pkt->pwritten;
    if (packlen == 0 && pkt->flags & OPENSSL_WPACKET_FLAGS_NON_ZERO_LENGTH)
    packlen = pkt->written - sub->pwritten;
    if (packlen == 0
            && sub->flags & OPENSSL_WPACKET_FLAGS_NON_ZERO_LENGTH)
        return 0;

    if (packlen == 0
            && pkt->flags & OPENSSL_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) {
            && sub->flags & OPENSSL_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) {
        /* Deallocate any bytes allocated for the length of the WPACKET */
        if ((pkt->wbuf->curr - pkt->lenbytes) == pkt->packet_len) {
            pkt->wbuf->written -= pkt->lenbytes;
            pkt->wbuf->curr -= pkt->lenbytes;
        if ((pkt->curr - sub->lenbytes) == sub->packet_len) {
            pkt->written -= sub->lenbytes;
            pkt->curr -= sub->lenbytes;
        }

        /* Don't write out the packet length */
        pkt->packet_len = NULL;
        sub->packet_len = NULL;
    }

    /* Write out the WPACKET length if needed */
    if (pkt->packet_len != NULL) {
    if (sub->packet_len != NULL) {
        size_t lenbytes;

        lenbytes = pkt->lenbytes;
        lenbytes = sub->lenbytes;

        for (; lenbytes > 0; lenbytes--) {
            pkt->packet_len[lenbytes - 1] = (unsigned char)(packlen & 0xff);
            sub->packet_len[lenbytes - 1]
                = (unsigned char)(packlen & 0xff);
            packlen >>= 8;
        }
        if (packlen > 0) {
@@ -170,51 +163,74 @@ int WPACKET_close(WPACKET *pkt)
        }
    }

    if (pkt->parent != NULL) {
        if (pkt->parent->haschild != 1) {
            /* Should not happen! */
            return 0;
    pkt->subs = sub->parent;
    OPENSSL_free(sub);

    return 1;
}
        pkt->parent->haschild = 0;
        pkt->parent = NULL;

/*
 * Closes the most recent sub-packet. It also writes out the length of the
 * packet to the required location (normally the start of the WPACKET) if
 * appropriate. The top level WPACKET should be closed using WPACKET_finish()
 * instead of this function.
 */
int WPACKET_close(WPACKET *pkt)
{
    if (pkt->subs == NULL || pkt->subs->parent == NULL)
        return 0;

    return wpacket_intern_close(pkt);
}

    pkt->isclosed = 1;
/*
 * The same as WPACKET_close() but only for the top most WPACKET. Additionally
 * frees memory resources for this WPACKET.
 */
int WPACKET_finish(WPACKET *pkt)
{
    int ret;

    return 1;
    if (pkt->subs == NULL || pkt->subs->parent != NULL)
        return 0;

    ret = wpacket_intern_close(pkt);

    /* We free up memory no matter whether |ret| is zero or not */
    OPENSSL_free(pkt->subs);
    pkt->subs = NULL;
    return ret;
}

/*
 * Initialise a new sub-packet (|subpkt|), based on a parent (|pkt|).
 * Additionally |lenbytes| of data is preallocated at the start of the
 * sub-packet to store its length once we know it.
 * Initialise a new sub-packet. Additionally |lenbytes| of data is preallocated
 * at the start of the sub-packet to store its length once we know it.
 */
int WPACKET_get_sub_packet_len(WPACKET *pkt, WPACKET *subpkt, size_t lenbytes)
int WPACKET_start_sub_packet_len(WPACKET *pkt, size_t lenbytes)
{
    if (pkt->isclosed || pkt->haschild || subpkt == NULL)
    WPACKET_SUB *sub;

    if (pkt->subs == NULL)
        return 0;

    subpkt->parent = pkt;
    subpkt->wbuf = pkt->wbuf;
    subpkt->pwritten = pkt->wbuf->written + lenbytes;
    subpkt->lenbytes = lenbytes;
    subpkt->haschild = 0;
    subpkt->isclosed = 0;
    sub = OPENSSL_zalloc(sizeof(*sub));
    if (sub == NULL)
        return 0;

    sub->parent = pkt->subs;
    pkt->subs = sub;
    sub->pwritten = pkt->written + lenbytes;
    sub->lenbytes = lenbytes;

    if (lenbytes == 0) {
        subpkt->packet_len = NULL;
        pkt->haschild = 1;
        sub->packet_len = NULL;
        return 1;
    }

    subpkt->packet_len = WPACKET_BUF_allocate(pkt->wbuf, lenbytes);
    if (subpkt->packet_len == NULL) {
        subpkt->isclosed = 1;
    if (!WPACKET_allocate_bytes(pkt, lenbytes, &sub->packet_len)) {
        return 0;
    }

    pkt->haschild = 1;

    return 1;
}

@@ -222,31 +238,9 @@ int WPACKET_get_sub_packet_len(WPACKET *pkt, WPACKET *subpkt, size_t lenbytes)
 * Same as WPACKET_get_sub_packet_len() except no bytes are pre-allocated for
 * the sub-packet length.
 */
int WPACKET_get_sub_packet(WPACKET *pkt, WPACKET *subpkt)
int WPACKET_start_sub_packet(WPACKET *pkt)
{
    return WPACKET_get_sub_packet_len(pkt, subpkt, 0);
}

/*
 * Allocate some bytes in the WPACKET for writing. That number of bytes is
 * marked as having been written, and a pointer to their location is stored in
 * |*allocbytes|.
 */
int WPACKET_allocate_bytes(WPACKET *pkt, size_t bytes,
                           unsigned char **allocbytes)
{
    unsigned char *data;

    if (pkt->isclosed || pkt->haschild || bytes == 0)
        return 0;

    data = WPACKET_BUF_allocate(pkt->wbuf, bytes);
    if (data == NULL)
        return 0;

    *allocbytes = data;

    return 1;
    return WPACKET_start_sub_packet_len(pkt, 0);
}

/*
@@ -283,7 +277,7 @@ int WPACKET_put_bytes(WPACKET *pkt, unsigned int val, size_t bytes)
 */
int WPACKET_set_max_size(WPACKET *pkt, size_t maxsize)
{
    pkt->wbuf->maxsize = maxsize;
    pkt->maxsize = maxsize;

    return 1;
}
@@ -312,24 +306,24 @@ int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len)
 */
int WPACKET_get_total_written(WPACKET *pkt, size_t *written)
{
    if (pkt->isclosed || written == NULL)
    if (pkt->subs == NULL || written == NULL)
        return 0;

    *written = pkt->wbuf->curr - (unsigned char *)pkt->wbuf->buf->data;
    *written = pkt->written;

    return 1;
}

/*
 * Returns the length of this WPACKET so far. This excludes any bytes allocated
 * Returns the length of the last sub-packet. This excludes any bytes allocated
 * for the length itself.
 */
int WPACKET_get_length(WPACKET *pkt, size_t *len)
{
    if (pkt->isclosed || len == NULL)
    if (pkt->subs == NULL || len == NULL)
        return 0;

    *len = pkt->wbuf->written - pkt->pwritten;
    *len = pkt->written - pkt->subs->pwritten;

    return 1;
}
+28 −32
Original line number Diff line number Diff line
@@ -551,7 +551,29 @@ __owur static ossl_inline int PACKET_get_length_prefixed_3(PACKET *pkt,

/* Writeable packets */

typedef struct packetw_buf {
typedef struct wpacket_sub WPACKET_SUB;
struct wpacket_sub {
    /* The parent WPACKET_SUB if we have one or NULL otherwise */
    WPACKET_SUB *parent;

    /*
     * Pointer to where the length of this WPACKET goes (or NULL if we don't
     * write the length)
     */
    unsigned char *packet_len;

    /* Number of bytes in the packet_len */
    size_t lenbytes;

    /* Number of bytes written to the buf prior to this packet starting */
    size_t pwritten;

    /* Flags for this sub-packet */
    unsigned int flags;
};

typedef struct wpacket_st WPACKET;
struct wpacket_st {
    /* The buffer where we store the output data */
    BUF_MEM *buf;

@@ -566,36 +588,9 @@ typedef struct packetw_buf {
     * if no maximum
     */
    size_t maxsize;
} WPACKET_BUF;

typedef struct packetw_st WPACKET;
struct packetw_st {
    /* The parent WPACKET if we have one or NULL otherwise */
    WPACKET *parent;

    /* The actual buffer - shared with sub-packets */
    WPACKET_BUF *wbuf;

    /* Flags for this WPACKET */
    unsigned int flags;

    /*
     * Pointer to where the length of this WPACKET goes (or NULL if we don't
     * write the length)
     */
    unsigned char *packet_len;

    /* Number of bytes in the packet_len */
    size_t lenbytes;

    /* Number of bytes written to the buf prior to this packet starting */
    size_t pwritten;

    /* True if we have an active sub-packet or false otherwise */
    int haschild;

    /* True if WPACKET_close() has been called on this WPACKET */
    int isclosed;
    /* Our sub-packets (always at least one if not closed) */
    WPACKET_SUB *subs;
};

/* Flags */
@@ -614,8 +609,9 @@ int WPACKET_set_flags(WPACKET *pkt, unsigned int flags);
int WPACKET_set_packet_len(WPACKET *pkt, unsigned char *packet_len,
                           size_t lenbytes);
int WPACKET_close(WPACKET *pkt);
int WPACKET_get_sub_packet_len(WPACKET *pkt, WPACKET *subpkt, size_t lenbytes);
int WPACKET_get_sub_packet(WPACKET *pkt, WPACKET *subpkt);
int WPACKET_finish(WPACKET *pkt);
int WPACKET_start_sub_packet_len(WPACKET *pkt, size_t lenbytes);
int WPACKET_start_sub_packet(WPACKET *pkt);
int WPACKET_allocate_bytes(WPACKET *pkt, size_t bytes,
                           unsigned char **allocbytes);
int WPACKET_put_bytes(WPACKET *pkt, unsigned int val, size_t bytes);
+2 −2
Original line number Diff line number Diff line
@@ -2795,11 +2795,11 @@ int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len)
 * at that point.
 * TODO - RENAME ME
 */
int ssl3_set_handshake_header2(SSL *s, WPACKET *pkt, WPACKET *body, int htype)
int ssl3_set_handshake_header2(SSL *s, WPACKET *pkt, int htype)
{
    /* Set the content type and 3 bytes for the message len */
    if (!WPACKET_put_bytes(pkt, htype, 1)
            || !WPACKET_get_sub_packet_len(pkt, body, 3))
            || !WPACKET_start_sub_packet_len(pkt, 3))
        return 0;

    return 1;
+5 −8
Original line number Diff line number Diff line
@@ -1586,8 +1586,7 @@ typedef struct ssl3_enc_method {
    /* Set the handshake header */
    int (*set_handshake_header) (SSL *s, int type, unsigned long len);
    /* Set the handshake header */
    int (*set_handshake_header2) (SSL *s, WPACKET *pkt, WPACKET *body,
                                  int type);
    int (*set_handshake_header2) (SSL *s, WPACKET *pkt, int type);
    /* Close construction of the handshake message */
    int (*close_construct_packet) (SSL *s, WPACKET *pkt);
    /* Write out handshake message */
@@ -1599,8 +1598,8 @@ typedef struct ssl3_enc_method {
        (((unsigned char *)s->init_buf->data) + s->method->ssl3_enc->hhlen)
# define ssl_set_handshake_header(s, htype, len) \
        s->method->ssl3_enc->set_handshake_header(s, htype, len)
# define ssl_set_handshake_header2(s, pkt, body, htype) \
        s->method->ssl3_enc->set_handshake_header2((s), (pkt), (body), (htype))
# define ssl_set_handshake_header2(s, pkt, htype) \
        s->method->ssl3_enc->set_handshake_header2((s), (pkt), (htype))
# define ssl_close_construct_packet(s, pkt) \
        s->method->ssl3_enc->close_construct_packet((s), (pkt))
# define ssl_do_write(s)  s->method->ssl3_enc->do_write(s)
@@ -1906,11 +1905,9 @@ __owur int ssl3_do_change_cipher_spec(SSL *ssl);
__owur long ssl3_default_timeout(void);

__owur int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len);
__owur int ssl3_set_handshake_header2(SSL *s, WPACKET *pkt, WPACKET *body,
                                      int htype);
__owur int ssl3_set_handshake_header2(SSL *s, WPACKET *pkt, int htype);
__owur int tls_close_construct_packet(SSL *s, WPACKET *pkt);
__owur int dtls1_set_handshake_header2(SSL *s, WPACKET *pkt, WPACKET *body,
                                       int htype);
__owur int dtls1_set_handshake_header2(SSL *s, WPACKET *pkt, int htype);
__owur int dtls1_close_construct_packet(SSL *s, WPACKET *pkt);
__owur int ssl3_handshake_write(SSL *s);

+21 −21
Original line number Diff line number Diff line
@@ -697,7 +697,7 @@ int tls_construct_client_hello(SSL *s)
    SSL_COMP *comp;
#endif
    SSL_SESSION *sess = s->session;
    WPACKET pkt, body, spkt;
    WPACKET pkt;

    if (!WPACKET_init(&pkt, s->init_buf)
            || !WPACKET_set_max_size(&pkt, SSL3_RT_MAX_PLAIN_LENGTH)) {
@@ -746,7 +746,7 @@ int tls_construct_client_hello(SSL *s)
    if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random)) <= 0)
        goto err;

    if (!ssl_set_handshake_header2(s, &pkt, &body, SSL3_MT_CLIENT_HELLO)) {
    if (!ssl_set_handshake_header2(s, &pkt, SSL3_MT_CLIENT_HELLO)) {
        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        goto err;
@@ -782,8 +782,8 @@ int tls_construct_client_hello(SSL *s)
     * client_version in client hello and not resetting it to
     * the negotiated version.
     */
    if (!WPACKET_put_bytes(&body, s->client_version, 2)
            || !WPACKET_memcpy(&body, s->s3->client_random, SSL3_RANDOM_SIZE)) {
    if (!WPACKET_put_bytes(&pkt, s->client_version, 2)
            || !WPACKET_memcpy(&pkt, s->s3->client_random, SSL3_RANDOM_SIZE)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        goto err;
    }
@@ -794,9 +794,9 @@ int tls_construct_client_hello(SSL *s)
    else
        i = s->session->session_id_length;
    if (i > (int)sizeof(s->session->session_id)
            || !WPACKET_get_sub_packet_len(&body, &spkt, 1)
            || (i != 0 && !WPACKET_memcpy(&spkt, s->session->session_id, i))
            || !WPACKET_close(&spkt)) {
            || !WPACKET_start_sub_packet_len(&pkt, 1)
            || (i != 0 && !WPACKET_memcpy(&pkt, s->session->session_id, i))
            || !WPACKET_close(&pkt)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        goto err;
    }
@@ -804,29 +804,29 @@ int tls_construct_client_hello(SSL *s)
    /* cookie stuff for DTLS */
    if (SSL_IS_DTLS(s)) {
        if (s->d1->cookie_len > sizeof(s->d1->cookie)
                || !WPACKET_get_sub_packet_len(&body, &spkt, 1)
                || !WPACKET_memcpy(&spkt, s->d1->cookie, s->d1->cookie_len)
                || !WPACKET_close(&spkt)) {
                || !WPACKET_start_sub_packet_len(&pkt, 1)
                || !WPACKET_memcpy(&pkt, s->d1->cookie, s->d1->cookie_len)
                || !WPACKET_close(&pkt)) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
            goto err;
        }
    }

    /* Ciphers supported */
    if (!WPACKET_get_sub_packet_len(&body, &spkt, 2)) {
    if (!WPACKET_start_sub_packet_len(&pkt, 2)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    /* ssl_cipher_list_to_bytes() raises SSLerr if appropriate */
    if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &spkt))
    if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &pkt))
        goto err;
    if (!WPACKET_close(&spkt)) {
    if (!WPACKET_close(&pkt)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        goto err;
    }

    /* COMPRESSION */
    if (!WPACKET_get_sub_packet_len(&body, &spkt, 1)) {
    if (!WPACKET_start_sub_packet_len(&pkt, 1)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        goto err;
    }
@@ -835,7 +835,7 @@ int tls_construct_client_hello(SSL *s)
        int compnum = sk_SSL_COMP_num(s->ctx->comp_methods);
        for (i = 0; i < compnum; i++) {
            comp = sk_SSL_COMP_value(s->ctx->comp_methods, i);
            if (!WPACKET_put_bytes(&spkt, comp->id, 1)) {
            if (!WPACKET_put_bytes(&pkt, comp->id, 1)) {
                SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
                goto err;
            }
@@ -843,7 +843,7 @@ int tls_construct_client_hello(SSL *s)
    }
#endif
    /* Add the NULL method */
    if (!WPACKET_put_bytes(&spkt, 0, 1) || !WPACKET_close(&spkt)) {
    if (!WPACKET_put_bytes(&pkt, 0, 1) || !WPACKET_close(&pkt)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        goto err;
    }
@@ -853,21 +853,21 @@ int tls_construct_client_hello(SSL *s)
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
        goto err;
    }
    if (!WPACKET_get_sub_packet_len(&body, &spkt, 2)
    if (!WPACKET_start_sub_packet_len(&pkt, 2)
               /*
                * If extensions are of zero length then we don't even add the
                * extensions length bytes
                */
            || !WPACKET_set_flags(&spkt,
            || !WPACKET_set_flags(&pkt,
                                  OPENSSL_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)
            || !ssl_add_clienthello_tlsext(s, &spkt, &al)
            || !WPACKET_close(&spkt)) {
            || !ssl_add_clienthello_tlsext(s, &pkt, &al)
            || !WPACKET_close(&pkt)) {
        ssl3_send_alert(s, SSL3_AL_FATAL, al);
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        goto err;
    }

    if (!WPACKET_close(&body) || !ssl_close_construct_packet(s, &pkt)) {
    if (!WPACKET_close(&pkt) || !ssl_close_construct_packet(s, &pkt)) {
        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        goto err;
Loading