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