summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sshbuf-getput-basic.c163
-rw-r--r--sshbuf.h23
2 files changed, 183 insertions, 3 deletions
diff --git a/sshbuf-getput-basic.c b/sshbuf-getput-basic.c
index 50648258f..27058d5bb 100644
--- a/sshbuf-getput-basic.c
+++ b/sshbuf-getput-basic.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf-getput-basic.c,v 1.7 2017/06/01 04:51:58 djm Exp $ */ 1/* $OpenBSD: sshbuf-getput-basic.c,v 1.8 2019/07/14 23:32:27 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -93,6 +93,93 @@ sshbuf_get_u8(struct sshbuf *buf, u_char *valp)
93 return 0; 93 return 0;
94} 94}
95 95
96static int
97check_offset(const struct sshbuf *buf, int wr, size_t offset, size_t len)
98{
99 if (sshbuf_ptr(buf) == NULL) /* calls sshbuf_check_sanity() */
100 return SSH_ERR_INTERNAL_ERROR;
101 if (offset >= SIZE_MAX - len)
102 return SSH_ERR_INVALID_ARGUMENT;
103 if (offset + len > sshbuf_len(buf)) {
104 return wr ?
105 SSH_ERR_NO_BUFFER_SPACE : SSH_ERR_MESSAGE_INCOMPLETE;
106 }
107 return 0;
108}
109
110static int
111check_roffset(const struct sshbuf *buf, size_t offset, size_t len,
112 const u_char **p)
113{
114 int r;
115
116 *p = NULL;
117 if ((r = check_offset(buf, 0, offset, len)) != 0)
118 return r;
119 *p = sshbuf_ptr(buf) + offset;
120 return 0;
121}
122
123int
124sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, u_int64_t *valp)
125{
126 const u_char *p = NULL;
127 int r;
128
129 if (valp != NULL)
130 *valp = 0;
131 if ((r = check_roffset(buf, offset, 8, &p)) != 0)
132 return r;
133 if (valp != NULL)
134 *valp = PEEK_U64(p);
135 return 0;
136}
137
138int
139sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, u_int32_t *valp)
140{
141 const u_char *p = NULL;
142 int r;
143
144 if (valp != NULL)
145 *valp = 0;
146 if ((r = check_roffset(buf, offset, 4, &p)) != 0)
147 return r;
148 if (valp != NULL)
149 *valp = PEEK_U32(p);
150 return 0;
151}
152
153int
154sshbuf_peek_u16(const struct sshbuf *buf, size_t offset, u_int16_t *valp)
155{
156 const u_char *p = NULL;
157 int r;
158
159 if (valp != NULL)
160 *valp = 0;
161 if ((r = check_roffset(buf, offset, 2, &p)) != 0)
162 return r;
163 if (valp != NULL)
164 *valp = PEEK_U16(p);
165 return 0;
166}
167
168int
169sshbuf_peek_u8(const struct sshbuf *buf, size_t offset, u_char *valp)
170{
171 const u_char *p = NULL;
172 int r;
173
174 if (valp != NULL)
175 *valp = 0;
176 if ((r = check_roffset(buf, offset, 1, &p)) != 0)
177 return r;
178 if (valp != NULL)
179 *valp = *p;
180 return 0;
181}
182
96int 183int
97sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp) 184sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp)
98{ 185{
@@ -344,6 +431,80 @@ sshbuf_put_u8(struct sshbuf *buf, u_char val)
344 return 0; 431 return 0;
345} 432}
346 433
434static int
435check_woffset(struct sshbuf *buf, size_t offset, size_t len, u_char **p)
436{
437 int r;
438
439 *p = NULL;
440 if ((r = check_offset(buf, 1, offset, len)) != 0)
441 return r;
442 if (sshbuf_mutable_ptr(buf) == NULL)
443 return SSH_ERR_BUFFER_READ_ONLY;
444 *p = sshbuf_mutable_ptr(buf) + offset;
445 return 0;
446}
447
448int
449sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val)
450{
451 u_char *p = NULL;
452 int r;
453
454 if ((r = check_woffset(buf, offset, 8, &p)) != 0)
455 return r;
456 POKE_U64(p, val);
457 return 0;
458}
459
460int
461sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val)
462{
463 u_char *p = NULL;
464 int r;
465
466 if ((r = check_woffset(buf, offset, 4, &p)) != 0)
467 return r;
468 POKE_U32(p, val);
469 return 0;
470}
471
472int
473sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val)
474{
475 u_char *p = NULL;
476 int r;
477
478 if ((r = check_woffset(buf, offset, 2, &p)) != 0)
479 return r;
480 POKE_U16(p, val);
481 return 0;
482}
483
484int
485sshbuf_poke_u8(struct sshbuf *buf, size_t offset, u_char val)
486{
487 u_char *p = NULL;
488 int r;
489
490 if ((r = check_woffset(buf, offset, 1, &p)) != 0)
491 return r;
492 *p = val;
493 return 0;
494}
495
496int
497sshbuf_poke(struct sshbuf *buf, size_t offset, void *v, size_t len)
498{
499 u_char *p = NULL;
500 int r;
501
502 if ((r = check_woffset(buf, offset, len, &p)) != 0)
503 return r;
504 memcpy(p, v, len);
505 return 0;
506}
507
347int 508int
348sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len) 509sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len)
349{ 510{
diff --git a/sshbuf.h b/sshbuf.h
index 7900b82ba..1d9d5bb23 100644
--- a/sshbuf.h
+++ b/sshbuf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf.h,v 1.13 2019/01/21 09:54:11 djm Exp $ */ 1/* $OpenBSD: sshbuf.h,v 1.14 2019/07/14 23:32:27 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -176,6 +176,26 @@ int sshbuf_put_u32(struct sshbuf *buf, u_int32_t val);
176int sshbuf_put_u16(struct sshbuf *buf, u_int16_t val); 176int sshbuf_put_u16(struct sshbuf *buf, u_int16_t val);
177int sshbuf_put_u8(struct sshbuf *buf, u_char val); 177int sshbuf_put_u8(struct sshbuf *buf, u_char val);
178 178
179/* Functions to peek at the contents of a buffer without modifying it. */
180int sshbuf_peek_u64(const struct sshbuf *buf, size_t offset,
181 u_int64_t *valp);
182int sshbuf_peek_u32(const struct sshbuf *buf, size_t offset,
183 u_int32_t *valp);
184int sshbuf_peek_u16(const struct sshbuf *buf, size_t offset,
185 u_int16_t *valp);
186int sshbuf_peek_u8(const struct sshbuf *buf, size_t offset,
187 u_char *valp);
188
189/*
190 * Functions to poke values into an exisiting buffer (e.g. a length header
191 * to a packet). The destination bytes must already exist in the buffer.
192 */
193int sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val);
194int sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val);
195int sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val);
196int sshbuf_poke_u8(struct sshbuf *buf, size_t offset, u_char val);
197int sshbuf_poke(struct sshbuf *buf, size_t offset, void *v, size_t len);
198
179/* 199/*
180 * Functions to extract or store SSH wire encoded strings (u32 len || data) 200 * Functions to extract or store SSH wire encoded strings (u32 len || data)
181 * The "cstring" variants admit no \0 characters in the string contents. 201 * The "cstring" variants admit no \0 characters in the string contents.
@@ -202,7 +222,6 @@ int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
202/* Another variant: "peeks" into the buffer without modifying it */ 222/* Another variant: "peeks" into the buffer without modifying it */
203int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, 223int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
204 size_t *lenp); 224 size_t *lenp);
205/* XXX peek_u8 / peek_u32 */
206 225
207/* 226/*
208 * Functions to extract or store SSH wire encoded bignums and elliptic 227 * Functions to extract or store SSH wire encoded bignums and elliptic