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