11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* $NetBSD: base64.c,v 1.8 2002/11/11 01:15:17 thorpej Exp $ */ 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1996 by Internet Software Consortium. 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies. 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SOFTWARE. 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Portions Copyright (c) 1995 by International Business Machines, Inc. 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * International Business Machines, Inc. (hereinafter called IBM) grants 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * permission under its copyrights to use, copy, modify, and distribute this 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Software with or without fee, provided that the above copyright notice and 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * all paragraphs of this notice appear in all copies, and that the name of IBM 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * not be used in connection with the marketing of any product incorporating 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the Software or modifications thereof, without specific, written prior 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * permission. 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * To the extent it has a right to do so, IBM grants an immunity from suit 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * under its patents, if any, for the use, sale or manufacture of products to 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the extent that such products are used for performing Domain Name System 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * dynamic updates in TCP/IP networks by means of the Software. No immunity is 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * granted for any product per se or for any other function of any product. 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h> 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(LIBC_SCCS) && !defined(lint) 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__RCSID("$NetBSD: base64.c,v 1.8 2002/11/11 01:15:17 thorpej Exp $"); 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* LIBC_SCCS and not lint */ 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h> 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/param.h> 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/socket.h> 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netinet/in.h> 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <arpa/inet.h> 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "arpa_nameser.h" 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <assert.h> 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <ctype.h> 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef ANDROID_CHANGES 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "resolv_private.h" 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <resolv.h> 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h> 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h> 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h> 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char Base64[] = 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char Pad64 = '='; 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project The following encoding technique is taken from RFC 1521 by Borenstein 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project and Freed. It is reproduced here in a slightly edited form for 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project convenience. 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project A 65-character subset of US-ASCII is used, enabling 6 bits to be 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project represented per printable character. (The extra 65th character, "=", 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project is used to signify a special processing function.) 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project The encoding process represents 24-bit groups of input bits as output 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strings of 4 encoded characters. Proceeding from left to right, a 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 24-bit input group is formed by concatenating 3 8-bit input groups. 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project These 24 bits are then treated as 4 concatenated 6-bit groups, each 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project of which is translated into a single digit in the base64 alphabet. 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Each 6-bit group is used as an index into an array of 64 printable 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project characters. The character referenced by the index is placed in the 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project output string. 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Table 1: The Base64 Alphabet 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Value Encoding Value Encoding Value Encoding Value Encoding 951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 0 A 17 R 34 i 51 z 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1 B 18 S 35 j 52 0 971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2 C 19 T 36 k 53 1 981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3 D 20 U 37 l 54 2 991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4 E 21 V 38 m 55 3 1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5 F 22 W 39 n 56 4 1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6 G 23 X 40 o 57 5 1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7 H 24 Y 41 p 58 6 1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8 I 25 Z 42 q 59 7 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9 J 26 a 43 r 60 8 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 10 K 27 b 44 s 61 9 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 11 L 28 c 45 t 62 + 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12 M 29 d 46 u 63 / 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13 N 30 e 47 v 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 14 O 31 f 48 w (pad) = 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 15 P 32 g 49 x 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 16 Q 33 h 50 y 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Special processing is performed if fewer than 24 bits are available 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project at the end of the data being encoded. A full encoding quantum is 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project always completed at the end of a quantity. When fewer than 24 input 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bits are available in an input group, zero bits are added (on the 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project right) to form an integral number of 6-bit groups. Padding at the 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project end of the data is performed using the '=' character. 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Since all base64 input is an integral number of octets, only the 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ------------------------------------------------- 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project following cases can arise: 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (1) the final quantum of encoding input is an integral 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project multiple of 24 bits; here, the final unit of encoded 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project output will be an integral multiple of 4 characters 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project with no "=" padding, 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (2) the final quantum of encoding input is exactly 8 bits; 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project here, the final unit of encoded output will be two 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project characters followed by two "=" padding characters, or 1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (3) the final quantum of encoding input is exactly 16 bits; 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project here, the final unit of encoded output will be three 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project characters followed by one "=" padding character. 1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectb64_ntop(src, srclength, target, targsize) 1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char const *src; 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t srclength; 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *target; 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t targsize; 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t datalength = 0; 14450ace4fec5e8cb5afcbc656a4556fa528adfd760David 'Digit' Turner u_char input[3] = { 0, 0, 0 }; /* make compiler happy */ 1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char output[4]; 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t i; 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(src != NULL); 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(target != NULL); 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (2 < srclength) { 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project input[0] = *src++; 1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project input[1] = *src++; 1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project input[2] = *src++; 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srclength -= 3; 1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project output[0] = (u_int32_t)input[0] >> 2; 1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project output[1] = ((u_int32_t)(input[0] & 0x03) << 4) + 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((u_int32_t)input[1] >> 4); 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) + 1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((u_int32_t)input[2] >> 6); 1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project output[3] = input[2] & 0x3f; 1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(output[0] < 64); 1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(output[1] < 64); 1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(output[2] < 64); 1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(output[3] < 64); 1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (datalength + 4 > targsize) 1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength++] = Base64[output[0]]; 1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength++] = Base64[output[1]]; 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength++] = Base64[output[2]]; 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength++] = Base64[output[3]]; 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Now we worry about padding. */ 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (0 != srclength) { 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Get what's left. */ 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project input[0] = input[1] = input[2] = '\0'; 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (i = 0; i < srclength; i++) 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project input[i] = *src++; 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project output[0] = (u_int32_t)input[0] >> 2; 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project output[1] = ((u_int32_t)(input[0] & 0x03) << 4) + 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((u_int32_t)input[1] >> 4); 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) + 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((u_int32_t)input[2] >> 6); 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(output[0] < 64); 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(output[1] < 64); 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(output[2] < 64); 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (datalength + 4 > targsize) 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength++] = Base64[output[0]]; 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength++] = Base64[output[1]]; 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (srclength == 1) 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength++] = Pad64; 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength++] = Base64[output[2]]; 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength++] = Pad64; 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (datalength >= targsize) 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[datalength] = '\0'; /* Returned value doesn't count \0. */ 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (datalength); 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* skips all whitespace anywhere. 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project converts characters, four at a time, starting at (or after) 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project src from base - 64 numbers into three 8 bit bytes in the target area. 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project it returns the number of data bytes stored at the target, or -1 on error. 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectb64_pton(src, target, targsize) 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char const *src; 2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *target; 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t targsize; 2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t tarindex; 2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int state, ch; 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *pos; 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(src != NULL); 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project assert(target != NULL); 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project state = 0; 2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tarindex = 0; 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((ch = (u_char) *src++) != '\0') { 2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (isspace(ch)) /* Skip whitespace anywhere. */ 2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == Pad64) 2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pos = strchr(Base64, ch); 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (pos == 0) /* A non-base64 character. */ 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (state) { 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 0: 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (target) { 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tarindex >= targsize) 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[tarindex] = (pos - Base64) << 2; 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project state = 1; 2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 1: 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (target) { 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tarindex + 1 >= targsize) 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[tarindex] |= 2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (u_int32_t)(pos - Base64) >> 4; 2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[tarindex+1] = ((pos - Base64) & 0x0f) 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project << 4 ; 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tarindex++; 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project state = 2; 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 2: 2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (target) { 2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tarindex + 1 >= targsize) 2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[tarindex] |= 2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (u_int32_t)(pos - Base64) >> 2; 2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[tarindex+1] = ((pos - Base64) & 0x03) 2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project << 6; 2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tarindex++; 2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project state = 3; 2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 3: 2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (target) { 2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tarindex >= targsize) 2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project target[tarindex] |= (pos - Base64); 2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tarindex++; 2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project state = 0; 2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project abort(); 2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * We are done decoding Base-64 chars. Let's see if we ended 2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * on a byte boundary, and/or with erroneous trailing characters. 2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch == Pad64) { /* We got a pad char. */ 2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ch = *src++; /* Skip it, get next. */ 2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (state) { 2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 0: /* Invalid = in first position */ 2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 1: /* Invalid = in second position */ 2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 2: /* Valid, means one byte of info */ 3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Skip any number of spaces. */ 3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (; ch != '\0'; ch = (u_char) *src++) 3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!isspace(ch)) 3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Make sure there is another trailing = sign. */ 3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ch != Pad64) 3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ch = *src++; /* Skip the = */ 3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Fall through to "single trailing =" case. */ 3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* FALLTHROUGH */ 3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 3: /* Valid, means two bytes of info */ 3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * We know this char is an =. Is there anything but 3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * whitespace after it? 3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (; ch != '\0'; ch = (u_char) *src++) 3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!isspace(ch)) 3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Now make sure for cases 2 and 3 that the "extra" 3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * bits that slopped past the last full byte were 3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * zeros. If we don't check them, they become a 3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * subliminal channel. 3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (target && target[tarindex] != 0) 3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * We ended by seeing the end of the string. Make sure we 3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * have no partial bytes lying around. 3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (state != 0) 3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (tarindex); 3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 341