Annotation of src/usr.bin/ssh/bufbn.c, Revision 1.5
1.5 ! stevesk 1: /* $OpenBSD: bufbn.c,v 1.4 2006/11/06 21:25:28 markus Exp $*/
1.1 dtucker 2: /*
3: * Author: Tatu Ylonen <ylo@cs.hut.fi>
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: *
9: * As far as I am concerned, the code I have written for this software
10: * can be used freely for any purpose. Any derived versions of this
11: * software must be clearly marked as such, and if the derived work is
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: *
15: *
16: * SSH2 packet format added by Markus Friedl
17: * Copyright (c) 2000 Markus Friedl. All rights reserved.
18: *
19: * Redistribution and use in source and binary forms, with or without
20: * modification, are permitted provided that the following conditions
21: * are met:
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: */
39:
1.3 deraadt 40: #include <sys/types.h>
1.1 dtucker 41:
42: #include <openssl/bn.h>
1.2 stevesk 43:
44: #include <string.h>
1.3 deraadt 45: #include <stdarg.h>
1.2 stevesk 46:
1.1 dtucker 47: #include "xmalloc.h"
1.3 deraadt 48: #include "buffer.h"
1.1 dtucker 49: #include "log.h"
50: #include "misc.h"
51:
52: /*
53: * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
54: * by (bits+7)/8 bytes of binary data, msb first.
55: */
56: int
57: buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
58: {
59: int bits = BN_num_bits(value);
60: int bin_size = (bits + 7) / 8;
61: u_char *buf = xmalloc(bin_size);
62: int oi;
63: char msg[2];
64:
65: /* Get the value of in binary */
66: oi = BN_bn2bin(value, buf);
67: if (oi != bin_size) {
68: error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d",
69: oi, bin_size);
70: xfree(buf);
71: return (-1);
72: }
73:
74: /* Store the number of bits in the buffer in two bytes, msb first. */
75: put_u16(msg, bits);
76: buffer_append(buffer, msg, 2);
77: /* Store the binary data. */
78: buffer_append(buffer, buf, oi);
79:
80: memset(buf, 0, bin_size);
81: xfree(buf);
82:
83: return (0);
84: }
85:
86: void
87: buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
88: {
89: if (buffer_put_bignum_ret(buffer, value) == -1)
90: fatal("buffer_put_bignum: buffer error");
91: }
92:
93: /*
1.5 ! stevesk 94: * Retrieves a BIGNUM from the buffer.
1.1 dtucker 95: */
96: int
97: buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
98: {
99: u_int bits, bytes;
100: u_char buf[2], *bin;
101:
1.5 ! stevesk 102: /* Get the number of bits. */
1.1 dtucker 103: if (buffer_get_ret(buffer, (char *) buf, 2) == -1) {
104: error("buffer_get_bignum_ret: invalid length");
105: return (-1);
106: }
107: bits = get_u16(buf);
108: /* Compute the number of binary bytes that follow. */
109: bytes = (bits + 7) / 8;
110: if (bytes > 8 * 1024) {
111: error("buffer_get_bignum_ret: cannot handle BN of size %d", bytes);
112: return (-1);
113: }
114: if (buffer_len(buffer) < bytes) {
115: error("buffer_get_bignum_ret: input buffer too small");
116: return (-1);
117: }
118: bin = buffer_ptr(buffer);
1.4 markus 119: if (BN_bin2bn(bin, bytes, value) == NULL) {
120: error("buffer_get_bignum_ret: BN_bin2bn failed");
121: return (-1);
122: }
1.1 dtucker 123: if (buffer_consume_ret(buffer, bytes) == -1) {
124: error("buffer_get_bignum_ret: buffer_consume failed");
125: return (-1);
126: }
127: return (0);
128: }
129:
130: void
131: buffer_get_bignum(Buffer *buffer, BIGNUM *value)
132: {
133: if (buffer_get_bignum_ret(buffer, value) == -1)
134: fatal("buffer_get_bignum: buffer error");
135: }
136:
137: /*
1.5 ! stevesk 138: * Stores a BIGNUM in the buffer in SSH2 format.
1.1 dtucker 139: */
140: int
141: buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
142: {
143: u_int bytes;
144: u_char *buf;
145: int oi;
146: u_int hasnohigh = 0;
147:
148: if (BN_is_zero(value)) {
149: buffer_put_int(buffer, 0);
150: return 0;
151: }
152: if (value->neg) {
153: error("buffer_put_bignum2_ret: negative numbers not supported");
154: return (-1);
155: }
156: bytes = BN_num_bytes(value) + 1; /* extra padding byte */
157: if (bytes < 2) {
158: error("buffer_put_bignum2_ret: BN too small");
159: return (-1);
160: }
161: buf = xmalloc(bytes);
162: buf[0] = 0x00;
163: /* Get the value of in binary */
164: oi = BN_bn2bin(value, buf+1);
165: if (oi < 0 || (u_int)oi != bytes - 1) {
166: error("buffer_put_bignum2_ret: BN_bn2bin() failed: "
167: "oi %d != bin_size %d", oi, bytes);
168: xfree(buf);
169: return (-1);
170: }
171: hasnohigh = (buf[1] & 0x80) ? 0 : 1;
172: buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
173: memset(buf, 0, bytes);
174: xfree(buf);
175: return (0);
176: }
177:
178: void
179: buffer_put_bignum2(Buffer *buffer, const BIGNUM *value)
180: {
181: if (buffer_put_bignum2_ret(buffer, value) == -1)
182: fatal("buffer_put_bignum2: buffer error");
183: }
184:
185: int
186: buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value)
187: {
188: u_int len;
189: u_char *bin;
190:
191: if ((bin = buffer_get_string_ret(buffer, &len)) == NULL) {
192: error("buffer_get_bignum2_ret: invalid bignum");
193: return (-1);
194: }
195:
196: if (len > 0 && (bin[0] & 0x80)) {
197: error("buffer_get_bignum2_ret: negative numbers not supported");
198: xfree(bin);
199: return (-1);
200: }
201: if (len > 8 * 1024) {
202: error("buffer_get_bignum2_ret: cannot handle BN of size %d", len);
203: xfree(bin);
204: return (-1);
205: }
1.4 markus 206: if (BN_bin2bn(bin, len, value) == NULL) {
207: error("buffer_get_bignum2_ret: BN_bin2bn failed");
208: return (-1);
209: }
1.1 dtucker 210: xfree(bin);
211: return (0);
212: }
213:
214: void
215: buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
216: {
217: if (buffer_get_bignum2_ret(buffer, value) == -1)
218: fatal("buffer_get_bignum2: buffer error");
219: }