summaryrefslogtreecommitdiffstats
path: root/bufaux.c
blob: 31e1ae9ee457b6e1efcb8935b9bd7b8045c3ef53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*

bufaux.c

Author: Tatu Ylonen <ylo@cs.hut.fi>

Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                   All rights reserved

Created: Wed Mar 29 02:24:47 1995 ylo

Auxiliary functions for storing and retrieving various data types to/from
Buffers.

*/

#include "config.h"
#include "includes.h"
RCSID("$Id: bufaux.c,v 1.3 1999/11/08 05:15:55 damien Exp $");

#include "ssh.h"

#ifdef HAVE_OPENSSL
#include <openssl/bn.h>
#endif
#ifdef HAVE_SSL
#include <ssl/bn.h>
#endif

#include "bufaux.h"
#include "xmalloc.h"
#include "getput.h"

/* Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
   by (bits+7)/8 bytes of binary data, msb first. */

void
buffer_put_bignum(Buffer *buffer, BIGNUM *value)
{
  int bits = BN_num_bits(value);
  int bin_size = (bits + 7) / 8;
  char *buf = xmalloc(bin_size);
  int oi;
  char msg[2];
  
  /* Get the value of in binary */
  oi = BN_bn2bin(value, buf);
  if (oi != bin_size)
    fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
	  oi, bin_size);

  /* Store the number of bits in the buffer in two bytes, msb first. */
  PUT_16BIT(msg, bits);
  buffer_append(buffer, msg, 2);
  /* Store the binary data. */
  buffer_append(buffer, buf, oi);
  /* Clear the temporary data. */
  memset(buf, 0, bin_size);
  xfree(buf);
}

/* Retrieves an BIGNUM from the buffer. */

int
buffer_get_bignum(Buffer *buffer, BIGNUM *value)
{
  int bits, bytes;
  unsigned char buf[2], *bin;

  /* Get the number for bits. */
  buffer_get(buffer, (char *)buf, 2);
  bits = GET_16BIT(buf);
  /* Compute the number of binary bytes that follow. */
  bytes = (bits + 7) / 8;
  bin = xmalloc(bytes);
  buffer_get(buffer, bin, bytes);
  BN_bin2bn(bin, bytes, value);
  xfree(bin);

  return 2 + bytes;
}

/* Returns an integer from the buffer (4 bytes, msb first). */

unsigned int buffer_get_int(Buffer *buffer)
{
  unsigned char buf[4];
  buffer_get(buffer, (char *)buf, 4);
  return GET_32BIT(buf);
}

/* Stores an integer in the buffer in 4 bytes, msb first. */

void buffer_put_int(Buffer *buffer, unsigned int value)
{
  char buf[4];
  PUT_32BIT(buf, value);
  buffer_append(buffer, buf, 4);
}

/* Returns an arbitrary binary string from the buffer.  The string cannot
   be longer than 256k.  The returned value points to memory allocated
   with xmalloc; it is the responsibility of the calling function to free
   the data.  If length_ptr is non-NULL, the length of the returned data
   will be stored there.  A null character will be automatically appended
   to the returned string, and is not counted in length. */

char *buffer_get_string(Buffer *buffer, unsigned int *length_ptr)
{
  unsigned int len;
  char *value;
  /* Get the length. */
  len = buffer_get_int(buffer);
  if (len > 256*1024)
    fatal("Received packet with bad string length %d", len);
  /* Allocate space for the string.  Add one byte for a null character. */
  value = xmalloc(len + 1);
  /* Get the string. */
  buffer_get(buffer, value, len);
  /* Append a null character to make processing easier. */
  value[len] = 0;
  /* Optionally return the length of the string. */
  if (length_ptr)
    *length_ptr = len;
  return value;
}

/* Stores and arbitrary binary string in the buffer. */

void buffer_put_string(Buffer *buffer, const void *buf, unsigned int len)
{
  buffer_put_int(buffer, len);
  buffer_append(buffer, buf, len);
}

/* Returns a character from the buffer (0 - 255). */

int buffer_get_char(Buffer *buffer)
{
  char ch;
  buffer_get(buffer, &ch, 1);
  return (unsigned char)ch;
}

/* Stores a character in the buffer. */

void buffer_put_char(Buffer *buffer, int value)
{
  char ch = value;
  buffer_append(buffer, &ch, 1);
}