Apache HTTPD
apr_base64.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* base64 encoder/decoder. Originally part of main/util.c
18 * but moved here so that support/ab and apr_sha1.c could
19 * use it. This meant removing the apr_palloc()s and adding
20 * ugly 'len' functions, which is quite a nasty cost.
21 */
22
23#undef NDEBUG /* always abort() on assert()ion failure */
24#include <assert.h>
25
26#include "apr_base64.h"
27#if APR_CHARSET_EBCDIC
28#include "apr_xlate.h"
29#endif /* APR_CHARSET_EBCDIC */
30
31/* Above APR_BASE64_ENCODE_MAX length the encoding can't fit in an int >= 0 */
32#define APR_BASE64_ENCODE_MAX 1610612733
33
34/* Above APR_BASE64_DECODE_MAX length the decoding can't fit in an int >= 0 */
35#define APR_BASE64_DECODE_MAX 2863311524u
36
37/* aaaack but it's fast and const should make it shared text page. */
38static const unsigned char pr2six[256] =
39{
40#if !APR_CHARSET_EBCDIC
41 /* ASCII table */
42 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
43 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
44 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
45 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
46 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
47 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
48 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
49 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
50 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
51 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
52 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
53 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
54 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
55 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
56 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
57 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
58#else /*APR_CHARSET_EBCDIC*/
59 /* EBCDIC table */
60 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
61 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
62 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
63 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64,
65 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
66 64, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
67 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
68 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64,
69 64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64,
70 64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64,
71 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
72 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 64, 64, 64, 64, 64, 64,
73 64, 9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64,
74 64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64,
75 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64
76#endif /*APR_CHARSET_EBCDIC*/
77};
78
79#if APR_CHARSET_EBCDIC
81static unsigned char os_toascii[256];
82
85{
86 int i;
88 apr_status_t rv;
89 int onoff;
90
91 /* Only single-byte conversion is supported.
92 */
94 if (rv) {
95 return rv;
96 }
97 if (!onoff) { /* If conversion is not single-byte-only */
98 return APR_EINVAL;
99 }
101 if (rv) {
102 return rv;
103 }
104 if (!onoff) { /* If conversion is not single-byte-only */
105 return APR_EINVAL;
106 }
108 for (i = 0; i < sizeof(os_toascii); i++) {
109 os_toascii[i] = i;
110 }
114
115 return APR_SUCCESS;
116}
117#endif /*APR_CHARSET_EBCDIC*/
118
120{
121 register const unsigned char *bufin;
122 register apr_size_t nprbytes;
123
124 bufin = (const unsigned char *) bufcoded;
125 while (pr2six[*(bufin++)] <= 63);
126 nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
128
129 return (int)(((nprbytes + 3u) / 4u) * 3u + 1u);
130}
131
132APU_DECLARE(int) apr_base64_decode(char *bufplain, const char *bufcoded)
133{
134#if APR_CHARSET_EBCDIC
136#endif /* APR_CHARSET_EBCDIC */
137 int len;
138
139 len = apr_base64_decode_binary((unsigned char *) bufplain, bufcoded);
140#if APR_CHARSET_EBCDIC
144#endif /* APR_CHARSET_EBCDIC */
145 bufplain[len] = '\0';
146 return len;
147}
148
149/* This is the same as apr_base64_decode() except on EBCDIC machines, where
150 * the conversion of the output to ebcdic is left out.
151 */
153 const char *bufcoded)
154{
155 int nbytesdecoded;
156 register const unsigned char *bufin;
157 register unsigned char *bufout;
158 register apr_size_t nprbytes;
159
160 bufin = (const unsigned char *) bufcoded;
161 while (pr2six[*(bufin++)] <= 63);
162 nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
164 nbytesdecoded = (int)(((nprbytes + 3u) / 4u) * 3u);
165
166 bufout = (unsigned char *) bufplain;
167 bufin = (const unsigned char *) bufcoded;
168
169 while (nprbytes >= 4) {
170 *(bufout++) =
171 (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
172 *(bufout++) =
173 (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
174 *(bufout++) =
175 (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
176 bufin += 4;
177 nprbytes -= 4;
178 }
179
180 /* Note: (nprbytes == 1) would be an error, so just ignore that case */
181 if (nprbytes > 1) {
182 *(bufout++) =
183 (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
184 }
185 if (nprbytes > 2) {
186 *(bufout++) =
187 (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
188 }
189
190 return nbytesdecoded - (int)((4u - nprbytes) & 3u);
191}
192
193static const char basis_64[] =
194 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
195
197{
199
200 return ((len + 2) / 3 * 4) + 1;
201}
202
203APU_DECLARE(int) apr_base64_encode(char *encoded, const char *string, int len)
204{
205#if !APR_CHARSET_EBCDIC
206 return apr_base64_encode_binary(encoded, (const unsigned char *) string, len);
207#else /* APR_CHARSET_EBCDIC */
208 int i;
209 char *p;
210
212
213 p = encoded;
214 for (i = 0; i < len - 2; i += 3) {
215 *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
216 *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
217 ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
218 *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) |
219 ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)];
220 *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F];
221 }
222 if (i < len) {
223 *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
224 if (i == (len - 1)) {
225 *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4)];
226 *p++ = '=';
227 }
228 else {
229 *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
230 ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
231 *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)];
232 }
233 *p++ = '=';
234 }
235
236 *p++ = '\0';
237 return (unsigned int)(p - encoded);
238#endif /* APR_CHARSET_EBCDIC */
239}
240
241/* This is the same as apr_base64_encode() except on EBCDIC machines, where
242 * the conversion of the input to ascii is left out.
243 */
244APU_DECLARE(int) apr_base64_encode_binary(char *encoded,
245 const unsigned char *string, int len)
246{
247 int i;
248 char *p;
249
251
252 p = encoded;
253 for (i = 0; i < len - 2; i += 3) {
254 *p++ = basis_64[(string[i] >> 2) & 0x3F];
255 *p++ = basis_64[((string[i] & 0x3) << 4) |
256 ((int) (string[i + 1] & 0xF0) >> 4)];
257 *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
258 ((int) (string[i + 2] & 0xC0) >> 6)];
259 *p++ = basis_64[string[i + 2] & 0x3F];
260 }
261 if (i < len) {
262 *p++ = basis_64[(string[i] >> 2) & 0x3F];
263 if (i == (len - 1)) {
264 *p++ = basis_64[((string[i] & 0x3) << 4)];
265 *p++ = '=';
266 }
267 else {
268 *p++ = basis_64[((string[i] & 0x3) << 4) |
269 ((int) (string[i + 1] & 0xF0) >> 4)];
270 *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
271 }
272 *p++ = '=';
273 }
274
275 *p++ = '\0';
276 return (unsigned int)(p - encoded);
277}
const char apr_size_t len
Definition ap_regex.h:187
static const char basis_64[]
Definition apr_base64.c:193
#define APR_BASE64_ENCODE_MAX
Definition apr_base64.c:32
#define APR_BASE64_DECODE_MAX
Definition apr_base64.c:35
static const unsigned char pr2six[256]
Definition apr_base64.c:38
APR-UTIL Base64 Encoding.
APU_DECLARE(void)
Computes SipHash-2-4, producing a 64bit (APR_SIPHASH_DSIZE) hash from a message and a 128bit (APR_SIP...
Definition apr_sha1.c:206
APR I18N translation library.
#define APR_EINVAL
Definition apr_errno.h:711
struct apr_xlate_t apr_xlate_t
Definition apr_xlate.h:39
const char apr_size_t * inbytes_left
Definition apr_xlate.h:119
const char apr_size_t char apr_size_t * outbytes_left
Definition apr_xlate.h:121
int * onoff
Definition apr_xlate.h:93
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_pool_t * p
Definition md_event.c:32
int i
Definition mod_so.c:347
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray