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