121057Speter/*
236891Speter * Copyright (c) 1996, 1998 by Internet Software Consortium.
321057Speter *
421057Speter * Permission to use, copy, modify, and distribute this software for any
521057Speter * purpose with or without fee is hereby granted, provided that the above
621057Speter * copyright notice and this permission notice appear in all copies.
721057Speter *
821057Speter * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
921057Speter * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
1021057Speter * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
1121057Speter * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
1221057Speter * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
1321057Speter * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
1421057Speter * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
1521057Speter * SOFTWARE.
1621057Speter */
1721057Speter
1821057Speter/*
1921057Speter * Portions Copyright (c) 1995 by International Business Machines, Inc.
2021057Speter *
2121057Speter * International Business Machines, Inc. (hereinafter called IBM) grants
2221057Speter * permission under its copyrights to use, copy, modify, and distribute this
2321057Speter * Software with or without fee, provided that the above copyright notice and
2421057Speter * all paragraphs of this notice appear in all copies, and that the name of IBM
2521057Speter * not be used in connection with the marketing of any product incorporating
2621057Speter * the Software or modifications thereof, without specific, written prior
2721057Speter * permission.
2821057Speter *
2921057Speter * To the extent it has a right to do so, IBM grants an immunity from suit
3021057Speter * under its patents, if any, for the use, sale or manufacture of products to
3121057Speter * the extent that such products are used for performing Domain Name System
3221057Speter * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
3321057Speter * granted for any product per se or for any other function of any product.
3421057Speter *
3521057Speter * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
3621057Speter * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
3721057Speter * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
3821057Speter * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
3921057Speter * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
4021057Speter * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
4121057Speter */
4221057Speter
4392986Sobrien#include <sys/cdefs.h>
4492986Sobrien__FBSDID("$FreeBSD: stable/10/lib/libc/net/base64.c 309485 2016-12-03 17:17:42Z ngie $");
4536891Speter
4621057Speter#include <sys/types.h>
4721057Speter#include <sys/param.h>
4821057Speter#include <sys/socket.h>
4936891Speter
5021057Speter#include <netinet/in.h>
5121057Speter#include <arpa/inet.h>
5221057Speter#include <arpa/nameser.h>
5321057Speter
5421057Speter#include <ctype.h>
5521057Speter#include <resolv.h>
5621057Speter#include <stdio.h>
5736891Speter#include <stdlib.h>
5836891Speter#include <string.h>
5921057Speter
6021057Speter#define Assert(Cond) if (!(Cond)) abort()
6121057Speter
6221057Speterstatic const char Base64[] =
6321057Speter	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
6421057Speterstatic const char Pad64 = '=';
6521057Speter
6621057Speter/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
6721057Speter   The following encoding technique is taken from RFC 1521 by Borenstein
6821057Speter   and Freed.  It is reproduced here in a slightly edited form for
6921057Speter   convenience.
7021057Speter
7121057Speter   A 65-character subset of US-ASCII is used, enabling 6 bits to be
7221057Speter   represented per printable character. (The extra 65th character, "=",
7321057Speter   is used to signify a special processing function.)
7421057Speter
7521057Speter   The encoding process represents 24-bit groups of input bits as output
7621057Speter   strings of 4 encoded characters. Proceeding from left to right, a
7721057Speter   24-bit input group is formed by concatenating 3 8-bit input groups.
7821057Speter   These 24 bits are then treated as 4 concatenated 6-bit groups, each
7921057Speter   of which is translated into a single digit in the base64 alphabet.
8021057Speter
8121057Speter   Each 6-bit group is used as an index into an array of 64 printable
8221057Speter   characters. The character referenced by the index is placed in the
8321057Speter   output string.
8421057Speter
8521057Speter                         Table 1: The Base64 Alphabet
8621057Speter
8721057Speter      Value Encoding  Value Encoding  Value Encoding  Value Encoding
8821057Speter          0 A            17 R            34 i            51 z
8921057Speter          1 B            18 S            35 j            52 0
9021057Speter          2 C            19 T            36 k            53 1
9121057Speter          3 D            20 U            37 l            54 2
9221057Speter          4 E            21 V            38 m            55 3
9321057Speter          5 F            22 W            39 n            56 4
9421057Speter          6 G            23 X            40 o            57 5
9521057Speter          7 H            24 Y            41 p            58 6
9621057Speter          8 I            25 Z            42 q            59 7
9721057Speter          9 J            26 a            43 r            60 8
9821057Speter         10 K            27 b            44 s            61 9
9921057Speter         11 L            28 c            45 t            62 +
10021057Speter         12 M            29 d            46 u            63 /
10121057Speter         13 N            30 e            47 v
10221057Speter         14 O            31 f            48 w         (pad) =
10321057Speter         15 P            32 g            49 x
10421057Speter         16 Q            33 h            50 y
10521057Speter
10621057Speter   Special processing is performed if fewer than 24 bits are available
10721057Speter   at the end of the data being encoded.  A full encoding quantum is
10821057Speter   always completed at the end of a quantity.  When fewer than 24 input
10921057Speter   bits are available in an input group, zero bits are added (on the
11021057Speter   right) to form an integral number of 6-bit groups.  Padding at the
11121057Speter   end of the data is performed using the '=' character.
11221057Speter
11321057Speter   Since all base64 input is an integral number of octets, only the
11421057Speter         -------------------------------------------------
11521057Speter   following cases can arise:
11621057Speter
11721057Speter       (1) the final quantum of encoding input is an integral
11821057Speter           multiple of 24 bits; here, the final unit of encoded
11921057Speter	   output will be an integral multiple of 4 characters
12021057Speter	   with no "=" padding,
12121057Speter       (2) the final quantum of encoding input is exactly 8 bits;
12221057Speter           here, the final unit of encoded output will be two
12321057Speter	   characters followed by two "=" padding characters, or
12421057Speter       (3) the final quantum of encoding input is exactly 16 bits;
12521057Speter           here, the final unit of encoded output will be three
12621057Speter	   characters followed by one "=" padding character.
12721057Speter   */
12821057Speter
12921057Speterint
13036891Speterb64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
13121057Speter	size_t datalength = 0;
13221057Speter	u_char input[3];
13321057Speter	u_char output[4];
13436891Speter	size_t i;
13521057Speter
13621057Speter	while (2 < srclength) {
13721057Speter		input[0] = *src++;
13821057Speter		input[1] = *src++;
13921057Speter		input[2] = *src++;
14021057Speter		srclength -= 3;
14121057Speter
14221057Speter		output[0] = input[0] >> 2;
14321057Speter		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
14421057Speter		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
14521057Speter		output[3] = input[2] & 0x3f;
14621057Speter		Assert(output[0] < 64);
14721057Speter		Assert(output[1] < 64);
14821057Speter		Assert(output[2] < 64);
14921057Speter		Assert(output[3] < 64);
15021057Speter
15121057Speter		if (datalength + 4 > targsize)
15221057Speter			return (-1);
15321057Speter		target[datalength++] = Base64[output[0]];
15421057Speter		target[datalength++] = Base64[output[1]];
15521057Speter		target[datalength++] = Base64[output[2]];
15621057Speter		target[datalength++] = Base64[output[3]];
15721057Speter	}
15821057Speter
15921057Speter	/* Now we worry about padding. */
16021057Speter	if (0 != srclength) {
16121057Speter		/* Get what's left. */
16221057Speter		input[0] = input[1] = input[2] = '\0';
16321057Speter		for (i = 0; i < srclength; i++)
16421057Speter			input[i] = *src++;
16521057Speter
16621057Speter		output[0] = input[0] >> 2;
16721057Speter		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
16821057Speter		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
16921057Speter		Assert(output[0] < 64);
17021057Speter		Assert(output[1] < 64);
17121057Speter		Assert(output[2] < 64);
17221057Speter
17321057Speter		if (datalength + 4 > targsize)
17421057Speter			return (-1);
17521057Speter		target[datalength++] = Base64[output[0]];
17621057Speter		target[datalength++] = Base64[output[1]];
17721057Speter		if (srclength == 1)
17821057Speter			target[datalength++] = Pad64;
17921057Speter		else
18021057Speter			target[datalength++] = Base64[output[2]];
18121057Speter		target[datalength++] = Pad64;
18221057Speter	}
18321057Speter	if (datalength >= targsize)
18421057Speter		return (-1);
18521057Speter	target[datalength] = '\0';	/* Returned value doesn't count \0. */
18621057Speter	return (datalength);
18721057Speter}
18821057Speter
18921057Speter/* skips all whitespace anywhere.
19021057Speter   converts characters, four at a time, starting at (or after)
19121057Speter   src from base - 64 numbers into three 8 bit bytes in the target area.
19221057Speter   it returns the number of data bytes stored at the target, or -1 on error.
19321057Speter */
19421057Speter
19521057Speterint
196280399Semasteb64_pton(const char *src, u_char *target, size_t targsize)
19721057Speter{
19821057Speter	int tarindex, state, ch;
199280398Semaste	u_char nextbyte;
20021057Speter	char *pos;
20121057Speter
20221057Speter	state = 0;
20321057Speter	tarindex = 0;
20421057Speter
20521057Speter	while ((ch = *src++) != '\0') {
20652858Sache		if (isspace((unsigned char)ch))        /* Skip whitespace anywhere. */
20721057Speter			continue;
20821057Speter
20921057Speter		if (ch == Pad64)
21021057Speter			break;
21121057Speter
21221057Speter		pos = strchr(Base64, ch);
213309485Sngie		if (pos == NULL)		/* A non-base64 character. */
21421057Speter			return (-1);
21521057Speter
21621057Speter		switch (state) {
21721057Speter		case 0:
21821057Speter			if (target) {
21936891Speter				if ((size_t)tarindex >= targsize)
22021057Speter					return (-1);
22121057Speter				target[tarindex] = (pos - Base64) << 2;
22221057Speter			}
22321057Speter			state = 1;
22421057Speter			break;
22521057Speter		case 1:
22621057Speter			if (target) {
227280398Semaste				if ((size_t)tarindex >= targsize)
22821057Speter					return (-1);
22921057Speter				target[tarindex]   |=  (pos - Base64) >> 4;
230280398Semaste				nextbyte = ((pos - Base64) & 0x0f) << 4;
231280398Semaste				if ((size_t)tarindex + 1 < targsize)
232280398Semaste					target[tarindex + 1] = nextbyte;
233280398Semaste				else if (nextbyte)
234280398Semaste					return (-1);
23521057Speter			}
23621057Speter			tarindex++;
23721057Speter			state = 2;
23821057Speter			break;
23921057Speter		case 2:
24021057Speter			if (target) {
241280398Semaste				if ((size_t)tarindex >= targsize)
24221057Speter					return (-1);
24321057Speter				target[tarindex]   |=  (pos - Base64) >> 2;
244280398Semaste				nextbyte = ((pos - Base64) & 0x03) << 6;
245280398Semaste				if ((size_t)tarindex + 1 < targsize)
246280398Semaste					target[tarindex + 1] = nextbyte;
247280398Semaste				else if (nextbyte)
248280398Semaste					return (-1);
24921057Speter			}
25021057Speter			tarindex++;
25121057Speter			state = 3;
25221057Speter			break;
25321057Speter		case 3:
25421057Speter			if (target) {
25536891Speter				if ((size_t)tarindex >= targsize)
25621057Speter					return (-1);
25721057Speter				target[tarindex] |= (pos - Base64);
25821057Speter			}
25921057Speter			tarindex++;
26021057Speter			state = 0;
26121057Speter			break;
26221057Speter		default:
26321057Speter			abort();
26421057Speter		}
26521057Speter	}
26621057Speter
26721057Speter	/*
26821057Speter	 * We are done decoding Base-64 chars.  Let's see if we ended
26921057Speter	 * on a byte boundary, and/or with erroneous trailing characters.
27021057Speter	 */
27121057Speter
27221057Speter	if (ch == Pad64) {		/* We got a pad char. */
27321057Speter		ch = *src++;		/* Skip it, get next. */
27421057Speter		switch (state) {
27521057Speter		case 0:		/* Invalid = in first position */
27621057Speter		case 1:		/* Invalid = in second position */
27721057Speter			return (-1);
27821057Speter
27921057Speter		case 2:		/* Valid, means one byte of info */
28021057Speter			/* Skip any number of spaces. */
28136891Speter			for ((void)NULL; ch != '\0'; ch = *src++)
28252858Sache				if (!isspace((unsigned char)ch))
28321057Speter					break;
28421057Speter			/* Make sure there is another trailing = sign. */
28521057Speter			if (ch != Pad64)
28621057Speter				return (-1);
28721057Speter			ch = *src++;		/* Skip the = */
28821057Speter			/* Fall through to "single trailing =" case. */
28921057Speter			/* FALLTHROUGH */
29021057Speter
29121057Speter		case 3:		/* Valid, means two bytes of info */
29221057Speter			/*
29321057Speter			 * We know this char is an =.  Is there anything but
29421057Speter			 * whitespace after it?
29521057Speter			 */
29636891Speter			for ((void)NULL; ch != '\0'; ch = *src++)
29752858Sache				if (!isspace((unsigned char)ch))
29821057Speter					return (-1);
29921057Speter
30021057Speter			/*
30121057Speter			 * Now make sure for cases 2 and 3 that the "extra"
30221057Speter			 * bits that slopped past the last full byte were
30321057Speter			 * zeros.  If we don't check them, they become a
30421057Speter			 * subliminal channel.
30521057Speter			 */
306280398Semaste			if (target && (size_t)tarindex < targsize &&
307280398Semaste			    target[tarindex] != 0)
30821057Speter				return (-1);
30921057Speter		}
31021057Speter	} else {
31121057Speter		/*
31221057Speter		 * We ended by seeing the end of the string.  Make sure we
31321057Speter		 * have no partial bytes lying around.
31421057Speter		 */
31521057Speter		if (state != 0)
31621057Speter			return (-1);
31721057Speter	}
31821057Speter
31921057Speter	return (tarindex);
32021057Speter}
321