1181111Sdes/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */ 298937Sdes 398937Sdes/* 498937Sdes * Copyright (c) 1996 by Internet Software Consortium. 598937Sdes * 698937Sdes * Permission to use, copy, modify, and distribute this software for any 798937Sdes * purpose with or without fee is hereby granted, provided that the above 898937Sdes * copyright notice and this permission notice appear in all copies. 998937Sdes * 1098937Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 1198937Sdes * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 1298937Sdes * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 1398937Sdes * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 1498937Sdes * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 1598937Sdes * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 1698937Sdes * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 1798937Sdes * SOFTWARE. 1898937Sdes */ 1998937Sdes 2098937Sdes/* 2198937Sdes * Portions Copyright (c) 1995 by International Business Machines, Inc. 2298937Sdes * 2398937Sdes * International Business Machines, Inc. (hereinafter called IBM) grants 2498937Sdes * permission under its copyrights to use, copy, modify, and distribute this 2598937Sdes * Software with or without fee, provided that the above copyright notice and 2698937Sdes * all paragraphs of this notice appear in all copies, and that the name of IBM 2798937Sdes * not be used in connection with the marketing of any product incorporating 2898937Sdes * the Software or modifications thereof, without specific, written prior 2998937Sdes * permission. 3098937Sdes * 3198937Sdes * To the extent it has a right to do so, IBM grants an immunity from suit 3298937Sdes * under its patents, if any, for the use, sale or manufacture of products to 3398937Sdes * the extent that such products are used for performing Domain Name System 3498937Sdes * dynamic updates in TCP/IP networks by means of the Software. No immunity is 3598937Sdes * granted for any product per se or for any other function of any product. 3698937Sdes * 3798937Sdes * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, 3898937Sdes * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 3998937Sdes * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, 4098937Sdes * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING 4198937Sdes * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN 4298937Sdes * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. 4398937Sdes */ 4498937Sdes 45157016Sdes/* OPENBSD ORIGINAL: lib/libc/net/base64.c */ 46157016Sdes 47106121Sdes#include "includes.h" 4898937Sdes 49113908Sdes#if (!defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)) || (!defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON)) 5098937Sdes 5198937Sdes#include <sys/types.h> 5298937Sdes#include <sys/param.h> 5398937Sdes#include <sys/socket.h> 5498937Sdes#include <netinet/in.h> 5598937Sdes#include <arpa/inet.h> 5698937Sdes 5798937Sdes#include <ctype.h> 5898937Sdes#include <stdio.h> 5998937Sdes 6098937Sdes#include <stdlib.h> 6198937Sdes#include <string.h> 6298937Sdes 6398937Sdes#include "base64.h" 6498937Sdes 6598937Sdesstatic const char Base64[] = 6698937Sdes "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 6798937Sdesstatic const char Pad64 = '='; 6898937Sdes 6998937Sdes/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) 7098937Sdes The following encoding technique is taken from RFC 1521 by Borenstein 7198937Sdes and Freed. It is reproduced here in a slightly edited form for 7298937Sdes convenience. 7398937Sdes 7498937Sdes A 65-character subset of US-ASCII is used, enabling 6 bits to be 7598937Sdes represented per printable character. (The extra 65th character, "=", 7698937Sdes is used to signify a special processing function.) 7798937Sdes 7898937Sdes The encoding process represents 24-bit groups of input bits as output 7998937Sdes strings of 4 encoded characters. Proceeding from left to right, a 8098937Sdes 24-bit input group is formed by concatenating 3 8-bit input groups. 8198937Sdes These 24 bits are then treated as 4 concatenated 6-bit groups, each 8298937Sdes of which is translated into a single digit in the base64 alphabet. 8398937Sdes 8498937Sdes Each 6-bit group is used as an index into an array of 64 printable 8598937Sdes characters. The character referenced by the index is placed in the 8698937Sdes output string. 8798937Sdes 8898937Sdes Table 1: The Base64 Alphabet 8998937Sdes 9098937Sdes Value Encoding Value Encoding Value Encoding Value Encoding 9198937Sdes 0 A 17 R 34 i 51 z 9298937Sdes 1 B 18 S 35 j 52 0 9398937Sdes 2 C 19 T 36 k 53 1 9498937Sdes 3 D 20 U 37 l 54 2 9598937Sdes 4 E 21 V 38 m 55 3 9698937Sdes 5 F 22 W 39 n 56 4 9798937Sdes 6 G 23 X 40 o 57 5 9898937Sdes 7 H 24 Y 41 p 58 6 9998937Sdes 8 I 25 Z 42 q 59 7 10098937Sdes 9 J 26 a 43 r 60 8 10198937Sdes 10 K 27 b 44 s 61 9 10298937Sdes 11 L 28 c 45 t 62 + 10398937Sdes 12 M 29 d 46 u 63 / 10498937Sdes 13 N 30 e 47 v 10598937Sdes 14 O 31 f 48 w (pad) = 10698937Sdes 15 P 32 g 49 x 10798937Sdes 16 Q 33 h 50 y 10898937Sdes 10998937Sdes Special processing is performed if fewer than 24 bits are available 11098937Sdes at the end of the data being encoded. A full encoding quantum is 11198937Sdes always completed at the end of a quantity. When fewer than 24 input 11298937Sdes bits are available in an input group, zero bits are added (on the 11398937Sdes right) to form an integral number of 6-bit groups. Padding at the 11498937Sdes end of the data is performed using the '=' character. 11598937Sdes 11698937Sdes Since all base64 input is an integral number of octets, only the 11798937Sdes ------------------------------------------------- 11898937Sdes following cases can arise: 11998937Sdes 12098937Sdes (1) the final quantum of encoding input is an integral 12198937Sdes multiple of 24 bits; here, the final unit of encoded 12298937Sdes output will be an integral multiple of 4 characters 12398937Sdes with no "=" padding, 12498937Sdes (2) the final quantum of encoding input is exactly 8 bits; 12598937Sdes here, the final unit of encoded output will be two 12698937Sdes characters followed by two "=" padding characters, or 12798937Sdes (3) the final quantum of encoding input is exactly 16 bits; 12898937Sdes here, the final unit of encoded output will be three 12998937Sdes characters followed by one "=" padding character. 13098937Sdes */ 13198937Sdes 132113908Sdes#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) 13398937Sdesint 13498937Sdesb64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) 13598937Sdes{ 13698937Sdes size_t datalength = 0; 13798937Sdes u_char input[3]; 13898937Sdes u_char output[4]; 139157016Sdes u_int i; 14098937Sdes 14198937Sdes while (2 < srclength) { 14298937Sdes input[0] = *src++; 14398937Sdes input[1] = *src++; 14498937Sdes input[2] = *src++; 14598937Sdes srclength -= 3; 14698937Sdes 14798937Sdes output[0] = input[0] >> 2; 14898937Sdes output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 14998937Sdes output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 15098937Sdes output[3] = input[2] & 0x3f; 15198937Sdes 15298937Sdes if (datalength + 4 > targsize) 15398937Sdes return (-1); 15498937Sdes target[datalength++] = Base64[output[0]]; 15598937Sdes target[datalength++] = Base64[output[1]]; 15698937Sdes target[datalength++] = Base64[output[2]]; 15798937Sdes target[datalength++] = Base64[output[3]]; 15898937Sdes } 15998937Sdes 16098937Sdes /* Now we worry about padding. */ 16198937Sdes if (0 != srclength) { 16298937Sdes /* Get what's left. */ 16398937Sdes input[0] = input[1] = input[2] = '\0'; 16498937Sdes for (i = 0; i < srclength; i++) 16598937Sdes input[i] = *src++; 16698937Sdes 16798937Sdes output[0] = input[0] >> 2; 16898937Sdes output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 16998937Sdes output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 17098937Sdes 17198937Sdes if (datalength + 4 > targsize) 17298937Sdes return (-1); 17398937Sdes target[datalength++] = Base64[output[0]]; 17498937Sdes target[datalength++] = Base64[output[1]]; 17598937Sdes if (srclength == 1) 17698937Sdes target[datalength++] = Pad64; 17798937Sdes else 17898937Sdes target[datalength++] = Base64[output[2]]; 17998937Sdes target[datalength++] = Pad64; 18098937Sdes } 18198937Sdes if (datalength >= targsize) 18298937Sdes return (-1); 18398937Sdes target[datalength] = '\0'; /* Returned value doesn't count \0. */ 18498937Sdes return (datalength); 18598937Sdes} 186113908Sdes#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ 18798937Sdes 188113908Sdes#if !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) 189113908Sdes 19098937Sdes/* skips all whitespace anywhere. 19198937Sdes converts characters, four at a time, starting at (or after) 19298937Sdes src from base - 64 numbers into three 8 bit bytes in the target area. 19398937Sdes it returns the number of data bytes stored at the target, or -1 on error. 19498937Sdes */ 19598937Sdes 19698937Sdesint 19798937Sdesb64_pton(char const *src, u_char *target, size_t targsize) 19898937Sdes{ 199157016Sdes u_int tarindex, state; 200157016Sdes int ch; 20198937Sdes char *pos; 20298937Sdes 20398937Sdes state = 0; 20498937Sdes tarindex = 0; 20598937Sdes 20698937Sdes while ((ch = *src++) != '\0') { 20798937Sdes if (isspace(ch)) /* Skip whitespace anywhere. */ 20898937Sdes continue; 20998937Sdes 21098937Sdes if (ch == Pad64) 21198937Sdes break; 21298937Sdes 21398937Sdes pos = strchr(Base64, ch); 21498937Sdes if (pos == 0) /* A non-base64 character. */ 21598937Sdes return (-1); 21698937Sdes 21798937Sdes switch (state) { 21898937Sdes case 0: 21998937Sdes if (target) { 22098937Sdes if (tarindex >= targsize) 22198937Sdes return (-1); 22298937Sdes target[tarindex] = (pos - Base64) << 2; 22398937Sdes } 22498937Sdes state = 1; 22598937Sdes break; 22698937Sdes case 1: 22798937Sdes if (target) { 22898937Sdes if (tarindex + 1 >= targsize) 22998937Sdes return (-1); 23098937Sdes target[tarindex] |= (pos - Base64) >> 4; 23198937Sdes target[tarindex+1] = ((pos - Base64) & 0x0f) 23298937Sdes << 4 ; 23398937Sdes } 23498937Sdes tarindex++; 23598937Sdes state = 2; 23698937Sdes break; 23798937Sdes case 2: 23898937Sdes if (target) { 23998937Sdes if (tarindex + 1 >= targsize) 24098937Sdes return (-1); 24198937Sdes target[tarindex] |= (pos - Base64) >> 2; 24298937Sdes target[tarindex+1] = ((pos - Base64) & 0x03) 24398937Sdes << 6; 24498937Sdes } 24598937Sdes tarindex++; 24698937Sdes state = 3; 24798937Sdes break; 24898937Sdes case 3: 24998937Sdes if (target) { 25098937Sdes if (tarindex >= targsize) 25198937Sdes return (-1); 25298937Sdes target[tarindex] |= (pos - Base64); 25398937Sdes } 25498937Sdes tarindex++; 25598937Sdes state = 0; 25698937Sdes break; 25798937Sdes } 25898937Sdes } 25998937Sdes 26098937Sdes /* 26198937Sdes * We are done decoding Base-64 chars. Let's see if we ended 26298937Sdes * on a byte boundary, and/or with erroneous trailing characters. 26398937Sdes */ 26498937Sdes 26598937Sdes if (ch == Pad64) { /* We got a pad char. */ 26698937Sdes ch = *src++; /* Skip it, get next. */ 26798937Sdes switch (state) { 26898937Sdes case 0: /* Invalid = in first position */ 26998937Sdes case 1: /* Invalid = in second position */ 27098937Sdes return (-1); 27198937Sdes 27298937Sdes case 2: /* Valid, means one byte of info */ 27398937Sdes /* Skip any number of spaces. */ 27498937Sdes for (; ch != '\0'; ch = *src++) 27598937Sdes if (!isspace(ch)) 27698937Sdes break; 27798937Sdes /* Make sure there is another trailing = sign. */ 27898937Sdes if (ch != Pad64) 27998937Sdes return (-1); 28098937Sdes ch = *src++; /* Skip the = */ 28198937Sdes /* Fall through to "single trailing =" case. */ 28298937Sdes /* FALLTHROUGH */ 28398937Sdes 28498937Sdes case 3: /* Valid, means two bytes of info */ 28598937Sdes /* 28698937Sdes * We know this char is an =. Is there anything but 28798937Sdes * whitespace after it? 28898937Sdes */ 28998937Sdes for (; ch != '\0'; ch = *src++) 29098937Sdes if (!isspace(ch)) 29198937Sdes return (-1); 29298937Sdes 29398937Sdes /* 29498937Sdes * Now make sure for cases 2 and 3 that the "extra" 29598937Sdes * bits that slopped past the last full byte were 29698937Sdes * zeros. If we don't check them, they become a 29798937Sdes * subliminal channel. 29898937Sdes */ 29998937Sdes if (target && target[tarindex] != 0) 30098937Sdes return (-1); 30198937Sdes } 30298937Sdes } else { 30398937Sdes /* 30498937Sdes * We ended by seeing the end of the string. Make sure we 30598937Sdes * have no partial bytes lying around. 30698937Sdes */ 30798937Sdes if (state != 0) 30898937Sdes return (-1); 30998937Sdes } 31098937Sdes 31198937Sdes return (tarindex); 31298937Sdes} 31398937Sdes 314113908Sdes#endif /* !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) */ 315113908Sdes#endif 316