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