File: | src/usr.bin/ssh/ssh-sk-helper/../sshbuf-getput-basic.c |
Warning: | line 285, column 7 Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: sshbuf-getput-basic.c,v 1.11 2020/06/05 03:25:35 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 | #include <sys/types.h> |
19 | |
20 | #include <stdarg.h> |
21 | #include <stdlib.h> |
22 | #include <stdio.h> |
23 | #include <string.h> |
24 | #include <stdint.h> |
25 | |
26 | #include "ssherr.h" |
27 | #define SSHBUF_INTERNAL |
28 | #include "sshbuf.h" |
29 | |
30 | int |
31 | sshbuf_get(struct sshbuf *buf, void *v, size_t len) |
32 | { |
33 | const u_char *p = sshbuf_ptr(buf); |
34 | int r; |
35 | |
36 | if ((r = sshbuf_consume(buf, len)) < 0) |
37 | return r; |
38 | if (v != NULL((void *)0) && len != 0) |
39 | memcpy(v, p, len); |
40 | return 0; |
41 | } |
42 | |
43 | int |
44 | sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp) |
45 | { |
46 | const u_char *p = sshbuf_ptr(buf); |
47 | int r; |
48 | |
49 | if ((r = sshbuf_consume(buf, 8)) < 0) |
50 | return r; |
51 | if (valp != NULL((void *)0)) |
52 | *valp = PEEK_U64(p)(((u_int64_t)(((const u_char *)(p))[0]) << 56) | ((u_int64_t )(((const u_char *)(p))[1]) << 48) | ((u_int64_t)(((const u_char *)(p))[2]) << 40) | ((u_int64_t)(((const u_char *)(p))[3]) << 32) | ((u_int64_t)(((const u_char *)(p)) [4]) << 24) | ((u_int64_t)(((const u_char *)(p))[5]) << 16) | ((u_int64_t)(((const u_char *)(p))[6]) << 8) | ( u_int64_t)(((const u_char *)(p))[7])); |
53 | return 0; |
54 | } |
55 | |
56 | int |
57 | sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp) |
58 | { |
59 | const u_char *p = sshbuf_ptr(buf); |
60 | int r; |
61 | |
62 | if ((r = sshbuf_consume(buf, 4)) < 0) |
63 | return r; |
64 | if (valp != NULL((void *)0)) |
65 | *valp = PEEK_U32(p)(((u_int32_t)(((const u_char *)(p))[0]) << 24) | ((u_int32_t )(((const u_char *)(p))[1]) << 16) | ((u_int32_t)(((const u_char *)(p))[2]) << 8) | (u_int32_t)(((const u_char * )(p))[3])); |
66 | return 0; |
67 | } |
68 | |
69 | int |
70 | sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp) |
71 | { |
72 | const u_char *p = sshbuf_ptr(buf); |
73 | int r; |
74 | |
75 | if ((r = sshbuf_consume(buf, 2)) < 0) |
76 | return r; |
77 | if (valp != NULL((void *)0)) |
78 | *valp = PEEK_U16(p)(((u_int16_t)(((const u_char *)(p))[0]) << 8) | (u_int16_t )(((const u_char *)(p))[1])); |
79 | return 0; |
80 | } |
81 | |
82 | int |
83 | sshbuf_get_u8(struct sshbuf *buf, u_char *valp) |
84 | { |
85 | const u_char *p = sshbuf_ptr(buf); |
86 | int r; |
87 | |
88 | if ((r = sshbuf_consume(buf, 1)) < 0) |
89 | return r; |
90 | if (valp != NULL((void *)0)) |
91 | *valp = (u_int8_t)*p; |
92 | return 0; |
93 | } |
94 | |
95 | static int |
96 | check_offset(const struct sshbuf *buf, int wr, size_t offset, size_t len) |
97 | { |
98 | if (sshbuf_ptr(buf) == NULL((void *)0)) /* calls sshbuf_check_sanity() */ |
99 | return SSH_ERR_INTERNAL_ERROR-1; |
100 | if (offset >= SIZE_MAX0xffffffffffffffffUL - len) |
101 | return SSH_ERR_INVALID_ARGUMENT-10; |
102 | if (offset + len > sshbuf_len(buf)) { |
103 | return wr ? |
104 | SSH_ERR_NO_BUFFER_SPACE-9 : SSH_ERR_MESSAGE_INCOMPLETE-3; |
105 | } |
106 | return 0; |
107 | } |
108 | |
109 | static int |
110 | check_roffset(const struct sshbuf *buf, size_t offset, size_t len, |
111 | const u_char **p) |
112 | { |
113 | int r; |
114 | |
115 | *p = NULL((void *)0); |
116 | if ((r = check_offset(buf, 0, offset, len)) != 0) |
117 | return r; |
118 | *p = sshbuf_ptr(buf) + offset; |
119 | return 0; |
120 | } |
121 | |
122 | int |
123 | sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, u_int64_t *valp) |
124 | { |
125 | const u_char *p = NULL((void *)0); |
126 | int r; |
127 | |
128 | if (valp != NULL((void *)0)) |
129 | *valp = 0; |
130 | if ((r = check_roffset(buf, offset, 8, &p)) != 0) |
131 | return r; |
132 | if (valp != NULL((void *)0)) |
133 | *valp = PEEK_U64(p)(((u_int64_t)(((const u_char *)(p))[0]) << 56) | ((u_int64_t )(((const u_char *)(p))[1]) << 48) | ((u_int64_t)(((const u_char *)(p))[2]) << 40) | ((u_int64_t)(((const u_char *)(p))[3]) << 32) | ((u_int64_t)(((const u_char *)(p)) [4]) << 24) | ((u_int64_t)(((const u_char *)(p))[5]) << 16) | ((u_int64_t)(((const u_char *)(p))[6]) << 8) | ( u_int64_t)(((const u_char *)(p))[7])); |
134 | return 0; |
135 | } |
136 | |
137 | int |
138 | sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, u_int32_t *valp) |
139 | { |
140 | const u_char *p = NULL((void *)0); |
141 | int r; |
142 | |
143 | if (valp != NULL((void *)0)) |
144 | *valp = 0; |
145 | if ((r = check_roffset(buf, offset, 4, &p)) != 0) |
146 | return r; |
147 | if (valp != NULL((void *)0)) |
148 | *valp = PEEK_U32(p)(((u_int32_t)(((const u_char *)(p))[0]) << 24) | ((u_int32_t )(((const u_char *)(p))[1]) << 16) | ((u_int32_t)(((const u_char *)(p))[2]) << 8) | (u_int32_t)(((const u_char * )(p))[3])); |
149 | return 0; |
150 | } |
151 | |
152 | int |
153 | sshbuf_peek_u16(const struct sshbuf *buf, size_t offset, u_int16_t *valp) |
154 | { |
155 | const u_char *p = NULL((void *)0); |
156 | int r; |
157 | |
158 | if (valp != NULL((void *)0)) |
159 | *valp = 0; |
160 | if ((r = check_roffset(buf, offset, 2, &p)) != 0) |
161 | return r; |
162 | if (valp != NULL((void *)0)) |
163 | *valp = PEEK_U16(p)(((u_int16_t)(((const u_char *)(p))[0]) << 8) | (u_int16_t )(((const u_char *)(p))[1])); |
164 | return 0; |
165 | } |
166 | |
167 | int |
168 | sshbuf_peek_u8(const struct sshbuf *buf, size_t offset, u_char *valp) |
169 | { |
170 | const u_char *p = NULL((void *)0); |
171 | int r; |
172 | |
173 | if (valp != NULL((void *)0)) |
174 | *valp = 0; |
175 | if ((r = check_roffset(buf, offset, 1, &p)) != 0) |
176 | return r; |
177 | if (valp != NULL((void *)0)) |
178 | *valp = *p; |
179 | return 0; |
180 | } |
181 | |
182 | int |
183 | sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp) |
184 | { |
185 | const u_char *val; |
186 | size_t len; |
187 | int r; |
188 | |
189 | if (valp != NULL((void *)0)) |
190 | *valp = NULL((void *)0); |
191 | if (lenp != NULL((void *)0)) |
192 | *lenp = 0; |
193 | if ((r = sshbuf_get_string_direct(buf, &val, &len)) < 0) |
194 | return r; |
195 | if (valp != NULL((void *)0)) { |
196 | if ((*valp = malloc(len + 1)) == NULL((void *)0)) { |
197 | SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); |
198 | return SSH_ERR_ALLOC_FAIL-2; |
199 | } |
200 | if (len != 0) |
201 | memcpy(*valp, val, len); |
202 | (*valp)[len] = '\0'; |
203 | } |
204 | if (lenp != NULL((void *)0)) |
205 | *lenp = len; |
206 | return 0; |
207 | } |
208 | |
209 | int |
210 | sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp) |
211 | { |
212 | size_t len; |
213 | const u_char *p; |
214 | int r; |
215 | |
216 | if (valp != NULL((void *)0)) |
217 | *valp = NULL((void *)0); |
218 | if (lenp != NULL((void *)0)) |
219 | *lenp = 0; |
220 | if ((r = sshbuf_peek_string_direct(buf, &p, &len)) < 0) |
221 | return r; |
222 | if (valp != NULL((void *)0)) |
223 | *valp = p; |
224 | if (lenp != NULL((void *)0)) |
225 | *lenp = len; |
226 | if (sshbuf_consume(buf, len + 4) != 0) { |
227 | /* Shouldn't happen */ |
228 | SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); |
229 | SSHBUF_ABORT(); |
230 | return SSH_ERR_INTERNAL_ERROR-1; |
231 | } |
232 | return 0; |
233 | } |
234 | |
235 | int |
236 | sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, |
237 | size_t *lenp) |
238 | { |
239 | u_int32_t len; |
240 | const u_char *p = sshbuf_ptr(buf); |
241 | |
242 | if (valp != NULL((void *)0)) |
243 | *valp = NULL((void *)0); |
244 | if (lenp != NULL((void *)0)) |
245 | *lenp = 0; |
246 | if (sshbuf_len(buf) < 4) { |
247 | SSHBUF_DBG(("SSH_ERR_MESSAGE_INCOMPLETE")); |
248 | return SSH_ERR_MESSAGE_INCOMPLETE-3; |
249 | } |
250 | len = PEEK_U32(p)(((u_int32_t)(((const u_char *)(p))[0]) << 24) | ((u_int32_t )(((const u_char *)(p))[1]) << 16) | ((u_int32_t)(((const u_char *)(p))[2]) << 8) | (u_int32_t)(((const u_char * )(p))[3])); |
251 | if (len > SSHBUF_SIZE_MAX0x8000000 - 4) { |
252 | SSHBUF_DBG(("SSH_ERR_STRING_TOO_LARGE")); |
253 | return SSH_ERR_STRING_TOO_LARGE-6; |
254 | } |
255 | if (sshbuf_len(buf) - 4 < len) { |
256 | SSHBUF_DBG(("SSH_ERR_MESSAGE_INCOMPLETE")); |
257 | return SSH_ERR_MESSAGE_INCOMPLETE-3; |
258 | } |
259 | if (valp != NULL((void *)0)) |
260 | *valp = p + 4; |
261 | if (lenp != NULL((void *)0)) |
262 | *lenp = len; |
263 | return 0; |
264 | } |
265 | |
266 | int |
267 | sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp) |
268 | { |
269 | size_t len; |
270 | const u_char *p, *z; |
271 | int r; |
272 | |
273 | if (valp != NULL((void *)0)) |
274 | *valp = NULL((void *)0); |
275 | if (lenp != NULL((void *)0)) |
276 | *lenp = 0; |
277 | if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0) |
278 | return r; |
279 | /* Allow a \0 only at the end of the string */ |
280 | if (len > 0 && |
281 | (z = memchr(p , '\0', len)) != NULL((void *)0) && z < p + len - 1) { |
282 | SSHBUF_DBG(("SSH_ERR_INVALID_FORMAT")); |
283 | return SSH_ERR_INVALID_FORMAT-4; |
284 | } |
285 | if ((r = sshbuf_skip_string(buf)sshbuf_get_string_direct(buf, ((void *)0), ((void *)0))) != 0) |
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r' | |
286 | return -1; |
287 | if (valp != NULL((void *)0)) { |
288 | if ((*valp = malloc(len + 1)) == NULL((void *)0)) { |
289 | SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); |
290 | return SSH_ERR_ALLOC_FAIL-2; |
291 | } |
292 | if (len != 0) |
293 | memcpy(*valp, p, len); |
294 | (*valp)[len] = '\0'; |
295 | } |
296 | if (lenp != NULL((void *)0)) |
297 | *lenp = (size_t)len; |
298 | return 0; |
299 | } |
300 | |
301 | int |
302 | sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v) |
303 | { |
304 | u_int32_t len; |
305 | u_char *p; |
306 | int r; |
307 | |
308 | /* |
309 | * Use sshbuf_peek_string_direct() to figure out if there is |
310 | * a complete string in 'buf' and copy the string directly |
311 | * into 'v'. |
312 | */ |
313 | if ((r = sshbuf_peek_string_direct(buf, NULL((void *)0), NULL((void *)0))) != 0 || |
314 | (r = sshbuf_get_u32(buf, &len)) != 0 || |
315 | (r = sshbuf_reserve(v, len, &p)) != 0 || |
316 | (r = sshbuf_get(buf, p, len)) != 0) |
317 | return r; |
318 | return 0; |
319 | } |
320 | |
321 | int |
322 | sshbuf_put(struct sshbuf *buf, const void *v, size_t len) |
323 | { |
324 | u_char *p; |
325 | int r; |
326 | |
327 | if ((r = sshbuf_reserve(buf, len, &p)) < 0) |
328 | return r; |
329 | if (len != 0) |
330 | memcpy(p, v, len); |
331 | return 0; |
332 | } |
333 | |
334 | int |
335 | sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v) |
336 | { |
337 | if (v == NULL((void *)0)) |
338 | return 0; |
339 | return sshbuf_put(buf, sshbuf_ptr(v), sshbuf_len(v)); |
340 | } |
341 | |
342 | int |
343 | sshbuf_putf(struct sshbuf *buf, const char *fmt, ...) |
344 | { |
345 | va_list ap; |
346 | int r; |
347 | |
348 | va_start(ap, fmt)__builtin_va_start(ap, fmt); |
349 | r = sshbuf_putfv(buf, fmt, ap); |
350 | va_end(ap)__builtin_va_end(ap); |
351 | return r; |
352 | } |
353 | |
354 | int |
355 | sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap) |
356 | { |
357 | va_list ap2; |
358 | int r, len; |
359 | u_char *p; |
360 | |
361 | va_copy(ap2, ap)__builtin_va_copy(ap2, ap); |
362 | if ((len = vsnprintf(NULL((void *)0), 0, fmt, ap2)) < 0) { |
363 | r = SSH_ERR_INVALID_ARGUMENT-10; |
364 | goto out; |
365 | } |
366 | if (len == 0) { |
367 | r = 0; |
368 | goto out; /* Nothing to do */ |
369 | } |
370 | va_end(ap2)__builtin_va_end(ap2); |
371 | va_copy(ap2, ap)__builtin_va_copy(ap2, ap); |
372 | if ((r = sshbuf_reserve(buf, (size_t)len + 1, &p)) < 0) |
373 | goto out; |
374 | if ((r = vsnprintf((char *)p, len + 1, fmt, ap2)) != len) { |
375 | r = SSH_ERR_INTERNAL_ERROR-1; |
376 | goto out; /* Shouldn't happen */ |
377 | } |
378 | /* Consume terminating \0 */ |
379 | if ((r = sshbuf_consume_end(buf, 1)) != 0) |
380 | goto out; |
381 | r = 0; |
382 | out: |
383 | va_end(ap2)__builtin_va_end(ap2); |
384 | return r; |
385 | } |
386 | |
387 | int |
388 | sshbuf_put_u64(struct sshbuf *buf, u_int64_t val) |
389 | { |
390 | u_char *p; |
391 | int r; |
392 | |
393 | if ((r = sshbuf_reserve(buf, 8, &p)) < 0) |
394 | return r; |
395 | POKE_U64(p, val)do { const u_int64_t __v = (val); ((u_char *)(p))[0] = (__v >> 56) & 0xff; ((u_char *)(p))[1] = (__v >> 48) & 0xff; ((u_char *)(p))[2] = (__v >> 40) & 0xff; ((u_char *)(p))[3] = (__v >> 32) & 0xff; ((u_char *)(p))[4] = (__v >> 24) & 0xff; ((u_char *)(p))[5] = (__v >> 16) & 0xff; ((u_char *)(p))[6] = (__v >> 8) & 0xff ; ((u_char *)(p))[7] = __v & 0xff; } while (0); |
396 | return 0; |
397 | } |
398 | |
399 | int |
400 | sshbuf_put_u32(struct sshbuf *buf, u_int32_t val) |
401 | { |
402 | u_char *p; |
403 | int r; |
404 | |
405 | if ((r = sshbuf_reserve(buf, 4, &p)) < 0) |
406 | return r; |
407 | POKE_U32(p, val)do { const u_int32_t __v = (val); ((u_char *)(p))[0] = (__v >> 24) & 0xff; ((u_char *)(p))[1] = (__v >> 16) & 0xff; ((u_char *)(p))[2] = (__v >> 8) & 0xff; ((u_char *)(p))[3] = __v & 0xff; } while (0); |
408 | return 0; |
409 | } |
410 | |
411 | int |
412 | sshbuf_put_u16(struct sshbuf *buf, u_int16_t val) |
413 | { |
414 | u_char *p; |
415 | int r; |
416 | |
417 | if ((r = sshbuf_reserve(buf, 2, &p)) < 0) |
418 | return r; |
419 | POKE_U16(p, val)do { const u_int16_t __v = (val); ((u_char *)(p))[0] = (__v >> 8) & 0xff; ((u_char *)(p))[1] = __v & 0xff; } while ( 0); |
420 | return 0; |
421 | } |
422 | |
423 | int |
424 | sshbuf_put_u8(struct sshbuf *buf, u_char val) |
425 | { |
426 | u_char *p; |
427 | int r; |
428 | |
429 | if ((r = sshbuf_reserve(buf, 1, &p)) < 0) |
430 | return r; |
431 | p[0] = val; |
432 | return 0; |
433 | } |
434 | |
435 | static int |
436 | check_woffset(struct sshbuf *buf, size_t offset, size_t len, u_char **p) |
437 | { |
438 | int r; |
439 | |
440 | *p = NULL((void *)0); |
441 | if ((r = check_offset(buf, 1, offset, len)) != 0) |
442 | return r; |
443 | if (sshbuf_mutable_ptr(buf) == NULL((void *)0)) |
444 | return SSH_ERR_BUFFER_READ_ONLY-49; |
445 | *p = sshbuf_mutable_ptr(buf) + offset; |
446 | return 0; |
447 | } |
448 | |
449 | int |
450 | sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val) |
451 | { |
452 | u_char *p = NULL((void *)0); |
453 | int r; |
454 | |
455 | if ((r = check_woffset(buf, offset, 8, &p)) != 0) |
456 | return r; |
457 | POKE_U64(p, val)do { const u_int64_t __v = (val); ((u_char *)(p))[0] = (__v >> 56) & 0xff; ((u_char *)(p))[1] = (__v >> 48) & 0xff; ((u_char *)(p))[2] = (__v >> 40) & 0xff; ((u_char *)(p))[3] = (__v >> 32) & 0xff; ((u_char *)(p))[4] = (__v >> 24) & 0xff; ((u_char *)(p))[5] = (__v >> 16) & 0xff; ((u_char *)(p))[6] = (__v >> 8) & 0xff ; ((u_char *)(p))[7] = __v & 0xff; } while (0); |
458 | return 0; |
459 | } |
460 | |
461 | int |
462 | sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val) |
463 | { |
464 | u_char *p = NULL((void *)0); |
465 | int r; |
466 | |
467 | if ((r = check_woffset(buf, offset, 4, &p)) != 0) |
468 | return r; |
469 | POKE_U32(p, val)do { const u_int32_t __v = (val); ((u_char *)(p))[0] = (__v >> 24) & 0xff; ((u_char *)(p))[1] = (__v >> 16) & 0xff; ((u_char *)(p))[2] = (__v >> 8) & 0xff; ((u_char *)(p))[3] = __v & 0xff; } while (0); |
470 | return 0; |
471 | } |
472 | |
473 | int |
474 | sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val) |
475 | { |
476 | u_char *p = NULL((void *)0); |
477 | int r; |
478 | |
479 | if ((r = check_woffset(buf, offset, 2, &p)) != 0) |
480 | return r; |
481 | POKE_U16(p, val)do { const u_int16_t __v = (val); ((u_char *)(p))[0] = (__v >> 8) & 0xff; ((u_char *)(p))[1] = __v & 0xff; } while ( 0); |
482 | return 0; |
483 | } |
484 | |
485 | int |
486 | sshbuf_poke_u8(struct sshbuf *buf, size_t offset, u_char val) |
487 | { |
488 | u_char *p = NULL((void *)0); |
489 | int r; |
490 | |
491 | if ((r = check_woffset(buf, offset, 1, &p)) != 0) |
492 | return r; |
493 | *p = val; |
494 | return 0; |
495 | } |
496 | |
497 | int |
498 | sshbuf_poke(struct sshbuf *buf, size_t offset, void *v, size_t len) |
499 | { |
500 | u_char *p = NULL((void *)0); |
501 | int r; |
502 | |
503 | if ((r = check_woffset(buf, offset, len, &p)) != 0) |
504 | return r; |
505 | memcpy(p, v, len); |
506 | return 0; |
507 | } |
508 | |
509 | int |
510 | sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len) |
511 | { |
512 | u_char *d; |
513 | int r; |
514 | |
515 | if (len > SSHBUF_SIZE_MAX0x8000000 - 4) { |
516 | SSHBUF_DBG(("SSH_ERR_NO_BUFFER_SPACE")); |
517 | return SSH_ERR_NO_BUFFER_SPACE-9; |
518 | } |
519 | if ((r = sshbuf_reserve(buf, len + 4, &d)) < 0) |
520 | return r; |
521 | POKE_U32(d, len)do { const u_int32_t __v = (len); ((u_char *)(d))[0] = (__v >> 24) & 0xff; ((u_char *)(d))[1] = (__v >> 16) & 0xff; ((u_char *)(d))[2] = (__v >> 8) & 0xff; ((u_char *)(d))[3] = __v & 0xff; } while (0); |
522 | if (len != 0) |
523 | memcpy(d + 4, v, len); |
524 | return 0; |
525 | } |
526 | |
527 | int |
528 | sshbuf_put_cstring(struct sshbuf *buf, const char *v) |
529 | { |
530 | return sshbuf_put_string(buf, v, v == NULL((void *)0) ? 0 : strlen(v)); |
531 | } |
532 | |
533 | int |
534 | sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v) |
535 | { |
536 | if (v == NULL((void *)0)) |
537 | return sshbuf_put_string(buf, NULL((void *)0), 0); |
538 | |
539 | return sshbuf_put_string(buf, sshbuf_ptr(v), sshbuf_len(v)); |
540 | } |
541 | |
542 | int |
543 | sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp) |
544 | { |
545 | const u_char *p; |
546 | size_t len; |
547 | struct sshbuf *ret; |
548 | int r; |
549 | |
550 | if (buf == NULL((void *)0) || bufp == NULL((void *)0)) |
551 | return SSH_ERR_INVALID_ARGUMENT-10; |
552 | *bufp = NULL((void *)0); |
553 | if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0) |
554 | return r; |
555 | if ((ret = sshbuf_from(p, len)) == NULL((void *)0)) |
556 | return SSH_ERR_ALLOC_FAIL-2; |
557 | if ((r = sshbuf_consume(buf, len + 4)) != 0 || /* Shouldn't happen */ |
558 | (r = sshbuf_set_parent(ret, buf)) != 0) { |
559 | sshbuf_free(ret); |
560 | return r; |
561 | } |
562 | *bufp = ret; |
563 | return 0; |
564 | } |
565 | |
566 | int |
567 | sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len) |
568 | { |
569 | u_char *d; |
570 | const u_char *s = (const u_char *)v; |
571 | int r, prepend; |
572 | |
573 | if (len > SSHBUF_SIZE_MAX0x8000000 - 5) { |
574 | SSHBUF_DBG(("SSH_ERR_NO_BUFFER_SPACE")); |
575 | return SSH_ERR_NO_BUFFER_SPACE-9; |
576 | } |
577 | /* Skip leading zero bytes */ |
578 | for (; len > 0 && *s == 0; len--, s++) |
579 | ; |
580 | /* |
581 | * If most significant bit is set then prepend a zero byte to |
582 | * avoid interpretation as a negative number. |
583 | */ |
584 | prepend = len > 0 && (s[0] & 0x80) != 0; |
585 | if ((r = sshbuf_reserve(buf, len + 4 + prepend, &d)) < 0) |
586 | return r; |
587 | POKE_U32(d, len + prepend)do { const u_int32_t __v = (len + prepend); ((u_char *)(d))[0 ] = (__v >> 24) & 0xff; ((u_char *)(d))[1] = (__v >> 16) & 0xff; ((u_char *)(d))[2] = (__v >> 8) & 0xff ; ((u_char *)(d))[3] = __v & 0xff; } while (0); |
588 | if (prepend) |
589 | d[4] = 0; |
590 | if (len != 0) |
591 | memcpy(d + 4 + prepend, s, len); |
592 | return 0; |
593 | } |
594 | |
595 | int |
596 | sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, |
597 | const u_char **valp, size_t *lenp) |
598 | { |
599 | const u_char *d; |
600 | size_t len, olen; |
601 | int r; |
602 | |
603 | if ((r = sshbuf_peek_string_direct(buf, &d, &olen)) < 0) |
604 | return r; |
605 | len = olen; |
606 | /* Refuse negative (MSB set) bignums */ |
607 | if ((len != 0 && (*d & 0x80) != 0)) |
608 | return SSH_ERR_BIGNUM_IS_NEGATIVE-5; |
609 | /* Refuse overlong bignums, allow prepended \0 to avoid MSB set */ |
610 | if (len > SSHBUF_MAX_BIGNUM(16384 / 8) + 1 || |
611 | (len == SSHBUF_MAX_BIGNUM(16384 / 8) + 1 && *d != 0)) |
612 | return SSH_ERR_BIGNUM_TOO_LARGE-7; |
613 | /* Trim leading zeros */ |
614 | while (len > 0 && *d == 0x00) { |
615 | d++; |
616 | len--; |
617 | } |
618 | if (valp != NULL((void *)0)) |
619 | *valp = d; |
620 | if (lenp != NULL((void *)0)) |
621 | *lenp = len; |
622 | if (sshbuf_consume(buf, olen + 4) != 0) { |
623 | /* Shouldn't happen */ |
624 | SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); |
625 | SSHBUF_ABORT(); |
626 | return SSH_ERR_INTERNAL_ERROR-1; |
627 | } |
628 | return 0; |
629 | } |