Loading ssl/packet.c +111 −117 Original line number Diff line number Diff line Loading @@ -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; } /* Loading @@ -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; } Loading Loading @@ -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) { Loading @@ -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; } Loading @@ -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); } /* Loading Loading @@ -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; } Loading Loading @@ -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; } ssl/packet_locl.h +28 −32 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 */ Loading @@ -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); Loading ssl/s3_lib.c +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading ssl/ssl_locl.h +5 −8 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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) Loading Loading @@ -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); Loading ssl/statem/statem_clnt.c +21 −21 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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 Loading
ssl/packet.c +111 −117 Original line number Diff line number Diff line Loading @@ -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; } /* Loading @@ -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; } Loading Loading @@ -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) { Loading @@ -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; } Loading @@ -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); } /* Loading Loading @@ -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; } Loading Loading @@ -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; }
ssl/packet_locl.h +28 −32 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 */ Loading @@ -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); Loading
ssl/s3_lib.c +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading
ssl/ssl_locl.h +5 −8 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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) Loading Loading @@ -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); Loading
ssl/statem/statem_clnt.c +21 −21 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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