]> andersk Git - gssapi-openssh.git/blame - openssh/openbsd-compat/base64.c
Re-import of OpenSSH 3.7.1p2 (Chase\!)
[gssapi-openssh.git] / openssh / openbsd-compat / base64.c
CommitLineData
41b2f314 1/* $OpenBSD: base64.c,v 1.4 2002/01/02 23:00:10 deraadt Exp $ */
3c0ef626 2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20/*
21 * Portions Copyright (c) 1995 by International Business Machines, Inc.
22 *
23 * International Business Machines, Inc. (hereinafter called IBM) grants
24 * permission under its copyrights to use, copy, modify, and distribute this
25 * Software with or without fee, provided that the above copyright notice and
26 * all paragraphs of this notice appear in all copies, and that the name of IBM
27 * not be used in connection with the marketing of any product incorporating
28 * the Software or modifications thereof, without specific, written prior
29 * permission.
30 *
31 * To the extent it has a right to do so, IBM grants an immunity from suit
32 * under its patents, if any, for the use, sale or manufacture of products to
33 * the extent that such products are used for performing Domain Name System
34 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
35 * granted for any product per se or for any other function of any product.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
38 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
40 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
41 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
42 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
43 */
44
41b2f314 45#include "includes.h"
3c0ef626 46
6a9b3198 47#if (!defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)) || (!defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON))
3c0ef626 48
49#include <sys/types.h>
50#include <sys/param.h>
51#include <sys/socket.h>
52#include <netinet/in.h>
53#include <arpa/inet.h>
54
55#include <ctype.h>
56#include <stdio.h>
57
58#include <stdlib.h>
59#include <string.h>
60
61#include "base64.h"
62
41b2f314 63/* XXX abort illegal in library */
3c0ef626 64#define Assert(Cond) if (!(Cond)) abort()
65
66static const char Base64[] =
67 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
68static const char Pad64 = '=';
69
70/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
71 The following encoding technique is taken from RFC 1521 by Borenstein
72 and Freed. It is reproduced here in a slightly edited form for
73 convenience.
74
75 A 65-character subset of US-ASCII is used, enabling 6 bits to be
76 represented per printable character. (The extra 65th character, "=",
77 is used to signify a special processing function.)
78
79 The encoding process represents 24-bit groups of input bits as output
80 strings of 4 encoded characters. Proceeding from left to right, a
81 24-bit input group is formed by concatenating 3 8-bit input groups.
82 These 24 bits are then treated as 4 concatenated 6-bit groups, each
83 of which is translated into a single digit in the base64 alphabet.
84
85 Each 6-bit group is used as an index into an array of 64 printable
86 characters. The character referenced by the index is placed in the
87 output string.
88
89 Table 1: The Base64 Alphabet
90
91 Value Encoding Value Encoding Value Encoding Value Encoding
92 0 A 17 R 34 i 51 z
93 1 B 18 S 35 j 52 0
94 2 C 19 T 36 k 53 1
95 3 D 20 U 37 l 54 2
96 4 E 21 V 38 m 55 3
97 5 F 22 W 39 n 56 4
98 6 G 23 X 40 o 57 5
99 7 H 24 Y 41 p 58 6
100 8 I 25 Z 42 q 59 7
101 9 J 26 a 43 r 60 8
102 10 K 27 b 44 s 61 9
103 11 L 28 c 45 t 62 +
104 12 M 29 d 46 u 63 /
105 13 N 30 e 47 v
106 14 O 31 f 48 w (pad) =
107 15 P 32 g 49 x
108 16 Q 33 h 50 y
109
110 Special processing is performed if fewer than 24 bits are available
111 at the end of the data being encoded. A full encoding quantum is
112 always completed at the end of a quantity. When fewer than 24 input
113 bits are available in an input group, zero bits are added (on the
114 right) to form an integral number of 6-bit groups. Padding at the
115 end of the data is performed using the '=' character.
116
117 Since all base64 input is an integral number of octets, only the
118 -------------------------------------------------
119 following cases can arise:
120
121 (1) the final quantum of encoding input is an integral
122 multiple of 24 bits; here, the final unit of encoded
123 output will be an integral multiple of 4 characters
124 with no "=" padding,
125 (2) the final quantum of encoding input is exactly 8 bits;
126 here, the final unit of encoded output will be two
127 characters followed by two "=" padding characters, or
128 (3) the final quantum of encoding input is exactly 16 bits;
129 here, the final unit of encoded output will be three
130 characters followed by one "=" padding character.
131 */
132
6a9b3198 133#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)
3c0ef626 134int
135b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize)
136{
137 size_t datalength = 0;
138 u_char input[3];
139 u_char output[4];
140 int i;
141
142 while (2 < srclength) {
143 input[0] = *src++;
144 input[1] = *src++;
145 input[2] = *src++;
146 srclength -= 3;
147
148 output[0] = input[0] >> 2;
149 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
150 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
151 output[3] = input[2] & 0x3f;
152 Assert(output[0] < 64);
153 Assert(output[1] < 64);
154 Assert(output[2] < 64);
155 Assert(output[3] < 64);
156
157 if (datalength + 4 > targsize)
158 return (-1);
159 target[datalength++] = Base64[output[0]];
160 target[datalength++] = Base64[output[1]];
161 target[datalength++] = Base64[output[2]];
162 target[datalength++] = Base64[output[3]];
163 }
164
165 /* Now we worry about padding. */
166 if (0 != srclength) {
167 /* Get what's left. */
168 input[0] = input[1] = input[2] = '\0';
169 for (i = 0; i < srclength; i++)
170 input[i] = *src++;
171
172 output[0] = input[0] >> 2;
173 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
174 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
175 Assert(output[0] < 64);
176 Assert(output[1] < 64);
177 Assert(output[2] < 64);
178
179 if (datalength + 4 > targsize)
180 return (-1);
181 target[datalength++] = Base64[output[0]];
182 target[datalength++] = Base64[output[1]];
183 if (srclength == 1)
184 target[datalength++] = Pad64;
185 else
186 target[datalength++] = Base64[output[2]];
187 target[datalength++] = Pad64;
188 }
189 if (datalength >= targsize)
190 return (-1);
191 target[datalength] = '\0'; /* Returned value doesn't count \0. */
192 return (datalength);
193}
6a9b3198 194#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */
195
196#if !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON)
3c0ef626 197
198/* skips all whitespace anywhere.
199 converts characters, four at a time, starting at (or after)
200 src from base - 64 numbers into three 8 bit bytes in the target area.
201 it returns the number of data bytes stored at the target, or -1 on error.
202 */
203
204int
205b64_pton(char const *src, u_char *target, size_t targsize)
206{
207 int tarindex, state, ch;
208 char *pos;
209
210 state = 0;
211 tarindex = 0;
212
213 while ((ch = *src++) != '\0') {
214 if (isspace(ch)) /* Skip whitespace anywhere. */
215 continue;
216
217 if (ch == Pad64)
218 break;
219
220 pos = strchr(Base64, ch);
221 if (pos == 0) /* A non-base64 character. */
222 return (-1);
223
224 switch (state) {
225 case 0:
226 if (target) {
227 if (tarindex >= targsize)
228 return (-1);
229 target[tarindex] = (pos - Base64) << 2;
230 }
231 state = 1;
232 break;
233 case 1:
234 if (target) {
235 if (tarindex + 1 >= targsize)
236 return (-1);
237 target[tarindex] |= (pos - Base64) >> 4;
238 target[tarindex+1] = ((pos - Base64) & 0x0f)
239 << 4 ;
240 }
241 tarindex++;
242 state = 2;
243 break;
244 case 2:
245 if (target) {
246 if (tarindex + 1 >= targsize)
247 return (-1);
248 target[tarindex] |= (pos - Base64) >> 2;
249 target[tarindex+1] = ((pos - Base64) & 0x03)
250 << 6;
251 }
252 tarindex++;
253 state = 3;
254 break;
255 case 3:
256 if (target) {
257 if (tarindex >= targsize)
258 return (-1);
259 target[tarindex] |= (pos - Base64);
260 }
261 tarindex++;
262 state = 0;
263 break;
264 }
265 }
266
267 /*
268 * We are done decoding Base-64 chars. Let's see if we ended
269 * on a byte boundary, and/or with erroneous trailing characters.
270 */
271
272 if (ch == Pad64) { /* We got a pad char. */
273 ch = *src++; /* Skip it, get next. */
274 switch (state) {
275 case 0: /* Invalid = in first position */
276 case 1: /* Invalid = in second position */
277 return (-1);
278
279 case 2: /* Valid, means one byte of info */
280 /* Skip any number of spaces. */
281 for (; ch != '\0'; ch = *src++)
282 if (!isspace(ch))
283 break;
284 /* Make sure there is another trailing = sign. */
285 if (ch != Pad64)
286 return (-1);
287 ch = *src++; /* Skip the = */
288 /* Fall through to "single trailing =" case. */
289 /* FALLTHROUGH */
290
291 case 3: /* Valid, means two bytes of info */
292 /*
293 * We know this char is an =. Is there anything but
294 * whitespace after it?
295 */
296 for (; ch != '\0'; ch = *src++)
297 if (!isspace(ch))
298 return (-1);
299
300 /*
301 * Now make sure for cases 2 and 3 that the "extra"
302 * bits that slopped past the last full byte were
303 * zeros. If we don't check them, they become a
304 * subliminal channel.
305 */
306 if (target && target[tarindex] != 0)
307 return (-1);
308 }
309 } else {
310 /*
311 * We ended by seeing the end of the string. Make sure we
312 * have no partial bytes lying around.
313 */
314 if (state != 0)
315 return (-1);
316 }
317
318 return (tarindex);
319}
320
6a9b3198 321#endif /* !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) */
322#endif
This page took 0.101665 seconds and 5 git commands to generate.