diff options
-rw-r--r-- | sshbuf-getput-basic.c | 163 | ||||
-rw-r--r-- | sshbuf.h | 23 |
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 | ||
96 | static int | ||
97 | check_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 | |||
110 | static int | ||
111 | check_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 | |||
123 | int | ||
124 | sshbuf_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 | |||
138 | int | ||
139 | sshbuf_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 | |||
153 | int | ||
154 | sshbuf_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 | |||
168 | int | ||
169 | sshbuf_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 | |||
96 | int | 183 | int |
97 | sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp) | 184 | sshbuf_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 | ||
434 | static int | ||
435 | check_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 | |||
448 | int | ||
449 | sshbuf_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 | |||
460 | int | ||
461 | sshbuf_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 | |||
472 | int | ||
473 | sshbuf_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 | |||
484 | int | ||
485 | sshbuf_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 | |||
496 | int | ||
497 | sshbuf_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 | |||
347 | int | 508 | int |
348 | sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len) | 509 | sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len) |
349 | { | 510 | { |
@@ -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); | |||
176 | int sshbuf_put_u16(struct sshbuf *buf, u_int16_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); | 177 | int sshbuf_put_u8(struct sshbuf *buf, u_char val); |
178 | 178 | ||
179 | /* Functions to peek at the contents of a buffer without modifying it. */ | ||
180 | int sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, | ||
181 | u_int64_t *valp); | ||
182 | int sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, | ||
183 | u_int32_t *valp); | ||
184 | int sshbuf_peek_u16(const struct sshbuf *buf, size_t offset, | ||
185 | u_int16_t *valp); | ||
186 | int 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 | */ | ||
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); | ||
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 */ |
203 | int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, | 223 | int 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 |