~ubuntu-branches/ubuntu/wily/easytag/wily

« back to all changes in this revision

Viewing changes to src/base64.c

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2013-10-11 17:07:47 UTC
  • mto: (8.1.4 sid)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: package-import@ubuntu.com-20131011170747-uqvgtx7uyd046j7z
Tags: upstream-2.1.8
Import upstream version 2.1.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
3
 
 * (Royal Institute of Technology, Stockholm, Sweden).
4
 
 * All rights reserved.
5
 
 *
6
 
 * Redistribution and use in source and binary forms, with or without
7
 
 * modification, are permitted provided that the following conditions
8
 
 * are met:
9
 
 *
10
 
 * 1. Redistributions of source code must retain the above copyright
11
 
 *    notice, this list of conditions and the following disclaimer.
12
 
 *
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.
16
 
 *
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.
20
 
 *
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
31
 
 * SUCH DAMAGE.
32
 
 */
33
 
 
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
37
 
   convenience.
38
 
 
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.)
42
 
 
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.
48
 
 
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
51
 
   output string.
52
 
 
53
 
                         Table 1: The Base64 Alphabet
54
 
 
55
 
      Value Encoding  Value Encoding  Value Encoding  Value Encoding
56
 
          0 A            17 R            34 i            51 z
57
 
          1 B            18 S            35 j            52 0
58
 
          2 C            19 T            36 k            53 1
59
 
          3 D            20 U            37 l            54 2
60
 
          4 E            21 V            38 m            55 3
61
 
          5 F            22 W            39 n            56 4
62
 
          6 G            23 X            40 o            57 5
63
 
          7 H            24 Y            41 p            58 6
64
 
          8 I            25 Z            42 q            59 7
65
 
          9 J            26 a            43 r            60 8
66
 
         10 K            27 b            44 s            61 9
67
 
         11 L            28 c            45 t            62 +
68
 
         12 M            29 d            46 u            63 /
69
 
         13 N            30 e            47 v
70
 
         14 O            31 f            48 w         (pad) =
71
 
         15 P            32 g            49 x
72
 
         16 Q            33 h            50 y
73
 
 
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.
80
 
 
81
 
   Since all base64 input is an integral number of octets, only the
82
 
         -------------------------------------------------
83
 
   following cases can arise:
84
 
 
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
88
 
           with no "=" padding,
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.
95
 
   */
96
 
 
97
 
/* $Id: base64.c,v 1.5 2001/05/28 17:33:41 joda Exp $ */
98
 
 
99
 
/*
100
 
 * Code taken from Kerberos krb4-1.2.2
101
 
 */
102
 
 
103
 
#include <stdlib.h>
104
 
#include <string.h>
105
 
#include "base64.h"
106
 
 
107
 
/* Useful for encoding */
108
 
static char base64_chars[] = 
109
 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
110
 
 
111
 
/* For constant time lookups */
112
 
static int
113
 
is_base64_char(char c)
114
 
{
115
 
    return (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || 
116
 
            ('0' <= c && c <= '9') || (c == '+' || c == '/'));
117
 
}
118
 
 
119
 
static int 
120
 
pos(char c)
121
 
{
122
 
    char *p;
123
 
    for (p = base64_chars; *p; p++)
124
 
        if (*p == c)
125
 
            return p - base64_chars;
126
 
    return -1;
127
 
}
128
 
 
129
 
int 
130
 
base64_encode(const void *data, int size, char **str)
131
 
{
132
 
    char *s, *p;
133
 
    int i;
134
 
    int c;
135
 
    const unsigned char *q;
136
 
 
137
 
    p = s = (char *) malloc(size * 4 / 3 + 4);
138
 
    if (p == NULL)
139
 
        return -1;
140
 
    q = (const unsigned char *) data;
141
 
    i = 0;
142
 
    for (i = 0; i < size;)
143
 
    {
144
 
        c = q[i++];
145
 
        c *= 256;
146
 
        if (i < size)
147
 
            c += q[i];
148
 
        i++;
149
 
        c *= 256;
150
 
        if (i < size)
151
 
            c += q[i];
152
 
        i++;
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];
157
 
        if (i > size)
158
 
            p[3] = '=';
159
 
        if (i > size + 1)
160
 
            p[2] = '=';
161
 
        p += 4;
162
 
    }
163
 
    *p = 0;
164
 
    *str = s;
165
 
    return strlen(s);
166
 
}
167
 
 
168
 
#define DECODE_ERROR ((unsigned) -1)
169
 
 
170
 
static unsigned int
171
 
token_decode(const char *token, const size_t size)
172
 
{
173
 
    int i;
174
 
    unsigned int val = 0;
175
 
    int marker = 0;
176
 
    
177
 
    if (size < 4)
178
 
        return DECODE_ERROR;
179
 
    for (i = 0; i < 4; i++)
180
 
    {
181
 
        val *= 64;
182
 
        if (token[i] == '=')
183
 
            marker++;
184
 
        else if (marker > 0)
185
 
            return DECODE_ERROR;
186
 
        else
187
 
            val += pos(token[i]);
188
 
    }
189
 
    if (marker > 2)
190
 
        return DECODE_ERROR;
191
 
    return (marker << 24) | val;
192
 
}
193
 
 
194
 
int
195
 
base64_decode(const char *str, void *data)
196
 
{
197
 
    const char     *p;
198
 
    unsigned char  *q;
199
 
    unsigned int    size;
200
 
 
201
 
    q = data;
202
 
    size = strlen(str);
203
 
    for (p = str; *p && (*p == '=' || is_base64_char(*p)); p += 4, size -= 4)
204
 
    {
205
 
        unsigned int val = token_decode(p, size);
206
 
        unsigned int marker = (val >> 24) & 0xff;
207
 
        
208
 
        if (val == DECODE_ERROR)
209
 
            return -1;
210
 
        *q++ = (val >> 16) & 0xff;
211
 
        if (marker < 2)
212
 
            *q++ = (val >> 8) & 0xff;
213
 
        if (marker < 1)
214
 
            *q++ = val & 0xff;
215
 
    }
216
 
    return q - (unsigned char *) data;
217
 
}
218