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 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 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