11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1996 by Internet Software Consortium. 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Permission to use, copy, modify, and distribute this software for any 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * purpose with or without fee is hereby granted, provided that the above 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * copyright notice and this permission notice appear in all copies. 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SOFTWARE. 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Portions Copyright (c) 1995 by International Business Machines, Inc. 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * International Business Machines, Inc. (hereinafter called IBM) grants 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * permission under its copyrights to use, copy, modify, and distribute this 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Software with or without fee, provided that the above copyright notice and 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * all paragraphs of this notice appear in all copies, and that the name of IBM 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * not be used in connection with the marketing of any product incorporating 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the Software or modifications thereof, without specific, written prior 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * permission. 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * To the extent it has a right to do so, IBM grants an immunity from suit 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * under its patents, if any, for the use, sale or manufacture of products to 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the extent that such products are used for performing Domain Name System 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * dynamic updates in TCP/IP networks by means of the Software. No immunity is 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * granted for any product per se or for any other function of any product. 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* OPENBSD ORIGINAL: lib/libc/net/base64.c */ 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if (!defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)) || (!defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON)) 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/param.h> 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h> 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/in.h> 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <arpa/inet.h> 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <ctype.h> 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h> 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "base64.h" 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic const char Base64[] = 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic const char Pad64 = '='; 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood The following encoding technique is taken from RFC 1521 by Borenstein 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood and Freed. It is reproduced here in a slightly edited form for 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood convenience. 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood A 65-character subset of US-ASCII is used, enabling 6 bits to be 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood represented per printable character. (The extra 65th character, "=", 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood is used to signify a special processing function.) 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood The encoding process represents 24-bit groups of input bits as output 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strings of 4 encoded characters. Proceeding from left to right, a 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24-bit input group is formed by concatenating 3 8-bit input groups. 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood These 24 bits are then treated as 4 concatenated 6-bit groups, each 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood of which is translated into a single digit in the base64 alphabet. 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Each 6-bit group is used as an index into an array of 64 printable 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood characters. The character referenced by the index is placed in the 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood output string. 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Table 1: The Base64 Alphabet 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Value Encoding Value Encoding Value Encoding Value Encoding 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 0 A 17 R 34 i 51 z 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1 B 18 S 35 j 52 0 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2 C 19 T 36 k 53 1 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3 D 20 U 37 l 54 2 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4 E 21 V 38 m 55 3 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5 F 22 W 39 n 56 4 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6 G 23 X 40 o 57 5 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7 H 24 Y 41 p 58 6 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8 I 25 Z 42 q 59 7 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9 J 26 a 43 r 60 8 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10 K 27 b 44 s 61 9 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11 L 28 c 45 t 62 + 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12 M 29 d 46 u 63 / 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13 N 30 e 47 v 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14 O 31 f 48 w (pad) = 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15 P 32 g 49 x 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16 Q 33 h 50 y 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Special processing is performed if fewer than 24 bits are available 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood at the end of the data being encoded. A full encoding quantum is 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood always completed at the end of a quantity. When fewer than 24 input 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bits are available in an input group, zero bits are added (on the 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood right) to form an integral number of 6-bit groups. Padding at the 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood end of the data is performed using the '=' character. 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Since all base64 input is an integral number of octets, only the 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ------------------------------------------------- 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood following cases can arise: 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (1) the final quantum of encoding input is an integral 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood multiple of 24 bits; here, the final unit of encoded 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood output will be an integral multiple of 4 characters 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood with no "=" padding, 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (2) the final quantum of encoding input is exactly 8 bits; 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood here, the final unit of encoded output will be two 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood characters followed by two "=" padding characters, or 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (3) the final quantum of encoding input is exactly 16 bits; 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood here, the final unit of encoded output will be three 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood characters followed by one "=" padding character. 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodb64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood size_t datalength = 0; 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char input[3]; 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char output[4]; 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (2 < srclength) { 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input[0] = *src++; 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input[1] = *src++; 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input[2] = *src++; 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood srclength -= 3; 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood output[0] = input[0] >> 2; 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood output[3] = input[2] & 0x3f; 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (datalength + 4 > targsize) 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength++] = Base64[output[0]]; 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength++] = Base64[output[1]]; 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength++] = Base64[output[2]]; 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength++] = Base64[output[3]]; 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Now we worry about padding. */ 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (0 != srclength) { 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Get what's left. */ 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input[0] = input[1] = input[2] = '\0'; 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < srclength; i++) 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input[i] = *src++; 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood output[0] = input[0] >> 2; 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (datalength + 4 > targsize) 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength++] = Base64[output[0]]; 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength++] = Base64[output[1]]; 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (srclength == 1) 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength++] = Pad64; 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength++] = Base64[output[2]]; 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength++] = Pad64; 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (datalength >= targsize) 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[datalength] = '\0'; /* Returned value doesn't count \0. */ 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (datalength); 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* skips all whitespace anywhere. 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood converts characters, four at a time, starting at (or after) 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood src from base - 64 numbers into three 8 bit bytes in the target area. 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood it returns the number of data bytes stored at the target, or -1 on error. 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodb64_pton(char const *src, u_char *target, size_t targsize) 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int tarindex, state; 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ch; 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *pos; 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = 0; 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tarindex = 0; 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while ((ch = *src++) != '\0') { 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (isspace(ch)) /* Skip whitespace anywhere. */ 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ch == Pad64) 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pos = strchr(Base64, ch); 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pos == 0) /* A non-base64 character. */ 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (state) { 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 0: 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (target) { 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tarindex >= targsize) 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[tarindex] = (pos - Base64) << 2; 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = 1; 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 1: 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (target) { 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tarindex + 1 >= targsize) 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[tarindex] |= (pos - Base64) >> 4; 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[tarindex+1] = ((pos - Base64) & 0x0f) 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood << 4 ; 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tarindex++; 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = 2; 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 2: 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (target) { 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tarindex + 1 >= targsize) 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[tarindex] |= (pos - Base64) >> 2; 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[tarindex+1] = ((pos - Base64) & 0x03) 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood << 6; 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tarindex++; 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = 3; 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 3: 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (target) { 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tarindex >= targsize) 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood target[tarindex] |= (pos - Base64); 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tarindex++; 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood state = 0; 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We are done decoding Base-64 chars. Let's see if we ended 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * on a byte boundary, and/or with erroneous trailing characters. 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ch == Pad64) { /* We got a pad char. */ 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *src++; /* Skip it, get next. */ 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (state) { 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 0: /* Invalid = in first position */ 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 1: /* Invalid = in second position */ 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 2: /* Valid, means one byte of info */ 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Skip any number of spaces. */ 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (; ch != '\0'; ch = *src++) 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!isspace(ch)) 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Make sure there is another trailing = sign. */ 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ch != Pad64) 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = *src++; /* Skip the = */ 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Fall through to "single trailing =" case. */ 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* FALLTHROUGH */ 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 3: /* Valid, means two bytes of info */ 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We know this char is an =. Is there anything but 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * whitespace after it? 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (; ch != '\0'; ch = *src++) 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!isspace(ch)) 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Now make sure for cases 2 and 3 that the "extra" 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * bits that slopped past the last full byte were 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * zeros. If we don't check them, they become a 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * subliminal channel. 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (target && target[tarindex] != 0) 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We ended by seeing the end of the string. Make sure we 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * have no partial bytes lying around. 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (state != 0) 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (tarindex); 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) */ 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 316