From ec30e8566e43d888ab1d7cf01749a979896bb3d9 Mon Sep 17 00:00:00 2001 From: Emilia Kasper Date: Tue, 18 Aug 2015 12:29:36 +0200 Subject: PACKET: add methods for reading length-prefixed TLS vectors. Rewrite ssl3_get_client_hello to use the new methods. Reviewed-by: Matt Caswell --- ssl/packet_locl.h | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'ssl/packet_locl.h') diff --git a/ssl/packet_locl.h b/ssl/packet_locl.h index 0d5d823..3f03fa7 100644 --- a/ssl/packet_locl.h +++ b/ssl/packet_locl.h @@ -88,6 +88,17 @@ __owur static inline size_t PACKET_remaining(const PACKET *pkt) } /* + * Returns a pointer to the PACKET's current position. + * For use in non-PACKETized APIs. + * TODO(openssl-team): this should return 'const unsigned char*' but can't + * currently because legacy code passes 'unsigned char*'s around. + */ +static inline unsigned char *PACKET_data(const PACKET *pkt) +{ + return pkt->curr; +} + +/* * Initialise a PACKET with |len| bytes held in |buf|. This does not make a * copy of the data so |buf| must be present for the whole time that the PACKET * is being used. @@ -388,6 +399,77 @@ __owur static inline int PACKET_length(const PACKET *pkt, size_t *len) return 1; } +/* + * Reads a variable-length vector prefixed with a one-byte length, and stores + * the contents in |subpkt|. |pkt| can equal |subpkt|. + * Data is not copied: the |subpkt| packet will share its underlying buffer with + * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. + * Upon failure, the original |pkt| and |subpkt| are not modified. + */ +__owur static inline int PACKET_get_length_prefixed_1(PACKET *pkt, PACKET *subpkt) +{ + unsigned int length; + unsigned char *data; + PACKET tmp = *pkt; + if (!PACKET_get_1(&tmp, &length) || + !PACKET_get_bytes(&tmp, &data, (size_t)length)) { + return 0; + } + + *pkt = tmp; + subpkt->start = subpkt->curr = data; + subpkt->end = subpkt->start + length; + + return 1; +} + +/* + * Reads a variable-length vector prefixed with a two-byte length, and stores + * the contents in |subpkt|. |pkt| can equal |subpkt|. + * Data is not copied: the |subpkt| packet will share its underlying buffer with + * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. + * Upon failure, the original |pkt| and |subpkt| are not modified. + */ +__owur static inline int PACKET_get_length_prefixed_2(PACKET *pkt, PACKET *subpkt) +{ + unsigned int length; + unsigned char *data; + PACKET tmp = *pkt; + if (!PACKET_get_net_2(&tmp, &length) || + !PACKET_get_bytes(&tmp, &data, (size_t)length)) { + return 0; + } + + *pkt = tmp; + subpkt->start = subpkt->curr = data; + subpkt->end = subpkt->start + length; + + return 1; +} + +/* + * Reads a variable-length vector prefixed with a three-byte length, and stores + * the contents in |subpkt|. |pkt| can equal |subpkt|. + * Data is not copied: the |subpkt| packet will share its underlying buffer with + * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. + * Upon failure, the original |pkt| and |subpkt| are not modified. + */ +__owur static inline int PACKET_get_length_prefixed_3(PACKET *pkt, PACKET *subpkt) +{ + unsigned long length; + unsigned char *data; + PACKET tmp = *pkt; + if (!PACKET_get_net_3(&tmp, &length) || + !PACKET_get_bytes(&tmp, &data, (size_t)length)) { + return 0; + } + + *pkt = tmp; + subpkt->start = subpkt->curr = data; + subpkt->end = subpkt->start + length; + + return 1; +} # ifdef __cplusplus } # endif -- cgit v1.1