source: trunk/third/openssh/bufaux.c @ 18759

Revision 18759, 6.9 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18758, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 *                    All rights reserved
5 * Auxiliary functions for storing and retrieving various data types to/from
6 * Buffers.
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose.  Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
13 *
14 *
15 * SSH2 packet format added by Markus Friedl
16 * Copyright (c) 2000 Markus Friedl.  All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 *    notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 *    notice, this list of conditions and the following disclaimer in the
25 *    documentation and/or other materials provided with the distribution.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#include "includes.h"
40RCSID("$OpenBSD: bufaux.c,v 1.27 2002/06/26 08:53:12 markus Exp $");
41
42#include <openssl/bn.h>
43#include "bufaux.h"
44#include "xmalloc.h"
45#include "getput.h"
46#include "log.h"
47
48/*
49 * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
50 * by (bits+7)/8 bytes of binary data, msb first.
51 */
52void
53buffer_put_bignum(Buffer *buffer, BIGNUM *value)
54{
55        int bits = BN_num_bits(value);
56        int bin_size = (bits + 7) / 8;
57        u_char *buf = xmalloc(bin_size);
58        int oi;
59        char msg[2];
60
61        /* Get the value of in binary */
62        oi = BN_bn2bin(value, buf);
63        if (oi != bin_size)
64                fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
65                    oi, bin_size);
66
67        /* Store the number of bits in the buffer in two bytes, msb first. */
68        PUT_16BIT(msg, bits);
69        buffer_append(buffer, msg, 2);
70        /* Store the binary data. */
71        buffer_append(buffer, (char *)buf, oi);
72
73        memset(buf, 0, bin_size);
74        xfree(buf);
75}
76
77/*
78 * Retrieves an BIGNUM from the buffer.
79 */
80void
81buffer_get_bignum(Buffer *buffer, BIGNUM *value)
82{
83        int bits, bytes;
84        u_char buf[2], *bin;
85
86        /* Get the number for bits. */
87        buffer_get(buffer, (char *) buf, 2);
88        bits = GET_16BIT(buf);
89        /* Compute the number of binary bytes that follow. */
90        bytes = (bits + 7) / 8;
91        if (bytes > 8 * 1024)
92                fatal("buffer_get_bignum: cannot handle BN of size %d", bytes);
93        if (buffer_len(buffer) < bytes)
94                fatal("buffer_get_bignum: input buffer too small");
95        bin = buffer_ptr(buffer);
96        BN_bin2bn(bin, bytes, value);
97        buffer_consume(buffer, bytes);
98}
99
100/*
101 * Stores an BIGNUM in the buffer in SSH2 format.
102 */
103void
104buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
105{
106        int bytes = BN_num_bytes(value) + 1;
107        u_char *buf = xmalloc(bytes);
108        int oi;
109        int hasnohigh = 0;
110
111        buf[0] = '\0';
112        /* Get the value of in binary */
113        oi = BN_bn2bin(value, buf+1);
114        if (oi != bytes-1)
115                fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
116                    oi, bytes);
117        hasnohigh = (buf[1] & 0x80) ? 0 : 1;
118        if (value->neg) {
119                /**XXX should be two's-complement */
120                int i, carry;
121                u_char *uc = buf;
122                log("negativ!");
123                for (i = bytes-1, carry = 1; i>=0; i--) {
124                        uc[i] ^= 0xff;
125                        if (carry)
126                                carry = !++uc[i];
127                }
128        }
129        buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
130        memset(buf, 0, bytes);
131        xfree(buf);
132}
133
134/* XXX does not handle negative BNs */
135void
136buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
137{
138        u_int len;
139        u_char *bin = buffer_get_string(buffer, &len);
140
141        if (len > 8 * 1024)
142                fatal("buffer_get_bignum2: cannot handle BN of size %d", len);
143        BN_bin2bn(bin, len, value);
144        xfree(bin);
145}
146/*
147 * Returns integers from the buffer (msb first).
148 */
149
150u_short
151buffer_get_short(Buffer *buffer)
152{
153        u_char buf[2];
154
155        buffer_get(buffer, (char *) buf, 2);
156        return GET_16BIT(buf);
157}
158
159u_int
160buffer_get_int(Buffer *buffer)
161{
162        u_char buf[4];
163
164        buffer_get(buffer, (char *) buf, 4);
165        return GET_32BIT(buf);
166}
167
168#ifdef HAVE_U_INT64_T
169u_int64_t
170buffer_get_int64(Buffer *buffer)
171{
172        u_char buf[8];
173
174        buffer_get(buffer, (char *) buf, 8);
175        return GET_64BIT(buf);
176}
177#endif
178
179/*
180 * Stores integers in the buffer, msb first.
181 */
182void
183buffer_put_short(Buffer *buffer, u_short value)
184{
185        char buf[2];
186
187        PUT_16BIT(buf, value);
188        buffer_append(buffer, buf, 2);
189}
190
191void
192buffer_put_int(Buffer *buffer, u_int value)
193{
194        char buf[4];
195
196        PUT_32BIT(buf, value);
197        buffer_append(buffer, buf, 4);
198}
199
200#ifdef HAVE_U_INT64_T
201void
202buffer_put_int64(Buffer *buffer, u_int64_t value)
203{
204        char buf[8];
205
206        PUT_64BIT(buf, value);
207        buffer_append(buffer, buf, 8);
208}
209#endif
210
211/*
212 * Returns an arbitrary binary string from the buffer.  The string cannot
213 * be longer than 256k.  The returned value points to memory allocated
214 * with xmalloc; it is the responsibility of the calling function to free
215 * the data.  If length_ptr is non-NULL, the length of the returned data
216 * will be stored there.  A null character will be automatically appended
217 * to the returned string, and is not counted in length.
218 */
219void *
220buffer_get_string(Buffer *buffer, u_int *length_ptr)
221{
222        u_char *value;
223        u_int len;
224
225        /* Get the length. */
226        len = buffer_get_int(buffer);
227        if (len > 256 * 1024)
228                fatal("buffer_get_string: bad string length %d", len);
229        /* Allocate space for the string.  Add one byte for a null character. */
230        value = xmalloc(len + 1);
231        /* Get the string. */
232        buffer_get(buffer, value, len);
233        /* Append a null character to make processing easier. */
234        value[len] = 0;
235        /* Optionally return the length of the string. */
236        if (length_ptr)
237                *length_ptr = len;
238        return value;
239}
240
241/*
242 * Stores and arbitrary binary string in the buffer.
243 */
244void
245buffer_put_string(Buffer *buffer, const void *buf, u_int len)
246{
247        buffer_put_int(buffer, len);
248        buffer_append(buffer, buf, len);
249}
250void
251buffer_put_cstring(Buffer *buffer, const char *s)
252{
253        if (s == NULL)
254                fatal("buffer_put_cstring: s == NULL");
255        buffer_put_string(buffer, s, strlen(s));
256}
257
258/*
259 * Returns a character from the buffer (0 - 255).
260 */
261int
262buffer_get_char(Buffer *buffer)
263{
264        char ch;
265
266        buffer_get(buffer, &ch, 1);
267        return (u_char) ch;
268}
269
270/*
271 * Stores a character in the buffer.
272 */
273void
274buffer_put_char(Buffer *buffer, int value)
275{
276        char ch = value;
277
278        buffer_append(buffer, &ch, 1);
279}
Note: See TracBrowser for help on using the repository browser.