diff options
author | Colin Watson <cjwatson@debian.org> | 2014-10-07 12:13:50 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2014-10-07 12:13:50 +0100 |
commit | 487bdb3a5ef6075887b830ccb8a0b14f6da78e93 (patch) | |
tree | a2cff6fec1e6c4b4153a170a3e172cfe6bfdec46 /bufaux.c | |
parent | 796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7 (diff) | |
parent | 28453d58058a4d60c3ebe7d7f0c31a510cbf6158 (diff) |
Import openssh_6.7p1.orig.tar.gz
Diffstat (limited to 'bufaux.c')
-rw-r--r-- | bufaux.c | 337 |
1 files changed, 103 insertions, 234 deletions
@@ -1,70 +1,40 @@ | |||
1 | /* $OpenBSD: bufaux.c,v 1.56 2014/02/02 03:44:31 djm Exp $ */ | 1 | /* $OpenBSD: bufaux.c,v 1.60 2014/04/30 05:29:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Copyright (c) 2012 Damien Miller <djm@mindrot.org> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | ||
5 | * All rights reserved | ||
6 | * Auxiliary functions for storing and retrieving various data types to/from | ||
7 | * Buffers. | ||
8 | * | 4 | * |
9 | * As far as I am concerned, the code I have written for this software | 5 | * Permission to use, copy, modify, and distribute this software for any |
10 | * can be used freely for any purpose. Any derived versions of this | 6 | * purpose with or without fee is hereby granted, provided that the above |
11 | * software must be clearly marked as such, and if the derived work is | 7 | * copyright notice and this permission notice appear in all copies. |
12 | * incompatible with the protocol description in the RFC file, it must be | ||
13 | * called by a name other than "ssh" or "Secure Shell". | ||
14 | * | 8 | * |
15 | * | 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
16 | * SSH2 packet format added by Markus Friedl | 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
17 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
18 | * | 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
19 | * Redistribution and use in source and binary forms, with or without | 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
20 | * modification, are permitted provided that the following conditions | 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
21 | * are met: | 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
22 | * 1. Redistributions of source code must retain the above copyright | ||
23 | * notice, this list of conditions and the following disclaimer. | ||
24 | * 2. Redistributions in binary form must reproduce the above copyright | ||
25 | * notice, this list of conditions and the following disclaimer in the | ||
26 | * documentation and/or other materials provided with the distribution. | ||
27 | * | ||
28 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
29 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
30 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
31 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
32 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
33 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
34 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
35 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
37 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | 16 | */ |
39 | 17 | ||
18 | /* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */ | ||
19 | |||
40 | #include "includes.h" | 20 | #include "includes.h" |
41 | 21 | ||
42 | #include <sys/types.h> | 22 | #include <sys/types.h> |
43 | 23 | ||
44 | #include <openssl/bn.h> | ||
45 | |||
46 | #include <string.h> | ||
47 | #include <stdarg.h> | ||
48 | #include <stdlib.h> | ||
49 | |||
50 | #include "xmalloc.h" | ||
51 | #include "buffer.h" | 24 | #include "buffer.h" |
52 | #include "log.h" | 25 | #include "log.h" |
53 | #include "misc.h" | 26 | #include "ssherr.h" |
54 | |||
55 | /* | ||
56 | * Returns integers from the buffer (msb first). | ||
57 | */ | ||
58 | 27 | ||
59 | int | 28 | int |
60 | buffer_get_short_ret(u_short *ret, Buffer *buffer) | 29 | buffer_get_short_ret(u_short *v, Buffer *buffer) |
61 | { | 30 | { |
62 | u_char buf[2]; | 31 | int ret; |
63 | 32 | ||
64 | if (buffer_get_ret(buffer, (char *) buf, 2) == -1) | 33 | if ((ret = sshbuf_get_u16(buffer, v)) != 0) { |
65 | return (-1); | 34 | error("%s: %s", __func__, ssh_err(ret)); |
66 | *ret = get_u16(buf); | 35 | return -1; |
67 | return (0); | 36 | } |
37 | return 0; | ||
68 | } | 38 | } |
69 | 39 | ||
70 | u_short | 40 | u_short |
@@ -73,21 +43,21 @@ buffer_get_short(Buffer *buffer) | |||
73 | u_short ret; | 43 | u_short ret; |
74 | 44 | ||
75 | if (buffer_get_short_ret(&ret, buffer) == -1) | 45 | if (buffer_get_short_ret(&ret, buffer) == -1) |
76 | fatal("buffer_get_short: buffer error"); | 46 | fatal("%s: buffer error", __func__); |
77 | 47 | ||
78 | return (ret); | 48 | return (ret); |
79 | } | 49 | } |
80 | 50 | ||
81 | int | 51 | int |
82 | buffer_get_int_ret(u_int *ret, Buffer *buffer) | 52 | buffer_get_int_ret(u_int *v, Buffer *buffer) |
83 | { | 53 | { |
84 | u_char buf[4]; | 54 | int ret; |
85 | 55 | ||
86 | if (buffer_get_ret(buffer, (char *) buf, 4) == -1) | 56 | if ((ret = sshbuf_get_u32(buffer, v)) != 0) { |
87 | return (-1); | 57 | error("%s: %s", __func__, ssh_err(ret)); |
88 | if (ret != NULL) | 58 | return -1; |
89 | *ret = get_u32(buf); | 59 | } |
90 | return (0); | 60 | return 0; |
91 | } | 61 | } |
92 | 62 | ||
93 | u_int | 63 | u_int |
@@ -96,21 +66,21 @@ buffer_get_int(Buffer *buffer) | |||
96 | u_int ret; | 66 | u_int ret; |
97 | 67 | ||
98 | if (buffer_get_int_ret(&ret, buffer) == -1) | 68 | if (buffer_get_int_ret(&ret, buffer) == -1) |
99 | fatal("buffer_get_int: buffer error"); | 69 | fatal("%s: buffer error", __func__); |
100 | 70 | ||
101 | return (ret); | 71 | return (ret); |
102 | } | 72 | } |
103 | 73 | ||
104 | int | 74 | int |
105 | buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer) | 75 | buffer_get_int64_ret(u_int64_t *v, Buffer *buffer) |
106 | { | 76 | { |
107 | u_char buf[8]; | 77 | int ret; |
108 | 78 | ||
109 | if (buffer_get_ret(buffer, (char *) buf, 8) == -1) | 79 | if ((ret = sshbuf_get_u64(buffer, v)) != 0) { |
110 | return (-1); | 80 | error("%s: %s", __func__, ssh_err(ret)); |
111 | if (ret != NULL) | 81 | return -1; |
112 | *ret = get_u64(buf); | 82 | } |
113 | return (0); | 83 | return 0; |
114 | } | 84 | } |
115 | 85 | ||
116 | u_int64_t | 86 | u_int64_t |
@@ -119,78 +89,52 @@ buffer_get_int64(Buffer *buffer) | |||
119 | u_int64_t ret; | 89 | u_int64_t ret; |
120 | 90 | ||
121 | if (buffer_get_int64_ret(&ret, buffer) == -1) | 91 | if (buffer_get_int64_ret(&ret, buffer) == -1) |
122 | fatal("buffer_get_int: buffer error"); | 92 | fatal("%s: buffer error", __func__); |
123 | 93 | ||
124 | return (ret); | 94 | return (ret); |
125 | } | 95 | } |
126 | 96 | ||
127 | /* | ||
128 | * Stores integers in the buffer, msb first. | ||
129 | */ | ||
130 | void | 97 | void |
131 | buffer_put_short(Buffer *buffer, u_short value) | 98 | buffer_put_short(Buffer *buffer, u_short value) |
132 | { | 99 | { |
133 | char buf[2]; | 100 | int ret; |
134 | 101 | ||
135 | put_u16(buf, value); | 102 | if ((ret = sshbuf_put_u16(buffer, value)) != 0) |
136 | buffer_append(buffer, buf, 2); | 103 | fatal("%s: %s", __func__, ssh_err(ret)); |
137 | } | 104 | } |
138 | 105 | ||
139 | void | 106 | void |
140 | buffer_put_int(Buffer *buffer, u_int value) | 107 | buffer_put_int(Buffer *buffer, u_int value) |
141 | { | 108 | { |
142 | char buf[4]; | 109 | int ret; |
143 | 110 | ||
144 | put_u32(buf, value); | 111 | if ((ret = sshbuf_put_u32(buffer, value)) != 0) |
145 | buffer_append(buffer, buf, 4); | 112 | fatal("%s: %s", __func__, ssh_err(ret)); |
146 | } | 113 | } |
147 | 114 | ||
148 | void | 115 | void |
149 | buffer_put_int64(Buffer *buffer, u_int64_t value) | 116 | buffer_put_int64(Buffer *buffer, u_int64_t value) |
150 | { | 117 | { |
151 | char buf[8]; | 118 | int ret; |
152 | 119 | ||
153 | put_u64(buf, value); | 120 | if ((ret = sshbuf_put_u64(buffer, value)) != 0) |
154 | buffer_append(buffer, buf, 8); | 121 | fatal("%s: %s", __func__, ssh_err(ret)); |
155 | } | 122 | } |
156 | 123 | ||
157 | /* | ||
158 | * Returns an arbitrary binary string from the buffer. The string cannot | ||
159 | * be longer than 256k. The returned value points to memory allocated | ||
160 | * with xmalloc; it is the responsibility of the calling function to free | ||
161 | * the data. If length_ptr is non-NULL, the length of the returned data | ||
162 | * will be stored there. A null character will be automatically appended | ||
163 | * to the returned string, and is not counted in length. | ||
164 | */ | ||
165 | void * | 124 | void * |
166 | buffer_get_string_ret(Buffer *buffer, u_int *length_ptr) | 125 | buffer_get_string_ret(Buffer *buffer, u_int *length_ptr) |
167 | { | 126 | { |
127 | size_t len; | ||
128 | int ret; | ||
168 | u_char *value; | 129 | u_char *value; |
169 | u_int len; | ||
170 | 130 | ||
171 | /* Get the length. */ | 131 | if ((ret = sshbuf_get_string(buffer, &value, &len)) != 0) { |
172 | if (buffer_get_int_ret(&len, buffer) != 0) { | 132 | error("%s: %s", __func__, ssh_err(ret)); |
173 | error("buffer_get_string_ret: cannot extract length"); | 133 | return NULL; |
174 | return (NULL); | ||
175 | } | ||
176 | if (len > 256 * 1024) { | ||
177 | error("buffer_get_string_ret: bad string length %u", len); | ||
178 | return (NULL); | ||
179 | } | ||
180 | /* Allocate space for the string. Add one byte for a null character. */ | ||
181 | value = xmalloc(len + 1); | ||
182 | /* Get the string. */ | ||
183 | if (buffer_get_ret(buffer, value, len) == -1) { | ||
184 | error("buffer_get_string_ret: buffer_get failed"); | ||
185 | free(value); | ||
186 | return (NULL); | ||
187 | } | 134 | } |
188 | /* Append a null character to make processing easier. */ | 135 | if (length_ptr != NULL) |
189 | value[len] = '\0'; | 136 | *length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */ |
190 | /* Optionally return the length of the string. */ | 137 | return value; |
191 | if (length_ptr) | ||
192 | *length_ptr = len; | ||
193 | return (value); | ||
194 | } | 138 | } |
195 | 139 | ||
196 | void * | 140 | void * |
@@ -199,31 +143,24 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr) | |||
199 | void *ret; | 143 | void *ret; |
200 | 144 | ||
201 | if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL) | 145 | if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL) |
202 | fatal("buffer_get_string: buffer error"); | 146 | fatal("%s: buffer error", __func__); |
203 | return (ret); | 147 | return (ret); |
204 | } | 148 | } |
205 | 149 | ||
206 | char * | 150 | char * |
207 | buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr) | 151 | buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr) |
208 | { | 152 | { |
209 | u_int length; | 153 | size_t len; |
210 | char *cp, *ret = buffer_get_string_ret(buffer, &length); | 154 | int ret; |
155 | char *value; | ||
211 | 156 | ||
212 | if (ret == NULL) | 157 | if ((ret = sshbuf_get_cstring(buffer, &value, &len)) != 0) { |
158 | error("%s: %s", __func__, ssh_err(ret)); | ||
213 | return NULL; | 159 | return NULL; |
214 | if ((cp = memchr(ret, '\0', length)) != NULL) { | ||
215 | /* XXX allow \0 at end-of-string for a while, remove later */ | ||
216 | if (cp == ret + length - 1) | ||
217 | error("buffer_get_cstring_ret: string contains \\0"); | ||
218 | else { | ||
219 | explicit_bzero(ret, length); | ||
220 | free(ret); | ||
221 | return NULL; | ||
222 | } | ||
223 | } | 160 | } |
224 | if (length_ptr != NULL) | 161 | if (length_ptr != NULL) |
225 | *length_ptr = length; | 162 | *length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */ |
226 | return ret; | 163 | return value; |
227 | } | 164 | } |
228 | 165 | ||
229 | char * | 166 | char * |
@@ -232,159 +169,91 @@ buffer_get_cstring(Buffer *buffer, u_int *length_ptr) | |||
232 | char *ret; | 169 | char *ret; |
233 | 170 | ||
234 | if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL) | 171 | if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL) |
235 | fatal("buffer_get_cstring: buffer error"); | 172 | fatal("%s: buffer error", __func__); |
236 | return ret; | 173 | return ret; |
237 | } | 174 | } |
238 | 175 | ||
239 | void * | 176 | const void * |
240 | buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr) | 177 | buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr) |
241 | { | 178 | { |
242 | void *ptr; | 179 | size_t len; |
243 | u_int len; | 180 | int ret; |
181 | const u_char *value; | ||
244 | 182 | ||
245 | if (buffer_get_int_ret(&len, buffer) != 0) | 183 | if ((ret = sshbuf_get_string_direct(buffer, &value, &len)) != 0) { |
246 | return NULL; | 184 | error("%s: %s", __func__, ssh_err(ret)); |
247 | if (len > 256 * 1024) { | ||
248 | error("buffer_get_string_ptr: bad string length %u", len); | ||
249 | return NULL; | 185 | return NULL; |
250 | } | 186 | } |
251 | ptr = buffer_ptr(buffer); | 187 | if (length_ptr != NULL) |
252 | buffer_consume(buffer, len); | 188 | *length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */ |
253 | if (length_ptr) | 189 | return value; |
254 | *length_ptr = len; | ||
255 | return (ptr); | ||
256 | } | 190 | } |
257 | 191 | ||
258 | void * | 192 | const void * |
259 | buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr) | 193 | buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr) |
260 | { | 194 | { |
261 | void *ret; | 195 | const void *ret; |
262 | 196 | ||
263 | if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL) | 197 | if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL) |
264 | fatal("buffer_get_string_ptr: buffer error"); | 198 | fatal("%s: buffer error", __func__); |
265 | return (ret); | 199 | return (ret); |
266 | } | 200 | } |
267 | 201 | ||
268 | /* | ||
269 | * Stores and arbitrary binary string in the buffer. | ||
270 | */ | ||
271 | void | 202 | void |
272 | buffer_put_string(Buffer *buffer, const void *buf, u_int len) | 203 | buffer_put_string(Buffer *buffer, const void *buf, u_int len) |
273 | { | 204 | { |
274 | buffer_put_int(buffer, len); | 205 | int ret; |
275 | buffer_append(buffer, buf, len); | 206 | |
207 | if ((ret = sshbuf_put_string(buffer, buf, len)) != 0) | ||
208 | fatal("%s: %s", __func__, ssh_err(ret)); | ||
276 | } | 209 | } |
210 | |||
277 | void | 211 | void |
278 | buffer_put_cstring(Buffer *buffer, const char *s) | 212 | buffer_put_cstring(Buffer *buffer, const char *s) |
279 | { | 213 | { |
280 | if (s == NULL) | 214 | int ret; |
281 | fatal("buffer_put_cstring: s == NULL"); | 215 | |
282 | buffer_put_string(buffer, s, strlen(s)); | 216 | if ((ret = sshbuf_put_cstring(buffer, s)) != 0) |
217 | fatal("%s: %s", __func__, ssh_err(ret)); | ||
283 | } | 218 | } |
284 | 219 | ||
285 | /* | ||
286 | * Returns a character from the buffer (0 - 255). | ||
287 | */ | ||
288 | int | 220 | int |
289 | buffer_get_char_ret(u_char *ret, Buffer *buffer) | 221 | buffer_get_char_ret(char *v, Buffer *buffer) |
290 | { | 222 | { |
291 | if (buffer_get_ret(buffer, ret, 1) == -1) { | 223 | int ret; |
292 | error("buffer_get_char_ret: buffer_get_ret failed"); | 224 | |
293 | return (-1); | 225 | if ((ret = sshbuf_get_u8(buffer, (u_char *)v)) != 0) { |
226 | error("%s: %s", __func__, ssh_err(ret)); | ||
227 | return -1; | ||
294 | } | 228 | } |
295 | return (0); | 229 | return 0; |
296 | } | 230 | } |
297 | 231 | ||
298 | int | 232 | int |
299 | buffer_get_char(Buffer *buffer) | 233 | buffer_get_char(Buffer *buffer) |
300 | { | 234 | { |
301 | u_char ch; | 235 | char ch; |
302 | 236 | ||
303 | if (buffer_get_char_ret(&ch, buffer) == -1) | 237 | if (buffer_get_char_ret(&ch, buffer) == -1) |
304 | fatal("buffer_get_char: buffer error"); | 238 | fatal("%s: buffer error", __func__); |
305 | return ch; | 239 | return (u_char) ch; |
306 | } | 240 | } |
307 | 241 | ||
308 | /* | ||
309 | * Stores a character in the buffer. | ||
310 | */ | ||
311 | void | 242 | void |
312 | buffer_put_char(Buffer *buffer, int value) | 243 | buffer_put_char(Buffer *buffer, int value) |
313 | { | 244 | { |
314 | char ch = value; | 245 | int ret; |
315 | 246 | ||
316 | buffer_append(buffer, &ch, 1); | 247 | if ((ret = sshbuf_put_u8(buffer, value)) != 0) |
248 | fatal("%s: %s", __func__, ssh_err(ret)); | ||
317 | } | 249 | } |
318 | 250 | ||
319 | /* Pseudo bignum functions */ | ||
320 | |||
321 | void * | ||
322 | buffer_get_bignum2_as_string_ret(Buffer *buffer, u_int *length_ptr) | ||
323 | { | ||
324 | u_int len; | ||
325 | u_char *bin, *p, *ret; | ||
326 | |||
327 | if ((p = bin = buffer_get_string_ret(buffer, &len)) == NULL) { | ||
328 | error("%s: invalid bignum", __func__); | ||
329 | return NULL; | ||
330 | } | ||
331 | |||
332 | if (len > 0 && (bin[0] & 0x80)) { | ||
333 | error("%s: negative numbers not supported", __func__); | ||
334 | free(bin); | ||
335 | return NULL; | ||
336 | } | ||
337 | if (len > 8 * 1024) { | ||
338 | error("%s: cannot handle BN of size %d", __func__, len); | ||
339 | free(bin); | ||
340 | return NULL; | ||
341 | } | ||
342 | /* Skip zero prefix on numbers with the MSB set */ | ||
343 | if (len > 1 && bin[0] == 0x00 && (bin[1] & 0x80) != 0) { | ||
344 | p++; | ||
345 | len--; | ||
346 | } | ||
347 | ret = xmalloc(len); | ||
348 | memcpy(ret, p, len); | ||
349 | explicit_bzero(p, len); | ||
350 | free(bin); | ||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | void * | ||
355 | buffer_get_bignum2_as_string(Buffer *buffer, u_int *l) | ||
356 | { | ||
357 | void *ret = buffer_get_bignum2_as_string_ret(buffer, l); | ||
358 | |||
359 | if (ret == NULL) | ||
360 | fatal("%s: buffer error", __func__); | ||
361 | return ret; | ||
362 | } | ||
363 | |||
364 | /* | ||
365 | * Stores a string using the bignum encoding rules (\0 pad if MSB set). | ||
366 | */ | ||
367 | void | 251 | void |
368 | buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l) | 252 | buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l) |
369 | { | 253 | { |
370 | u_char *buf, *p; | 254 | int ret; |
371 | int pad = 0; | ||
372 | |||
373 | if (l > 8 * 1024) | ||
374 | fatal("%s: length %u too long", __func__, l); | ||
375 | p = buf = xmalloc(l + 1); | ||
376 | /* | ||
377 | * If most significant bit is set then prepend a zero byte to | ||
378 | * avoid interpretation as a negative number. | ||
379 | */ | ||
380 | if (l > 0 && (s[0] & 0x80) != 0) { | ||
381 | *p++ = '\0'; | ||
382 | pad = 1; | ||
383 | } | ||
384 | memcpy(p, s, l); | ||
385 | buffer_put_string(buffer, buf, l + pad); | ||
386 | explicit_bzero(buf, l + pad); | ||
387 | free(buf); | ||
388 | } | ||
389 | 255 | ||
256 | if ((ret = sshbuf_put_bignum2_bytes(buffer, s, l)) != 0) | ||
257 | fatal("%s: %s", __func__, ssh_err(ret)); | ||
258 | } | ||
390 | 259 | ||