21 #include <sys/types.h>
25 # include <openssl/bn.h>
26 # ifdef OPENSSL_HAS_ECC
27 # include <openssl/ec.h>
31 #define SSHBUF_SIZE_MAX 0xF000000
32 #define SSHBUF_REFS_MAX 0x100000
33 #define SSHBUF_MAX_BIGNUM (16384 / 8)
34 #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1)
50 struct sshbuf *parent;
57 struct sshbuf *sshbuf_new(
void);
63 struct sshbuf *sshbuf_from(
const void *blob,
size_t len);
71 struct sshbuf *sshbuf_fromb(
struct sshbuf *buf);
80 int sshbuf_froms(
struct sshbuf *buf,
struct sshbuf **bufp);
85 void sshbuf_free(
struct sshbuf *buf);
90 void sshbuf_reset(
struct sshbuf *buf);
95 size_t sshbuf_max_size(
const struct sshbuf *buf);
101 int sshbuf_set_max_size(
struct sshbuf *buf,
size_t max_size);
106 size_t sshbuf_len(
const struct sshbuf *buf);
111 size_t sshbuf_avail(
const struct sshbuf *buf);
116 const u_char *sshbuf_ptr(
const struct sshbuf *buf);
122 u_char *sshbuf_mutable_ptr(
const struct sshbuf *buf);
130 int sshbuf_check_reserve(
const struct sshbuf *buf,
size_t len);
138 int sshbuf_allocate(
struct sshbuf *buf,
size_t len);
145 int sshbuf_reserve(
struct sshbuf *buf,
size_t len, u_char **dpp);
151 int sshbuf_consume(
struct sshbuf *buf,
size_t len);
157 int sshbuf_consume_end(
struct sshbuf *buf,
size_t len);
160 int sshbuf_get(
struct sshbuf *buf,
void *v,
size_t len);
161 int sshbuf_put(
struct sshbuf *buf,
const void *v,
size_t len);
162 int sshbuf_putb(
struct sshbuf *buf,
const struct sshbuf *v);
165 int sshbuf_putf(
struct sshbuf *buf,
const char *fmt, ...)
166 __attribute__((format(printf, 2, 3)));
167 int sshbuf_putfv(struct sshbuf *buf, const
char *fmt, va_list ap);
170 int sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp);
171 int sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp);
172 int sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp);
173 int sshbuf_get_u8(struct sshbuf *buf, u_char *valp);
174 int sshbuf_put_u64(struct sshbuf *buf, u_int64_t val);
175 int sshbuf_put_u32(struct sshbuf *buf, u_int32_t val);
176 int sshbuf_put_u16(struct sshbuf *buf, u_int16_t val);
177 int sshbuf_put_u8(struct sshbuf *buf, u_char val);
180 int sshbuf_peek_u64(const struct sshbuf *buf,
size_t offset,
182 int sshbuf_peek_u32(const struct sshbuf *buf,
size_t offset,
184 int sshbuf_peek_u16(const struct sshbuf *buf,
size_t offset,
186 int sshbuf_peek_u8(const struct sshbuf *buf,
size_t offset,
193 int sshbuf_poke_u64(struct sshbuf *buf,
size_t offset, u_int64_t val);
194 int sshbuf_poke_u32(struct sshbuf *buf,
size_t offset, u_int32_t val);
195 int sshbuf_poke_u16(struct sshbuf *buf,
size_t offset, u_int16_t val);
196 int sshbuf_poke_u8(struct sshbuf *buf,
size_t offset, u_char val);
197 int sshbuf_poke(struct sshbuf *buf,
size_t offset,
void *v,
size_t len);
204 int sshbuf_get_string(struct sshbuf *buf, u_char **valp,
size_t *lenp);
205 int sshbuf_get_cstring(struct sshbuf *buf,
char **valp,
size_t *lenp);
206 int sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v);
207 int sshbuf_put_string(struct sshbuf *buf, const
void *v,
size_t len);
208 int sshbuf_put_cstring(struct sshbuf *buf, const
char *v);
209 int sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v);
216 int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
220 #define sshbuf_skip_string(buf) sshbuf_get_string_direct(buf, NULL, NULL)
223 int sshbuf_peek_string_direct(
const struct sshbuf *buf,
const u_char **valp,
230 int sshbuf_put_bignum2_bytes(
struct sshbuf *buf,
const void *v,
size_t len);
231 int sshbuf_get_bignum2_bytes_direct(
struct sshbuf *buf,
232 const u_char **valp,
size_t *lenp);
234 int sshbuf_get_bignum2(
struct sshbuf *buf, BIGNUM **valp);
235 int sshbuf_put_bignum2(
struct sshbuf *buf,
const BIGNUM *v);
236 # ifdef OPENSSL_HAS_ECC
237 int sshbuf_get_ec(
struct sshbuf *buf, EC_POINT *v,
const EC_GROUP *g);
238 int sshbuf_get_eckey(
struct sshbuf *buf, EC_KEY *v);
239 int sshbuf_put_ec(
struct sshbuf *buf,
const EC_POINT *v,
const EC_GROUP *g);
240 int sshbuf_put_eckey(
struct sshbuf *buf,
const EC_KEY *v);
245 void sshbuf_dump(
const struct sshbuf *buf, FILE *f);
248 void sshbuf_dump_data(
const void *s,
size_t len, FILE *f);
251 char *sshbuf_dtob16(
struct sshbuf *buf);
254 char *sshbuf_dtob64_string(
const struct sshbuf *buf,
int wrap);
255 int sshbuf_dtob64(
const struct sshbuf *d,
struct sshbuf *b64,
int wrap);
257 int sshbuf_dtourlb64(
const struct sshbuf *d,
struct sshbuf *b64,
int wrap);
260 int sshbuf_b64tod(
struct sshbuf *buf,
const char *b64);
274 int sshbuf_cmp(
const struct sshbuf *b,
size_t offset,
275 const void *s,
size_t len);
286 sshbuf_find(
const struct sshbuf *b,
size_t start_offset,
287 const void *s,
size_t len,
size_t *offsetp);
294 char *sshbuf_dup_string(
struct sshbuf *buf);
300 int sshbuf_load_fd(
int,
struct sshbuf **)
301 __attribute__((__nonnull__ (2)));
302 int sshbuf_load_file(const
char *, struct sshbuf **)
303 __attribute__((__nonnull__ (2)));
309 int sshbuf_write_file(const
char *path, struct sshbuf *buf)
310 __attribute__((__nonnull__ (2)));
313 #define PEEK_U64(p) \
314 (((u_int64_t)(((const u_char *)(p))[0]) << 56) | \
315 ((u_int64_t)(((const u_char *)(p))[1]) << 48) | \
316 ((u_int64_t)(((const u_char *)(p))[2]) << 40) | \
317 ((u_int64_t)(((const u_char *)(p))[3]) << 32) | \
318 ((u_int64_t)(((const u_char *)(p))[4]) << 24) | \
319 ((u_int64_t)(((const u_char *)(p))[5]) << 16) | \
320 ((u_int64_t)(((const u_char *)(p))[6]) << 8) | \
321 (u_int64_t)(((const u_char *)(p))[7]))
322 #define PEEK_U32(p) \
323 (((u_int32_t)(((const u_char *)(p))[0]) << 24) | \
324 ((u_int32_t)(((const u_char *)(p))[1]) << 16) | \
325 ((u_int32_t)(((const u_char *)(p))[2]) << 8) | \
326 (u_int32_t)(((const u_char *)(p))[3]))
327 #define PEEK_U16(p) \
328 (((u_int16_t)(((const u_char *)(p))[0]) << 8) | \
329 (u_int16_t)(((const u_char *)(p))[1]))
331 #define POKE_U64(p, v) \
333 const u_int64_t __v = (v); \
334 ((u_char *)(p))[0] = (__v >> 56) & 0xff; \
335 ((u_char *)(p))[1] = (__v >> 48) & 0xff; \
336 ((u_char *)(p))[2] = (__v >> 40) & 0xff; \
337 ((u_char *)(p))[3] = (__v >> 32) & 0xff; \
338 ((u_char *)(p))[4] = (__v >> 24) & 0xff; \
339 ((u_char *)(p))[5] = (__v >> 16) & 0xff; \
340 ((u_char *)(p))[6] = (__v >> 8) & 0xff; \
341 ((u_char *)(p))[7] = __v & 0xff; \
343 #define POKE_U32(p, v) \
345 const u_int32_t __v = (v); \
346 ((u_char *)(p))[0] = (__v >> 24) & 0xff; \
347 ((u_char *)(p))[1] = (__v >> 16) & 0xff; \
348 ((u_char *)(p))[2] = (__v >> 8) & 0xff; \
349 ((u_char *)(p))[3] = __v & 0xff; \
351 #define POKE_U16(p, v) \
353 const u_int16_t __v = (v); \
354 ((u_char *)(p))[0] = (__v >> 8) & 0xff; \
355 ((u_char *)(p))[1] = __v & 0xff; \
359 #ifdef SSHBUF_INTERNAL
364 size_t sshbuf_alloc(
const struct sshbuf *buf);
369 int sshbuf_set_parent(
struct sshbuf *child,
struct sshbuf *parent);
374 const struct sshbuf *sshbuf_parent(
const struct sshbuf *buf);
379 u_int sshbuf_refcount(
const struct sshbuf *buf);
381 # define SSHBUF_SIZE_INIT 256
382 # define SSHBUF_SIZE_INC 256
383 # define SSHBUF_PACK_MIN 8192
388 # ifndef SSHBUF_ABORT
389 # define SSHBUF_ABORT()
393 # define SSHBUF_TELL(what) do { \
394 printf("%s:%d %s: %s size %zu alloc %zu off %zu max %zu\n", \
395 __FILE__, __LINE__, __func__, what, \
396 buf->size, buf->alloc, buf->off, buf->max_size); \
399 # define SSHBUF_DBG(x) do { \
400 printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
406 # define SSHBUF_TELL(what)
407 # define SSHBUF_DBG(x)