Home | History | Annotate | Download | only in openssh
      1 /*	$OpenBSD: sshbuf.h,v 1.4 2015/01/14 15:02:39 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 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 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  * Reserve len bytes in buf.
    143  * Returns 0 on success and a pointer to the first reserved byte via the
    144  * optional dpp parameter or a negative * SSH_ERR_* error code on failure.
    145  */
    146 int	sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp);
    147 
    148 /*
    149  * Consume len bytes from the start of buf
    150  * Returns 0 on success, or a negative SSH_ERR_* error code on failure.
    151  */
    152 int	sshbuf_consume(struct sshbuf *buf, size_t len);
    153 
    154 /*
    155  * Consume len bytes from the end of buf
    156  * Returns 0 on success, or a negative SSH_ERR_* error code on failure.
    157  */
    158 int	sshbuf_consume_end(struct sshbuf *buf, size_t len);
    159 
    160 /* Extract or deposit some bytes */
    161 int	sshbuf_get(struct sshbuf *buf, void *v, size_t len);
    162 int	sshbuf_put(struct sshbuf *buf, const void *v, size_t len);
    163 int	sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v);
    164 
    165 /* Append using a printf(3) format */
    166 int	sshbuf_putf(struct sshbuf *buf, const char *fmt, ...)
    167 	    __attribute__((format(printf, 2, 3)));
    168 int	sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap);
    169 
    170 /* Functions to extract or store big-endian words of various sizes */
    171 int	sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp);
    172 int	sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp);
    173 int	sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp);
    174 int	sshbuf_get_u8(struct sshbuf *buf, u_char *valp);
    175 int	sshbuf_put_u64(struct sshbuf *buf, u_int64_t val);
    176 int	sshbuf_put_u32(struct sshbuf *buf, u_int32_t val);
    177 int	sshbuf_put_u16(struct sshbuf *buf, u_int16_t val);
    178 int	sshbuf_put_u8(struct sshbuf *buf, u_char val);
    179 
    180 /*
    181  * Functions to extract or store SSH wire encoded strings (u32 len || data)
    182  * The "cstring" variants admit no \0 characters in the string contents.
    183  * Caller must free *valp.
    184  */
    185 int	sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp);
    186 int	sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp);
    187 int	sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v);
    188 int	sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len);
    189 int	sshbuf_put_cstring(struct sshbuf *buf, const char *v);
    190 int	sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v);
    191 
    192 /*
    193  * "Direct" variant of sshbuf_get_string, returns pointer into the sshbuf to
    194  * avoid an malloc+memcpy. The pointer is guaranteed to be valid until the
    195  * next sshbuf-modifying function call. Caller does not free.
    196  */
    197 int	sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
    198 	    size_t *lenp);
    199 
    200 /* Skip past a string */
    201 #define sshbuf_skip_string(buf) sshbuf_get_string_direct(buf, NULL, NULL)
    202 
    203 /* Another variant: "peeks" into the buffer without modifying it */
    204 int	sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
    205 	    size_t *lenp);
    206 
    207 /*
    208  * Functions to extract or store SSH wire encoded bignums and elliptic
    209  * curve points.
    210  */
    211 int	sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len);
    212 int	sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf,
    213 	    const u_char **valp, size_t *lenp);
    214 #ifdef WITH_OPENSSL
    215 int	sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v);
    216 int	sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v);
    217 int	sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v);
    218 int	sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v);
    219 # ifdef OPENSSL_HAS_ECC
    220 int	sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g);
    221 int	sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v);
    222 int	sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g);
    223 int	sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v);
    224 # endif /* OPENSSL_HAS_ECC */
    225 #endif /* WITH_OPENSSL */
    226 
    227 /* Dump the contents of the buffer in a human-readable format */
    228 void	sshbuf_dump(struct sshbuf *buf, FILE *f);
    229 
    230 /* Dump specified memory in a human-readable format */
    231 void	sshbuf_dump_data(const void *s, size_t len, FILE *f);
    232 
    233 /* Return the hexadecimal representation of the contents of the buffer */
    234 char	*sshbuf_dtob16(struct sshbuf *buf);
    235 
    236 /* Encode the contents of the buffer as base64 */
    237 char	*sshbuf_dtob64(struct sshbuf *buf);
    238 
    239 /* Decode base64 data and append it to the buffer */
    240 int	sshbuf_b64tod(struct sshbuf *buf, const char *b64);
    241 
    242 /* Macros for decoding/encoding integers */
    243 #define PEEK_U64(p) \
    244 	(((u_int64_t)(((u_char *)(p))[0]) << 56) | \
    245 	 ((u_int64_t)(((u_char *)(p))[1]) << 48) | \
    246 	 ((u_int64_t)(((u_char *)(p))[2]) << 40) | \
    247 	 ((u_int64_t)(((u_char *)(p))[3]) << 32) | \
    248 	 ((u_int64_t)(((u_char *)(p))[4]) << 24) | \
    249 	 ((u_int64_t)(((u_char *)(p))[5]) << 16) | \
    250 	 ((u_int64_t)(((u_char *)(p))[6]) << 8) | \
    251 	  (u_int64_t)(((u_char *)(p))[7]))
    252 #define PEEK_U32(p) \
    253 	(((u_int32_t)(((u_char *)(p))[0]) << 24) | \
    254 	 ((u_int32_t)(((u_char *)(p))[1]) << 16) | \
    255 	 ((u_int32_t)(((u_char *)(p))[2]) << 8) | \
    256 	  (u_int32_t)(((u_char *)(p))[3]))
    257 #define PEEK_U16(p) \
    258 	(((u_int16_t)(((u_char *)(p))[0]) << 8) | \
    259 	  (u_int16_t)(((u_char *)(p))[1]))
    260 
    261 #define POKE_U64(p, v) \
    262 	do { \
    263 		((u_char *)(p))[0] = (((u_int64_t)(v)) >> 56) & 0xff; \
    264 		((u_char *)(p))[1] = (((u_int64_t)(v)) >> 48) & 0xff; \
    265 		((u_char *)(p))[2] = (((u_int64_t)(v)) >> 40) & 0xff; \
    266 		((u_char *)(p))[3] = (((u_int64_t)(v)) >> 32) & 0xff; \
    267 		((u_char *)(p))[4] = (((u_int64_t)(v)) >> 24) & 0xff; \
    268 		((u_char *)(p))[5] = (((u_int64_t)(v)) >> 16) & 0xff; \
    269 		((u_char *)(p))[6] = (((u_int64_t)(v)) >> 8) & 0xff; \
    270 		((u_char *)(p))[7] = ((u_int64_t)(v)) & 0xff; \
    271 	} while (0)
    272 #define POKE_U32(p, v) \
    273 	do { \
    274 		((u_char *)(p))[0] = (((u_int64_t)(v)) >> 24) & 0xff; \
    275 		((u_char *)(p))[1] = (((u_int64_t)(v)) >> 16) & 0xff; \
    276 		((u_char *)(p))[2] = (((u_int64_t)(v)) >> 8) & 0xff; \
    277 		((u_char *)(p))[3] = ((u_int64_t)(v)) & 0xff; \
    278 	} while (0)
    279 #define POKE_U16(p, v) \
    280 	do { \
    281 		((u_char *)(p))[0] = (((u_int64_t)(v)) >> 8) & 0xff; \
    282 		((u_char *)(p))[1] = ((u_int64_t)(v)) & 0xff; \
    283 	} while (0)
    284 
    285 /* Internal definitions follow. Exposed for regress tests */
    286 #ifdef SSHBUF_INTERNAL
    287 
    288 /*
    289  * Return the allocation size of buf
    290  */
    291 size_t	sshbuf_alloc(const struct sshbuf *buf);
    292 
    293 /*
    294  * Increment the reference count of buf.
    295  */
    296 int	sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent);
    297 
    298 /*
    299  * Return the parent buffer of buf, or NULL if it has no parent.
    300  */
    301 const struct sshbuf *sshbuf_parent(const struct sshbuf *buf);
    302 
    303 /*
    304  * Return the reference count of buf
    305  */
    306 u_int	sshbuf_refcount(const struct sshbuf *buf);
    307 
    308 # define SSHBUF_SIZE_INIT	256		/* Initial allocation */
    309 # define SSHBUF_SIZE_INC	256		/* Preferred increment length */
    310 # define SSHBUF_PACK_MIN	8192		/* Minimim packable offset */
    311 
    312 /* # define SSHBUF_ABORT abort */
    313 /* # define SSHBUF_DEBUG */
    314 
    315 # ifndef SSHBUF_ABORT
    316 #  define SSHBUF_ABORT()
    317 # endif
    318 
    319 # ifdef SSHBUF_DEBUG
    320 #  define SSHBUF_TELL(what) do { \
    321 		printf("%s:%d %s: %s size %zu alloc %zu off %zu max %zu\n", \
    322 		    __FILE__, __LINE__, __func__, what, \
    323 		    buf->size, buf->alloc, buf->off, buf->max_size); \
    324 		fflush(stdout); \
    325 	} while (0)
    326 #  define SSHBUF_DBG(x) do { \
    327 		printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
    328 		printf x; \
    329 		printf("\n"); \
    330 		fflush(stdout); \
    331 	} while (0)
    332 # else
    333 #  define SSHBUF_TELL(what)
    334 #  define SSHBUF_DBG(x)
    335 # endif
    336 #endif /* SSHBUF_INTERNAL */
    337 
    338 #endif /* _SSHBUF_H */
    339