00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "includes.h"
00040 RCSID("$OpenBSD: bufaux.c,v 1.37 2005/11/05 05:01:15 djm Exp $");
00041
00042 #include <openssl/bn.h>
00043 #include "bufaux.h"
00044 #include "xmalloc.h"
00045 #include "getput.h"
00046 #include "log.h"
00047
00048
00049
00050
00051
00052 int
00053 buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
00054 {
00055 int bits = BN_num_bits(value);
00056 int bin_size = (bits + 7) / 8;
00057 u_char *buf = xmalloc(bin_size);
00058 int oi;
00059 char msg[2];
00060
00061
00062 oi = BN_bn2bin(value, buf);
00063 if (oi != bin_size) {
00064 error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d",
00065 oi, bin_size);
00066 xfree(buf);
00067 return (-1);
00068 }
00069
00070
00071 PUT_16BIT(msg, bits);
00072 buffer_append(buffer, msg, 2);
00073
00074 buffer_append(buffer, (char *)buf, oi);
00075
00076 memset(buf, 0, bin_size);
00077 xfree(buf);
00078
00079 return (0);
00080 }
00081
00082 void
00083 buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
00084 {
00085 if (buffer_put_bignum_ret(buffer, value) == -1)
00086 fatal("buffer_put_bignum: buffer error");
00087 }
00088
00089
00090
00091
00092 int
00093 buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
00094 {
00095 u_int bits, bytes;
00096 u_char buf[2], *bin;
00097
00098
00099 if (buffer_get_ret(buffer, (char *) buf, 2) == -1) {
00100 error("buffer_get_bignum_ret: invalid length");
00101 return (-1);
00102 }
00103 bits = GET_16BIT(buf);
00104
00105 bytes = (bits + 7) / 8;
00106 if (bytes > 8 * 1024) {
00107 error("buffer_get_bignum_ret: cannot handle BN of size %d", bytes);
00108 return (-1);
00109 }
00110 if (buffer_len(buffer) < bytes) {
00111 error("buffer_get_bignum_ret: input buffer too small");
00112 return (-1);
00113 }
00114 bin = buffer_ptr(buffer);
00115 BN_bin2bn(bin, bytes, value);
00116 if (buffer_consume_ret(buffer, bytes) == -1) {
00117 error("buffer_get_bignum_ret: buffer_consume failed");
00118 return (-1);
00119 }
00120 return (0);
00121 }
00122
00123 void
00124 buffer_get_bignum(Buffer *buffer, BIGNUM *value)
00125 {
00126 if (buffer_get_bignum_ret(buffer, value) == -1)
00127 fatal("buffer_get_bignum: buffer error");
00128 }
00129
00130
00131
00132
00133 int
00134 buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
00135 {
00136 u_int bytes;
00137 u_char *buf;
00138 int oi;
00139 u_int hasnohigh = 0;
00140
00141 if (BN_is_zero(value)) {
00142 buffer_put_int(buffer, 0);
00143 return 0;
00144 }
00145 if (value->neg) {
00146 error("buffer_put_bignum2_ret: negative numbers not supported");
00147 return (-1);
00148 }
00149 bytes = BN_num_bytes(value) + 1;
00150 if (bytes < 2) {
00151 error("buffer_put_bignum2_ret: BN too small");
00152 return (-1);
00153 }
00154 buf = xmalloc(bytes);
00155 buf[0] = 0x00;
00156
00157 oi = BN_bn2bin(value, buf+1);
00158 if (oi < 0 || (u_int)oi != bytes - 1) {
00159 error("buffer_put_bignum2_ret: BN_bn2bin() failed: "
00160 "oi %d != bin_size %d", oi, bytes);
00161 xfree(buf);
00162 return (-1);
00163 }
00164 hasnohigh = (buf[1] & 0x80) ? 0 : 1;
00165 buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
00166 memset(buf, 0, bytes);
00167 xfree(buf);
00168 return (0);
00169 }
00170
00171 void
00172 buffer_put_bignum2(Buffer *buffer, const BIGNUM *value)
00173 {
00174 if (buffer_put_bignum2_ret(buffer, value) == -1)
00175 fatal("buffer_put_bignum2: buffer error");
00176 }
00177
00178 int
00179 buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value)
00180 {
00181 u_int len;
00182 u_char *bin;
00183
00184 if ((bin = buffer_get_string_ret(buffer, &len)) == NULL) {
00185 error("buffer_get_bignum2_ret: invalid bignum");
00186 return (-1);
00187 }
00188
00189 if (len > 0 && (bin[0] & 0x80)) {
00190 error("buffer_get_bignum2_ret: negative numbers not supported");
00191 xfree(bin);
00192 return (-1);
00193 }
00194 if (len > 8 * 1024) {
00195 error("buffer_get_bignum2_ret: cannot handle BN of size %d", len);
00196 xfree(bin);
00197 return (-1);
00198 }
00199 BN_bin2bn(bin, len, value);
00200 xfree(bin);
00201 return (0);
00202 }
00203
00204 void
00205 buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
00206 {
00207 if (buffer_get_bignum2_ret(buffer, value) == -1)
00208 fatal("buffer_get_bignum2: buffer error");
00209 }
00210
00211
00212
00213
00214
00215 int
00216 buffer_get_short_ret(u_short *ret, Buffer *buffer)
00217 {
00218 u_char buf[2];
00219
00220 if (buffer_get_ret(buffer, (char *) buf, 2) == -1)
00221 return (-1);
00222 *ret = GET_16BIT(buf);
00223 return (0);
00224 }
00225
00226 u_short
00227 buffer_get_short(Buffer *buffer)
00228 {
00229 u_short ret;
00230
00231 if (buffer_get_short_ret(&ret, buffer) == -1)
00232 fatal("buffer_get_short: buffer error");
00233
00234 return (ret);
00235 }
00236
00237 int
00238 buffer_get_int_ret(u_int *ret, Buffer *buffer)
00239 {
00240 u_char buf[4];
00241
00242 if (buffer_get_ret(buffer, (char *) buf, 4) == -1)
00243 return (-1);
00244 *ret = GET_32BIT(buf);
00245 return (0);
00246 }
00247
00248 u_int
00249 buffer_get_int(Buffer *buffer)
00250 {
00251 u_int ret;
00252
00253 if (buffer_get_int_ret(&ret, buffer) == -1)
00254 fatal("buffer_get_int: buffer error");
00255
00256 return (ret);
00257 }
00258
00259 int
00260 buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer)
00261 {
00262 u_char buf[8];
00263
00264 if (buffer_get_ret(buffer, (char *) buf, 8) == -1)
00265 return (-1);
00266 *ret = GET_64BIT(buf);
00267 return (0);
00268 }
00269
00270 u_int64_t
00271 buffer_get_int64(Buffer *buffer)
00272 {
00273 u_int64_t ret;
00274
00275 if (buffer_get_int64_ret(&ret, buffer) == -1)
00276 fatal("buffer_get_int: buffer error");
00277
00278 return (ret);
00279 }
00280
00281
00282
00283
00284 void
00285 buffer_put_short(Buffer *buffer, u_short value)
00286 {
00287 char buf[2];
00288
00289 PUT_16BIT(buf, value);
00290 buffer_append(buffer, buf, 2);
00291 }
00292
00293 void
00294 buffer_put_int(Buffer *buffer, u_int value)
00295 {
00296 char buf[4];
00297
00298 PUT_32BIT(buf, value);
00299 buffer_append(buffer, buf, 4);
00300 }
00301
00302 void
00303 buffer_put_int64(Buffer *buffer, u_int64_t value)
00304 {
00305 char buf[8];
00306
00307 PUT_64BIT(buf, value);
00308 buffer_append(buffer, buf, 8);
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 void *
00320 buffer_get_string_ret(Buffer *buffer, u_int *length_ptr)
00321 {
00322 u_char *value;
00323 u_int len;
00324
00325
00326 len = buffer_get_int(buffer);
00327 if (len > 256 * 1024) {
00328 error("buffer_get_string_ret: bad string length %u", len);
00329 return (NULL);
00330 }
00331
00332 value = xmalloc(len + 1);
00333
00334 if (buffer_get_ret(buffer, value, len) == -1) {
00335 error("buffer_get_string_ret: buffer_get failed");
00336 xfree(value);
00337 return (NULL);
00338 }
00339
00340 value[len] = 0;
00341
00342 if (length_ptr)
00343 *length_ptr = len;
00344 return (value);
00345 }
00346
00347 void *
00348 buffer_get_string(Buffer *buffer, u_int *length_ptr)
00349 {
00350 void *ret;
00351
00352 if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL)
00353 fatal("buffer_get_string: buffer error");
00354 return (ret);
00355 }
00356
00357
00358
00359
00360 void
00361 buffer_put_string(Buffer *buffer, const void *buf, u_int len)
00362 {
00363 buffer_put_int(buffer, len);
00364 buffer_append(buffer, buf, len);
00365 }
00366 void
00367 buffer_put_cstring(Buffer *buffer, const char *s)
00368 {
00369 if (s == NULL)
00370 fatal("buffer_put_cstring: s == NULL");
00371 buffer_put_string(buffer, s, strlen(s));
00372 }
00373
00374
00375
00376
00377 int
00378 buffer_get_char_ret(char *ret, Buffer *buffer)
00379 {
00380 if (buffer_get_ret(buffer, ret, 1) == -1) {
00381 error("buffer_get_char_ret: buffer_get_ret failed");
00382 return (-1);
00383 }
00384 return (0);
00385 }
00386
00387 int
00388 buffer_get_char(Buffer *buffer)
00389 {
00390 char ch;
00391
00392 if (buffer_get_char_ret(&ch, buffer) == -1)
00393 fatal("buffer_get_char: buffer error");
00394 return (u_char) ch;
00395 }
00396
00397
00398
00399
00400 void
00401 buffer_put_char(Buffer *buffer, int value)
00402 {
00403 char ch = value;
00404
00405 buffer_append(buffer, &ch, 1);
00406 }