Home | History | Annotate | Download | only in openssh
      1 /*	$OpenBSD: sshbuf.h,v 1.8 2016/11/25 23:22:04 djm Exp $	*/
      2 /*
      3  * Copyright (c) 2011 Damien Miller
      4  *
      5  * Permission to use, copy, modify, and distribute this software for any
      6  * purpose with or without fee is hereby granted, provided that the above
      7  * copyright notice and this permission notice appear in all copies.
      8  *
      9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16  */
     17 
     18 #ifndef _SSHBUF_H
     19 #define _SSHBUF_H
     20 
     21 #include <sys/types.h>
     22 #include <stdarg.h>
     23 #include <stdio.h>
     24 #ifdef WITH_OPENSSL
     25 # include <openssl/bn.h>
     26 # ifdef OPENSSL_HAS_ECC
     27 #  include <openssl/ec.h>
     28 # endif /* OPENSSL_HAS_ECC */
     29 #endif /* WITH_OPENSSL */
     30 
     31 #define SSHBUF_SIZE_MAX		0x8000000	/* Hard maximum size */
     32 #define SSHBUF_REFS_MAX		0x100000	/* Max child buffers */
     33 #define SSHBUF_MAX_BIGNUM	(16384 / 8)	/* Max bignum *bytes* */
     34 #define SSHBUF_MAX_ECPOINT	((528 * 2 / 8) + 1) /* Max EC point *bytes* */
     35 
     36 /*
     37  * NB. do not depend on the internals of this. It will be made opaque
     38  * one day.
     39  */
     40 struct sshbuf {
     41 	u_char *d;		/* Data */
     42 	const u_char *cd;	/* Const data */
     43 	size_t off;		/* First available byte is buf->d + buf->off */
     44 	size_t size;		/* Last byte is buf->d + buf->size - 1 */
     45 	size_t max_size;	/* Maximum size of buffer */
     46 	size_t alloc;		/* Total bytes allocated to buf->d */
     47 	int readonly;		/* Refers to external, const data */
     48 	int dont_free;		/* Kludge to support sshbuf_init */
     49 	u_int refcount;		/* Tracks self and number of child buffers */
     50 	struct sshbuf *parent;	/* If child, pointer to parent */
     51 };
     52 
     53 #ifndef SSHBUF_NO_DEPREACTED
     54 /*
     55  * NB. Please do not use sshbuf_init() in new code. Please use sshbuf_new()
     56  * instead. sshbuf_init() is deprectated and will go away soon (it is
     57  * only included to allow compat with buffer_* in OpenSSH)
     58  */
     59 void sshbuf_init(struct sshbuf *buf);
     60 #endif
     61 
     62 /*
     63  * Create a new sshbuf buffer.
     64  * Returns pointer to buffer on success, or NULL on allocation failure.
     65  */
     66 struct sshbuf *sshbuf_new(void);
     67 
     68 /*
     69  * Create a new, read-only sshbuf buffer from existing data.
     70  * Returns pointer to buffer on success, or NULL on allocation failure.
     71  */
     72 struct sshbuf *sshbuf_from(const void *blob, size_t len);
     73 
     74 /*
     75  * Create a new, read-only sshbuf buffer from the contents of an existing
     76  * buffer. The contents of "buf" must not change in the lifetime of the
     77  * resultant buffer.
     78  * Returns pointer to buffer on success, or NULL on allocation failure.
     79  */
     80 struct sshbuf *sshbuf_fromb(struct sshbuf *buf);
     81 
     82 /*
     83  * Create a new, read-only sshbuf buffer from the contents of a string in
     84  * an existing buffer (the string is consumed in the process).
     85  * The contents of "buf" must not change in the lifetime of the resultant
     86  * buffer.
     87  * Returns pointer to buffer on success, or NULL on allocation failure.
     88  */
     89 int	sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp);
     90 
     91 /*
     92  * Clear and free buf
     93  */
     94 void	sshbuf_free(struct sshbuf *buf);
     95 
     96 /*
     97  * Reset buf, clearing its contents. NB. max_size is preserved.
     98  */
     99 void	sshbuf_reset(struct sshbuf *buf);
    100 
    101 /*
    102  * Return the maximum size of buf
    103  */
    104 size_t	sshbuf_max_size(const struct sshbuf *buf);
    105 
    106 /*
    107  * Set the maximum size of buf
    108  * Returns 0 on success, or a negative SSH_ERR_* error code on failure.
    109  */
    110 int	sshbuf_set_max_size(struct sshbuf *buf, size_t max_size);
    111 
    112 /*
    113  * Returns the length of data in buf
    114  */
    115 size_t	sshbuf_len(const struct sshbuf *buf);
    116 
    117 /*
    118  * Returns number of bytes left in buffer before hitting max_size.
    119  */
    120 size_t	sshbuf_avail(const struct sshbuf *buf);
    121 
    122 /*
    123  * Returns a read-only pointer to the start of the data in buf
    124  */
    125 const u_char *sshbuf_ptr(const struct sshbuf *buf);
    126 
    127 /*
    128  * Returns a mutable pointer to the start of the data in buf, or
    129  * NULL if the buffer is read-only.
    130  */
    131 u_char *sshbuf_mutable_ptr(const struct sshbuf *buf);
    132 
    133 /*
    134  * Check whether a reservation of size len will succeed in buf
    135  * Safer to use than direct comparisons again sshbuf_avail as it copes
    136  * with unsigned overflows correctly.
    137  * Returns 0 on success, or a negative SSH_ERR_* error code on failure.
    138  */
    139 int	sshbuf_check_reserve(const struct sshbuf *buf, size_t len);
    140 
    141 /*
    142  * Preallocates len additional bytes in buf.
    143  * Useful for cases where the caller knows how many bytes will ultimately be
    144  * required to avoid realloc in the buffer code.
    145  * Returns 0 on success, or a negative SSH_ERR_* error code on failure.
    146  */
    147 int	sshbuf_allocate(struct sshbuf *buf, size_t len);
    148 
    149 /*
    150  * Reserve len bytes in buf.
    151  * Returns 0 on success and a pointer to the first reserved byte via the
    152  * optional dpp parameter or a negative * SSH_ERR_* error code on failure.
    153  */
    154 int	sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp);
    155 
    156 /*
    157  * Consume len bytes from the start of buf
    158  * Returns 0 on success, or a negative SSH_ERR_* error code on failure.
    159  */
    160 int	sshbuf_consume(struct sshbuf *buf, size_t len);
    161 
    162 /*
    163  * Consume len bytes from the end of buf
    164  * Returns 0 on success, or a negative SSH_ERR_* error code on failure.
    165  */
    166 int	sshbuf_consume_end(struct sshbuf *buf, size_t len);
    167 
    168 /* Extract or deposit some bytes */
    169 int	sshbuf_get(struct sshbuf *buf, void *v, size_t len);
    170 int	sshbuf_put(struct sshbuf *buf, const void *v, size_t len);
    171 int	sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v);
    172 
    173 /* Append using a printf(3) format */
    174 int	sshbuf_putf(struct sshbuf *buf, const char *fmt, ...)
    175 	    __attribute__((format(printf, 2, 3)));
    176 int	sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap);
    177 
    178 /* Functions to extract or store big-endian words of various sizes */
    179 int	sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp);
    180 int	sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp);
    181 int	sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp);
    182 int	sshbuf_get_u8(struct sshbuf *buf, u_char *valp);
    183 int	sshbuf_put_u64(struct sshbuf *buf, u_int64_t val);
    184 int	sshbuf_put_u32(struct sshbuf *buf, u_int32_t val);
    185 int	sshbuf_put_u16(struct sshbuf *buf, u_int16_t val);
    186 int	sshbuf_put_u8(struct sshbuf *buf, u_char val);
    187 
    188 /*
    189  * Functions to extract or store SSH wire encoded strings (u32 len || data)
    190  * The "cstring" variants admit no \0 characters in the string contents.
    191  * Caller must free *valp.
    192  */
    193 int	sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp);
    194 int	sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp);
    195 int	sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v);
    196 int	sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len);
    197 int	sshbuf_put_cstring(struct sshbuf *buf, const char *v);
    198 int	sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v);
    199 
    200 /*
    201  * "Direct" variant of sshbuf_get_string, returns pointer into the sshbuf to
    202  * avoid an malloc+memcpy. The pointer is guaranteed to be valid until the
    203  * next sshbuf-modifying function call. Caller does not free.
    204  */
    205 int	sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
    206 	    size_t *lenp);
    207 
    208 /* Skip past a string */
    209 #define sshbuf_skip_string(buf) sshbuf_get_string_direct(buf, NULL, NULL)
    210 
    211 /* Another variant: "peeks" into the buffer without modifying it */
    212 int	sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
    213 	    size_t *lenp);
    214 
    215 /*
    216  * Functions to extract or store SSH wire encoded bignums and elliptic
    217  * curve points.
    218  */
    219 int	sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len);
    220 int	sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf,
    221 	    const u_char **valp, size_t *lenp);
    222 #ifdef WITH_OPENSSL
    223 int	sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v);
    224 int	sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v);
    225 int	sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v);
    226 int	sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v);
    227 # ifdef OPENSSL_HAS_ECC
    228 int	sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g);
    229 int	sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v);
    230 int	sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g);
    231 int	sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v);
    232 # endif /* OPENSSL_HAS_ECC */
    233 #endif /* WITH_OPENSSL */
    234 
    235 /* Dump the contents of the buffer in a human-readable format */
    236 void	sshbuf_dump(struct sshbuf *buf, FILE *f);
    237 
    238 /* Dump specified memory in a human-readable format */
    239 void	sshbuf_dump_data(const void *s, size_t len, FILE *f);
    240 
    241 /* Return the hexadecimal representation of the contents of the buffer */
    242 char	*sshbuf_dtob16(struct sshbuf *buf);
    243 
    244 /* Encode the contents of the buffer as base64 */
    245 char	*sshbuf_dtob64(struct sshbuf *buf);
    246 
    247 /* Decode base64 data and append it to the buffer */
    248 int	sshbuf_b64tod(struct sshbuf *buf, const char *b64);
    249 
    250 /*
    251  * Duplicate the contents of a buffer to a string (caller to free).
    252  * Returns NULL on buffer error, or if the buffer contains a premature
    253  * nul character.
    254  */
    255 char *sshbuf_dup_string(struct sshbuf *buf);
    256 
    257 /* Macros for decoding/encoding integers */
    258 #define PEEK_U64(p) \
    259 	(((u_int64_t)(((const u_char *)(p))[0]) << 56) | \
    260 	 ((u_int64_t)(((const u_char *)(p))[1]) << 48) | \
    261 	 ((u_int64_t)(((const u_char *)(p))[2]) << 40) | \
    262 	 ((u_int64_t)(((const u_char *)(p))[3]) << 32) | \
    263 	 ((u_int64_t)(((const u_char *)(p))[4]) << 24) | \
    264 	 ((u_int64_t)(((const u_char *)(p))[5]) << 16) | \
    265 	 ((u_int64_t)(((const u_char *)(p))[6]) << 8) | \
    266 	  (u_int64_t)(((const u_char *)(p))[7]))
    267 #define PEEK_U32(p) \
    268 	(((u_int32_t)(((const u_char *)(p))[0]) << 24) | \
    269 	 ((u_int32_t)(((const u_char *)(p))[1]) << 16) | \
    270 	 ((u_int32_t)(((const u_char *)(p))[2]) << 8) | \
    271 	  (u_int32_t)(((const u_char *)(p))[3]))
    272 #define PEEK_U16(p) \
    273 	(((u_int16_t)(((const u_char *)(p))[0]) << 8) | \
    274 	  (u_int16_t)(((const u_char *)(p))[1]))
    275 
    276 #define POKE_U64(p, v) \
    277 	do { \
    278 		const u_int64_t __v = (v); \
    279 		((u_char *)(p))[0] = (__v >> 56) & 0xff; \
    280 		((u_char *)(p))[1] = (__v >> 48) & 0xff; \
    281 		((u_char *)(p))[2] = (__v >> 40) & 0xff; \
    282 		((u_char *)(p))[3] = (__v >> 32) & 0xff; \
    283 		((u_char *)(p))[4] = (__v >> 24) & 0xff; \
    284 		((u_char *)(p))[5] = (__v >> 16) & 0xff; \
    285 		((u_char *)(p))[6] = (__v >> 8) & 0xff; \
    286 		((u_char *)(p))[7] = __v & 0xff; \
    287 	} while (0)
    288 #define POKE_U32(p, v) \
    289 	do { \
    290 		const u_int32_t __v = (v); \
    291 		((u_char *)(p))[0] = (__v >> 24) & 0xff; \
    292 		((u_char *)(p))[1] = (__v >> 16) & 0xff; \
    293 		((u_char *)(p))[2] = (__v >> 8) & 0xff; \
    294 		((u_char *)(p))[3] = __v & 0xff; \
    295 	} while (0)
    296 #define POKE_U16(p, v) \
    297 	do { \
    298 		const u_int16_t __v = (v); \
    299 		((u_char *)(p))[0] = (__v >> 8) & 0xff; \
    300 		((u_char *)(p))[1] = __v & 0xff; \
    301 	} while (0)
    302 
    303 /* Internal definitions follow. Exposed for regress tests */
    304 #ifdef SSHBUF_INTERNAL
    305 
    306 /*
    307  * Return the allocation size of buf
    308  */
    309 size_t	sshbuf_alloc(const struct sshbuf *buf);
    310 
    311 /*
    312  * Increment the reference count of buf.
    313  */
    314 int	sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent);
    315 
    316 /*
    317  * Return the parent buffer of buf, or NULL if it has no parent.
    318  */
    319 const struct sshbuf *sshbuf_parent(const struct sshbuf *buf);
    320 
    321 /*
    322  * Return the reference count of buf
    323  */
    324 u_int	sshbuf_refcount(const struct sshbuf *buf);
    325 
    326 # define SSHBUF_SIZE_INIT	256		/* Initial allocation */
    327 # define SSHBUF_SIZE_INC	256		/* Preferred increment length */
    328 # define SSHBUF_PACK_MIN	8192		/* Minimim packable offset */
    329 
    330 /* # define SSHBUF_ABORT abort */
    331 /* # define SSHBUF_DEBUG */
    332 
    333 # ifndef SSHBUF_ABORT
    334 #  define SSHBUF_ABORT()
    335 # endif
    336 
    337 # ifdef SSHBUF_DEBUG
    338 #  define SSHBUF_TELL(what) do { \
    339 		printf("%s:%d %s: %s size %zu alloc %zu off %zu max %zu\n", \
    340 		    __FILE__, __LINE__, __func__, what, \
    341 		    buf->size, buf->alloc, buf->off, buf->max_size); \
    342 		fflush(stdout); \
    343 	} while (0)
    344 #  define SSHBUF_DBG(x) do { \
    345 		printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
    346 		printf x; \
    347 		printf("\n"); \
    348 		fflush(stdout); \
    349 	} while (0)
    350 # else
    351 #  define SSHBUF_TELL(what)
    352 #  define SSHBUF_DBG(x)
    353 # endif
    354 #endif /* SSHBUF_INTERNAL */
    355 
    356 #endif /* _SSHBUF_H */
    357