]> andersk Git - openssh.git/blob - bufaux.c
- OpenBSD CVS Updates:
[openssh.git] / bufaux.c
1 /*
2  *
3  * bufaux.c
4  *
5  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6  *
7  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8  *                    All rights reserved
9  *
10  * Created: Wed Mar 29 02:24:47 1995 ylo
11  *
12  * Auxiliary functions for storing and retrieving various data types to/from
13  * Buffers.
14  *
15  * SSH2 packet format added by Markus Friedl
16  *
17  */
18
19 #include "includes.h"
20 RCSID("$OpenBSD: bufaux.c,v 1.12 2000/06/20 01:39:39 markus Exp $");
21
22 #include "ssh.h"
23 #include <openssl/bn.h>
24 #include "bufaux.h"
25 #include "xmalloc.h"
26 #include "getput.h"
27
28 /*
29  * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
30  * by (bits+7)/8 bytes of binary data, msb first.
31  */
32 void
33 buffer_put_bignum(Buffer *buffer, BIGNUM *value)
34 {
35         int bits = BN_num_bits(value);
36         int bin_size = (bits + 7) / 8;
37         char unsigned *buf = xmalloc(bin_size);
38         int oi;
39         char msg[2];
40
41         /* Get the value of in binary */
42         oi = BN_bn2bin(value, buf);
43         if (oi != bin_size)
44                 fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
45                       oi, bin_size);
46
47         /* Store the number of bits in the buffer in two bytes, msb first. */
48         PUT_16BIT(msg, bits);
49         buffer_append(buffer, msg, 2);
50         /* Store the binary data. */
51         buffer_append(buffer, (char *)buf, oi);
52
53         memset(buf, 0, bin_size);
54         xfree(buf);
55 }
56
57 /*
58  * Retrieves an BIGNUM from the buffer.
59  */
60 int
61 buffer_get_bignum(Buffer *buffer, BIGNUM *value)
62 {
63         int bits, bytes;
64         unsigned char buf[2], *bin;
65
66         /* Get the number for bits. */
67         buffer_get(buffer, (char *) buf, 2);
68         bits = GET_16BIT(buf);
69         /* Compute the number of binary bytes that follow. */
70         bytes = (bits + 7) / 8;
71         if (buffer_len(buffer) < bytes)
72                 fatal("buffer_get_bignum: input buffer too small");
73         bin = (unsigned char*) buffer_ptr(buffer);
74         BN_bin2bn(bin, bytes, value);
75         buffer_consume(buffer, bytes);
76
77         return 2 + bytes;
78 }
79
80 /*
81  * Stores an BIGNUM in the buffer in SSH2 format.
82  */
83 void
84 buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
85 {
86         int bytes = BN_num_bytes(value) + 1;
87         unsigned char *buf = xmalloc(bytes);
88         int oi;
89         int hasnohigh = 0;
90         buf[0] = '\0';
91         /* Get the value of in binary */
92         oi = BN_bn2bin(value, buf+1);
93         if (oi != bytes-1)
94                 fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
95                       oi, bytes);
96         hasnohigh = (buf[1] & 0x80) ? 0 : 1;
97         if (value->neg) {
98                 /**XXX should be two's-complement */
99                 int i, carry;
100                 unsigned char *uc = buf;
101                 log("negativ!");
102                 for(i = bytes-1, carry = 1; i>=0; i--) {
103                         uc[i] ^= 0xff;
104                         if(carry)
105                                 carry = !++uc[i];
106                 }
107         }
108         buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
109         memset(buf, 0, bytes);
110         xfree(buf);
111 }
112
113 int
114 buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
115 {
116         /**XXX should be two's-complement */
117         int len;
118         unsigned char *bin = (unsigned char *)buffer_get_string(buffer, (unsigned int *)&len);
119         BN_bin2bn(bin, len, value);
120         xfree(bin);
121         return len;
122 }
123
124 /*
125  * Returns an integer from the buffer (4 bytes, msb first).
126  */
127 unsigned int
128 buffer_get_int(Buffer *buffer)
129 {
130         unsigned char buf[4];
131         buffer_get(buffer, (char *) buf, 4);
132         return GET_32BIT(buf);
133 }
134
135 /*
136  * Stores an integer in the buffer in 4 bytes, msb first.
137  */
138 void
139 buffer_put_int(Buffer *buffer, unsigned int value)
140 {
141         char buf[4];
142         PUT_32BIT(buf, value);
143         buffer_append(buffer, buf, 4);
144 }
145
146 /*
147  * Returns an arbitrary binary string from the buffer.  The string cannot
148  * be longer than 256k.  The returned value points to memory allocated
149  * with xmalloc; it is the responsibility of the calling function to free
150  * the data.  If length_ptr is non-NULL, the length of the returned data
151  * will be stored there.  A null character will be automatically appended
152  * to the returned string, and is not counted in length.
153  */
154 char *
155 buffer_get_string(Buffer *buffer, unsigned int *length_ptr)
156 {
157         unsigned int len;
158         char *value;
159         /* Get the length. */
160         len = buffer_get_int(buffer);
161         if (len > 256 * 1024)
162                 fatal("Received packet with bad string length %d", len);
163         /* Allocate space for the string.  Add one byte for a null character. */
164         value = xmalloc(len + 1);
165         /* Get the string. */
166         buffer_get(buffer, value, len);
167         /* Append a null character to make processing easier. */
168         value[len] = 0;
169         /* Optionally return the length of the string. */
170         if (length_ptr)
171                 *length_ptr = len;
172         return value;
173 }
174
175 /*
176  * Stores and arbitrary binary string in the buffer.
177  */
178 void
179 buffer_put_string(Buffer *buffer, const void *buf, unsigned int len)
180 {
181         buffer_put_int(buffer, len);
182         buffer_append(buffer, buf, len);
183 }
184 void
185 buffer_put_cstring(Buffer *buffer, const char *s)
186 {
187         buffer_put_string(buffer, s, strlen(s));
188 }
189
190 /*
191  * Returns a character from the buffer (0 - 255).
192  */
193 int
194 buffer_get_char(Buffer *buffer)
195 {
196         char ch;
197         buffer_get(buffer, &ch, 1);
198         return (unsigned char) ch;
199 }
200
201 /*
202  * Stores a character in the buffer.
203  */
204 void
205 buffer_put_char(Buffer *buffer, int value)
206 {
207         char ch = value;
208         buffer_append(buffer, &ch, 1);
209 }
This page took 0.622172 seconds and 5 git commands to generate.