2
* Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
17
* 3. Neither the name of the Institute nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
21
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
35
The following encoding technique is taken from RFC 1521 by Borenstein
36
and Freed. It is reproduced here in a slightly edited form for
39
A 65-character subset of US-ASCII is used, enabling 6 bits to be
40
represented per printable character. (The extra 65th character, "=",
41
is used to signify a special processing function.)
43
The encoding process represents 24-bit groups of input bits as output
44
strings of 4 encoded characters. Proceeding from left to right, a
45
24-bit input group is formed by concatenating 3 8-bit input groups.
46
These 24 bits are then treated as 4 concatenated 6-bit groups, each
47
of which is translated into a single digit in the base64 alphabet.
49
Each 6-bit group is used as an index into an array of 64 printable
50
characters. The character referenced by the index is placed in the
53
Table 1: The Base64 Alphabet
55
Value Encoding Value Encoding Value Encoding Value Encoding
70
14 O 31 f 48 w (pad) =
74
Special processing is performed if fewer than 24 bits are available
75
at the end of the data being encoded. A full encoding quantum is
76
always completed at the end of a quantity. When fewer than 24 input
77
bits are available in an input group, zero bits are added (on the
78
right) to form an integral number of 6-bit groups. Padding at the
79
end of the data is performed using the '=' character.
81
Since all base64 input is an integral number of octets, only the
82
-------------------------------------------------
83
following cases can arise:
85
(1) the final quantum of encoding input is an integral
86
multiple of 24 bits; here, the final unit of encoded
87
output will be an integral multiple of 4 characters
89
(2) the final quantum of encoding input is exactly 8 bits;
90
here, the final unit of encoded output will be two
91
characters followed by two "=" padding characters, or
92
(3) the final quantum of encoding input is exactly 16 bits;
93
here, the final unit of encoded output will be three
94
characters followed by one "=" padding character.
97
/* $Id: base64.c,v 1.5 2001/05/28 17:33:41 joda Exp $ */
100
* Code taken from Kerberos krb4-1.2.2
107
/* Useful for encoding */
108
static char base64_chars[] =
109
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
111
/* For constant time lookups */
113
is_base64_char(char c)
115
return (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') ||
116
('0' <= c && c <= '9') || (c == '+' || c == '/'));
123
for (p = base64_chars; *p; p++)
125
return p - base64_chars;
130
base64_encode(const void *data, int size, char **str)
135
const unsigned char *q;
137
p = s = (char *) malloc(size * 4 / 3 + 4);
140
q = (const unsigned char *) data;
142
for (i = 0; i < size;)
153
p[0] = base64_chars[(c & 0x00fc0000) >> 18];
154
p[1] = base64_chars[(c & 0x0003f000) >> 12];
155
p[2] = base64_chars[(c & 0x00000fc0) >> 6];
156
p[3] = base64_chars[(c & 0x0000003f) >> 0];
168
#define DECODE_ERROR ((unsigned) -1)
171
token_decode(const char *token, const size_t size)
174
unsigned int val = 0;
179
for (i = 0; i < 4; i++)
187
val += pos(token[i]);
191
return (marker << 24) | val;
195
base64_decode(const char *str, void *data)
203
for (p = str; *p && (*p == '=' || is_base64_char(*p)); p += 4, size -= 4)
205
unsigned int val = token_decode(p, size);
206
unsigned int marker = (val >> 24) & 0xff;
208
if (val == DECODE_ERROR)
210
*q++ = (val >> 16) & 0xff;
212
*q++ = (val >> 8) & 0xff;
216
return q - (unsigned char *) data;