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 /* encode/decode functions.
18 *
19 * These functions perform various encoding operations, and are provided in
20 * pairs, a function to query the length of and encode existing buffers, as
21 * well as companion functions to perform the same process to memory
22 * allocated from a pool.
23 *
24 * The API is designed to have the smallest possible RAM footprint, and so
25 * will only allocate the exact amount of RAM needed for each conversion.
26 */
27
28 #include "apr_encode.h"
29 #include "apr_lib.h"
30 #include "apr_strings.h"
31 #include "apr_encode_private.h"
32
33 /* lookup table: fast and const should make it shared text page. */
34 static const unsigned char pr2six[256] =
35 {
36 #if !APR_CHARSET_EBCDIC
37 /* ASCII table */
38 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
39 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
40 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 62, 64, 63,
41 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 128, 64, 64,
42 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
43 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 63,
44 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
45 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
46 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
47 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
48 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
49 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 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 #else /* APR_CHARSET_EBCDIC */
55 /* EBCDIC table */
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 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
59 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
60 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64,
61 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
62 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, 64, 64,
63 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 64,
64 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64,
65 64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64,
66 64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 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, 0, 1, 2, 3, 4, 5, 6, 7, 8, 64, 64, 64, 64, 64, 64,
69 64, 9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64,
70 64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64,
71 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64
72 #endif /* APR_CHARSET_EBCDIC */
73 };
74
75 static const unsigned char pr2five[256] =
76 {
77 #if !APR_CHARSET_EBCDIC
78 /* ASCII table */
79 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
80 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
81 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
82 32, 32, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 128, 32, 32,
83 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
84 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32, 32, 32, 32, 32,
85 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
86 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
87 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
88 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
89 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
90 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
91 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
92 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
93 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
94 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
95 #else /* APR_CHARSET_EBCDIC */
96 /* EBCDIC table */
97 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
98 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
99 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
100 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
101 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
102 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
103 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
104 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 128, 32,
105 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
106 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
107 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
108 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
109 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 32, 32, 32, 32, 32, 32,
110 32, 9, 10, 11, 12, 13, 14, 15, 16, 17, 32, 32, 32, 32, 32, 32,
111 32, 32, 18, 19, 20, 21, 22, 23, 24, 25, 32, 32, 32, 32, 32, 32,
112 32, 32, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32
113 #endif /* APR_CHARSET_EBCDIC */
114 };
115
116 static const unsigned char pr2fivehex[256] =
117 {
118 #if !APR_CHARSET_EBCDIC
119 /* ASCII table */
120 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
121 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
122 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
123 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 32, 32, 32, 128, 32, 32,
124 32, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
125 25, 26, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
126 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
127 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
128 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
129 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
130 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
131 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
132 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
133 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
134 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
135 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
136 #else /* APR_CHARSET_EBCDIC */
137 /* EBCDIC table */
138 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
139 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
140 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
141 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
142 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
143 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
144 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
145 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 128, 32,
146 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
147 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
148 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
149 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
150 32, 10, 11, 12, 13, 14, 15, 16, 17, 18, 32, 32, 32, 32, 32, 32,
151 32, 19, 20, 21, 22, 23, 24, 25, 26, 27, 32, 32, 32, 32, 32, 32,
152 32, 32, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
153 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 32, 32, 32, 32, 32, 32
154 #endif /* APR_CHARSET_EBCDIC */
155 };
156
157 static const unsigned char pr2two[256] =
158 {
159 #if !APR_CHARSET_EBCDIC
160 /* ASCII table */
161 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
162 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
163 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
164 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 32, 16, 16, 16, 16, 16,
165 16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
166 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
167 16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
168 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
169 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
170 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
171 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
172 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
173 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
174 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
175 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
176 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
177 #else /* APR_CHARSET_EBCDIC */
178 /* EBCDIC table */
179 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
180 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
181 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
182 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
183 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
184 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
185 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
186 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 32, 16, 16, 16, 16, 16,
187 16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
188 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
189 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
190 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
191 16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
192 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
193 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
194 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 16, 16, 16, 16, 16
195 #endif /* APR_CHARSET_EBCDIC */
196 };
197
198 static const char base64[] =
199 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
200 static const char base64url[] =
201 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
202
203 static const char base32[] =
204 "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
205 static const char base32hex[] =
206 "0123456789ABCDEFGHIJKLMNOPQRSTUV";
207
208 static const char base16[] = "0123456789ABCDEF";
209 static const char base16lower[] = "0123456789abcdef";
210
apr_encode_base64(char * dest,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)211 APR_DECLARE(apr_status_t) apr_encode_base64(char *dest, const char *src,
212 apr_ssize_t slen, int flags, apr_size_t * len)
213 {
214 const char *base;
215
216 if (!src) {
217 return APR_NOTFOUND;
218 }
219
220 if (APR_ENCODE_STRING == slen) {
221 slen = strlen(src);
222 }
223
224 if (dest) {
225 register char *bufout = dest;
226 int i;
227
228 if (0 == ((flags & APR_ENCODE_BASE64URL))) {
229 base = base64;
230 }
231 else {
232 base = base64url;
233 }
234
235 for (i = 0; i < slen - 2; i += 3) {
236 *bufout++ = base[ENCODE_TO_ASCII(((src[i]) >> 2) & 0x3F)];
237 *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4)
238 | ((int)((src[i + 1]) & 0xF0) >> 4))];
239 *bufout++ = base[ENCODE_TO_ASCII((((src[i + 1]) & 0xF) << 2)
240 | ((int)(ENCODE_TO_ASCII(src[i + 2]) & 0xC0) >> 6))];
241 *bufout++ = base[ENCODE_TO_ASCII((src[i + 2]) & 0x3F)];
242 }
243 if (i < slen) {
244 *bufout++ = base[ENCODE_TO_ASCII(((src[i]) >> 2) & 0x3F)];
245 if (i == (slen - 1)) {
246 *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4))];
247 if (!(flags & APR_ENCODE_NOPADDING)) {
248 *bufout++ = '=';
249 }
250 }
251 else {
252 *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4)
253 | ((int)((src[i + 1]) & 0xF0) >> 4))];
254 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1]) & 0xF) << 2)];
255 }
256 if (!(flags & APR_ENCODE_NOPADDING)) {
257 *bufout++ = '=';
258 }
259 }
260
261 if (len) {
262 *len = bufout - dest;
263 }
264
265 *bufout++ = '\0';
266
267 return APR_SUCCESS;
268 }
269
270 if (len) {
271 *len = ((slen + 2) / 3 * 4) + 1;
272 }
273
274 return APR_SUCCESS;
275 }
276
apr_encode_base64_binary(char * dest,const unsigned char * src,apr_ssize_t slen,int flags,apr_size_t * len)277 APR_DECLARE(apr_status_t) apr_encode_base64_binary(char *dest, const unsigned char *src,
278 apr_ssize_t slen, int flags, apr_size_t * len)
279 {
280 const char *base;
281
282 if (!src) {
283 return APR_NOTFOUND;
284 }
285
286 if (dest) {
287 register char *bufout = dest;
288 int i;
289
290 if (0 == ((flags & APR_ENCODE_BASE64URL))) {
291 base = base64;
292 }
293 else {
294 base = base64url;
295 }
296
297 for (i = 0; i < slen - 2; i += 3) {
298 *bufout++ = base[(src[i] >> 2) & 0x3F];
299 *bufout++ = base[((src[i] & 0x3) << 4)
300 | ((int)(src[i + 1] & 0xF0) >> 4)];
301 *bufout++ = base[((src[i + 1] & 0xF) << 2)
302 | ((int)(src[i + 2] & 0xC0) >> 6)];
303 *bufout++ = base[src[i + 2] & 0x3F];
304 }
305 if (i < slen) {
306 *bufout++ = base[(src[i] >> 2) & 0x3F];
307 if (i == (slen - 1)) {
308 *bufout++ = base[((src[i] & 0x3) << 4)];
309 if (!(flags & APR_ENCODE_NOPADDING)) {
310 *bufout++ = '=';
311 }
312 }
313 else {
314 *bufout++ = base[((src[i] & 0x3) << 4)
315 | ((int)(src[i + 1] & 0xF0) >> 4)];
316 *bufout++ = base[((src[i + 1] & 0xF) << 2)];
317 }
318 if (!(flags & APR_ENCODE_NOPADDING)) {
319 *bufout++ = '=';
320 }
321 }
322
323 if (len) {
324 *len = bufout - dest;
325 }
326
327 *bufout++ = '\0';
328
329 return APR_SUCCESS;
330 }
331
332 if (len) {
333 *len = ((slen + 2) / 3 * 4) + 1;
334 }
335
336 return APR_SUCCESS;
337 }
338
apr_pencode_base64(apr_pool_t * p,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)339 APR_DECLARE(const char *)apr_pencode_base64(apr_pool_t * p, const char *src,
340 apr_ssize_t slen, int flags, apr_size_t * len)
341 {
342 apr_size_t size;
343
344 switch (apr_encode_base64(NULL, src, slen, flags, &size)) {
345 case APR_SUCCESS:{
346 char *cmd = apr_palloc(p, size);
347 apr_encode_base64(cmd, src, slen, flags, len);
348 return cmd;
349 }
350 case APR_NOTFOUND:{
351 break;
352 }
353 }
354
355 return NULL;
356 }
357
apr_pencode_base64_binary(apr_pool_t * p,const unsigned char * src,apr_ssize_t slen,int flags,apr_size_t * len)358 APR_DECLARE(const char *)apr_pencode_base64_binary(apr_pool_t * p, const unsigned char *src,
359 apr_ssize_t slen, int flags, apr_size_t * len)
360 {
361 apr_size_t size;
362
363 switch (apr_encode_base64_binary(NULL, src, slen, flags, &size)) {
364 case APR_SUCCESS:{
365 char *cmd = apr_palloc(p, size);
366 apr_encode_base64_binary(cmd, src, slen, flags, len);
367 return cmd;
368 }
369 case APR_NOTFOUND:{
370 break;
371 }
372 }
373
374 return NULL;
375 }
376
apr_decode_base64(char * dest,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)377 APR_DECLARE(apr_status_t) apr_decode_base64(char *dest, const char *src,
378 apr_ssize_t slen, int flags, apr_size_t * len)
379 {
380 if (!src) {
381 return APR_NOTFOUND;
382 }
383
384 if (APR_ENCODE_STRING == slen) {
385 slen = strlen(src);
386 }
387
388 if (dest) {
389 register const unsigned char *bufin;
390 register unsigned char *bufout;
391 register apr_size_t nprbytes;
392 register apr_size_t count = slen;
393
394 apr_status_t status;
395
396 bufin = (const unsigned char *)src;
397 while (pr2six[*(bufin++)] < 64 && count)
398 count--;
399 nprbytes = (bufin - (const unsigned char *)src) - 1;
400 while (pr2six[*(bufin++)] > 64 && count)
401 count--;
402
403 status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
404 count ? APR_BADCH : APR_SUCCESS;
405
406 bufout = (unsigned char *)dest;
407 bufin = (const unsigned char *)src;
408
409 while (nprbytes > 4) {
410 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2six[bufin[0]] << 2
411 | pr2six[bufin[1]] >> 4);
412 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
413 pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
414 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
415 pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
416 bufin += 4;
417 nprbytes -= 4;
418 }
419
420 if (nprbytes == 1) {
421 status = APR_BADCH;
422 }
423 if (nprbytes > 1) {
424 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
425 pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
426 }
427 if (nprbytes > 2) {
428 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
429 pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
430 }
431 if (nprbytes > 3) {
432 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
433 pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
434 }
435
436 if (len) {
437 *len = bufout - (unsigned char *)dest;
438 }
439
440 *(bufout++) = 0;
441
442 return status;
443 }
444
445 if (len) {
446 *len = (((int)slen + 3) / 4) * 3 + 1;
447 }
448
449 return APR_SUCCESS;
450 }
451
apr_decode_base64_binary(unsigned char * dest,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)452 APR_DECLARE(apr_status_t) apr_decode_base64_binary(unsigned char *dest,
453 const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
454 {
455 if (!src) {
456 return APR_NOTFOUND;
457 }
458
459 if (APR_ENCODE_STRING == slen) {
460 slen = strlen(src);
461 }
462
463 if (dest) {
464 register const unsigned char *bufin;
465 register unsigned char *bufout;
466 register apr_size_t nprbytes;
467 register apr_size_t count = slen;
468
469 apr_status_t status;
470
471 bufin = (const unsigned char *)src;
472 while (pr2six[*(bufin++)] < 64 && count)
473 count--;
474 nprbytes = (bufin - (const unsigned char *)src) - 1;
475 while (pr2six[*(bufin++)] > 64 && count)
476 count--;
477
478 status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
479 count ? APR_BADCH : APR_SUCCESS;
480
481 bufout = (unsigned char *)dest;
482 bufin = (const unsigned char *)src;
483
484 while (nprbytes > 4) {
485 *(bufout++) = (unsigned char)(pr2six[bufin[0]] << 2
486 | pr2six[bufin[1]] >> 4);
487 *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4
488 | pr2six[bufin[2]] >> 2);
489 *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6
490 | pr2six[bufin[3]]);
491 bufin += 4;
492 nprbytes -= 4;
493 }
494
495 if (nprbytes == 1) {
496 status = APR_BADCH;
497 }
498 if (nprbytes > 1) {
499 *(bufout++) = (unsigned char)(pr2six[bufin[0]] << 2
500 | pr2six[bufin[1]] >> 4);
501 }
502 if (nprbytes > 2) {
503 *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4
504 | pr2six[bufin[2]] >> 2);
505 }
506 if (nprbytes > 3) {
507 *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6
508 | pr2six[bufin[3]]);
509 }
510
511 if (len) {
512 *len = bufout - dest;
513 }
514
515 return status;
516 }
517
518 if (len) {
519 *len = (((int)slen + 3) / 4) * 3;
520 }
521
522 return APR_SUCCESS;
523 }
524
apr_pdecode_base64(apr_pool_t * p,const char * str,apr_ssize_t slen,int flags,apr_size_t * len)525 APR_DECLARE(const char *)apr_pdecode_base64(apr_pool_t * p, const char *str,
526 apr_ssize_t slen, int flags, apr_size_t * len)
527 {
528 apr_size_t size;
529
530 switch (apr_decode_base64(NULL, str, slen, flags, &size)) {
531 case APR_SUCCESS:{
532 void *cmd = apr_palloc(p, size);
533 apr_decode_base64(cmd, str, slen, flags, len);
534 return cmd;
535 }
536 case APR_BADCH:
537 case APR_NOTFOUND:{
538 break;
539 }
540 }
541
542 return NULL;
543 }
544
apr_pdecode_base64_binary(apr_pool_t * p,const char * str,apr_ssize_t slen,int flags,apr_size_t * len)545 APR_DECLARE(const unsigned char *)apr_pdecode_base64_binary(apr_pool_t * p,
546 const char *str, apr_ssize_t slen, int flags, apr_size_t * len)
547 {
548 apr_size_t size;
549
550 switch (apr_decode_base64_binary(NULL, str, slen, flags, &size)) {
551 case APR_SUCCESS:{
552 unsigned char *cmd = apr_palloc(p, size + 1);
553 cmd[size] = 0;
554 apr_decode_base64_binary(cmd, str, slen, flags, len);
555 return cmd;
556 }
557 case APR_BADCH:
558 case APR_NOTFOUND:{
559 break;
560 }
561 }
562
563 return NULL;
564 }
565
apr_encode_base32(char * dest,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)566 APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src,
567 apr_ssize_t slen, int flags, apr_size_t * len)
568 {
569 const char *base;
570
571 if (!src) {
572 return APR_NOTFOUND;
573 }
574
575 if (APR_ENCODE_STRING == slen) {
576 slen = strlen(src);
577 }
578
579 if (dest) {
580 register char *bufout = dest;
581 int i;
582
583 if (!((flags & APR_ENCODE_BASE32HEX))) {
584 base = base32;
585 }
586 else {
587 base = base32hex;
588 }
589
590 for (i = 0; i < slen - 4; i += 5) {
591 *bufout++ = base[ENCODE_TO_ASCII((src[i] >> 3) & 0x1F)];
592 *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
593 | ((src[i + 1] >> 6) & 0x3))];
594 *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
595 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1] << 4) & 0x10)
596 | ((src[i + 2] >> 4) & 0xF))];
597 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 2] << 1) & 0x1E)
598 | ((src[i + 3] >> 7) & 0x1))];
599 *bufout++ = base[ENCODE_TO_ASCII((src[i + 3] >> 2) & 0x1F)];
600 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 3] << 3) & 0x18)
601 | ((src[i + 4] >> 5) & 0x7))];
602 *bufout++ = base[ENCODE_TO_ASCII(src[i + 4] & 0x1F)];
603 }
604 if (i < slen) {
605 *bufout++ = base[ENCODE_TO_ASCII(src[i] >> 3) & 0x1F];
606 if (i == (slen - 1)) {
607 *bufout++ = base[ENCODE_TO_ASCII((src[i] << 2) & 0x1C)];
608 if (!(flags & APR_ENCODE_NOPADDING)) {
609 *bufout++ = '=';
610 *bufout++ = '=';
611 *bufout++ = '=';
612 *bufout++ = '=';
613 *bufout++ = '=';
614 *bufout++ = '=';
615 }
616 }
617 else if (i == (slen - 2)) {
618 *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
619 | ((src[i + 1] >> 6) & 0x3))];
620 *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
621 *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] << 4) & 0x10)];
622 if (!(flags & APR_ENCODE_NOPADDING)) {
623 *bufout++ = '=';
624 *bufout++ = '=';
625 *bufout++ = '=';
626 *bufout++ = '=';
627 }
628 }
629 else if (i == (slen - 3)) {
630 *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
631 | ((src[i + 1] >> 6) & 0x3))];
632 *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
633 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1] << 4) & 0x10)
634 | ((src[i + 2] >> 4) & 0xF))];
635 *bufout++ = base[ENCODE_TO_ASCII((src[i + 2] << 1) & 0x1E)];
636 if (!(flags & APR_ENCODE_NOPADDING)) {
637 *bufout++ = '=';
638 *bufout++ = '=';
639 *bufout++ = '=';
640 }
641 }
642 else {
643 *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
644 | ((src[i + 1] >> 6) & 0x3))];
645 *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
646 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1] << 4) & 0x10)
647 | ((src[i + 2] >> 4) & 0xF))];
648 *bufout++ = base[ENCODE_TO_ASCII(((src[i + 2] << 1) & 0x1E)
649 | ((src[i + 3] >> 7) & 0x1))];
650 *bufout++ = base[ENCODE_TO_ASCII((src[i + 3] >> 2) & 0x1F)];
651 *bufout++ = base[ENCODE_TO_ASCII((src[i + 3] << 3) & 0x18)];
652 if (!(flags & APR_ENCODE_NOPADDING)) {
653 *bufout++ = '=';
654 }
655 }
656 }
657
658 if (len) {
659 *len = bufout - dest;
660 }
661
662 *bufout++ = '\0';
663
664 return APR_SUCCESS;
665 }
666
667 if (len) {
668 *len = ((slen + 2) / 3 * 4) + 1;
669 }
670
671 return APR_SUCCESS;
672 }
673
apr_encode_base32_binary(char * dest,const unsigned char * src,apr_ssize_t slen,int flags,apr_size_t * len)674 APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned char *src,
675 apr_ssize_t slen, int flags, apr_size_t * len)
676 {
677 const char *base;
678
679 if (!src) {
680 return APR_NOTFOUND;
681 }
682
683 if (dest) {
684 register char *bufout = dest;
685 int i;
686
687 if (!((flags & APR_ENCODE_BASE32HEX))) {
688 base = base32;
689 }
690 else {
691 base = base32hex;
692 }
693
694 for (i = 0; i < slen - 4; i += 5) {
695 *bufout++ = base[((src[i] >> 3) & 0x1F)];
696 *bufout++ = base[(((src[i] << 2) & 0x1C)
697 | ((src[i + 1] >> 6) & 0x3))];
698 *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
699 *bufout++ = base[(((src[i + 1] << 4) & 0x10)
700 | ((src[i + 2] >> 4) & 0xF))];
701 *bufout++ = base[(((src[i + 2] << 1) & 0x1E)
702 | ((src[i + 3] >> 7) & 0x1))];
703 *bufout++ = base[((src[i + 3] >> 2) & 0x1F)];
704 *bufout++ = base[(((src[i + 3] << 3) & 0x18)
705 | ((src[i + 4] >> 5) & 0x7))];
706 *bufout++ = base[(src[i + 4] & 0x1F)];
707 }
708 if (i < slen) {
709 *bufout++ = base[(src[i] >> 3) & 0x1F];
710 if (i == (slen - 1)) {
711 *bufout++ = base[((src[i] << 2) & 0x1C)];
712 if (!(flags & APR_ENCODE_NOPADDING)) {
713 *bufout++ = '=';
714 *bufout++ = '=';
715 *bufout++ = '=';
716 *bufout++ = '=';
717 *bufout++ = '=';
718 *bufout++ = '=';
719 }
720 }
721 else if (i == (slen - 2)) {
722 *bufout++ = base[(((src[i] << 2) & 0x1C)
723 | ((src[i + 1] >> 6) & 0x3))];
724 *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
725 *bufout++ = base[((src[i + 1] << 4) & 0x10)];
726 if (!(flags & APR_ENCODE_NOPADDING)) {
727 *bufout++ = '=';
728 *bufout++ = '=';
729 *bufout++ = '=';
730 *bufout++ = '=';
731 }
732 }
733 else if (i == (slen - 3)) {
734 *bufout++ = base[(((src[i] << 2) & 0x1C)
735 | ((src[i + 1] >> 6) & 0x3))];
736 *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
737 *bufout++ = base[(((src[i + 1] << 4) & 0x10)
738 | ((int)(src[i + 2] >> 4) & 0xF))];
739 *bufout++ = base[((src[i + 2] << 1) & 0x1E)];
740 if (!(flags & APR_ENCODE_NOPADDING)) {
741 *bufout++ = '=';
742 *bufout++ = '=';
743 *bufout++ = '=';
744 }
745 }
746 else {
747 *bufout++ = base[(((src[i] << 2) & 0x1C)
748 | ((src[i + 1] >> 6) & 0x3))];
749 *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
750 *bufout++ = base[(((src[i + 1] << 4) & 0x10)
751 | ((src[i + 2] >> 4) & 0xF))];
752 *bufout++ = base[(((src[i + 2] << 1) & 0x1E)
753 | ((src[i + 3] >> 7) & 0x1))];
754 *bufout++ = base[((src[i + 3] >> 2) & 0x1F)];
755 *bufout++ = base[((src[i + 3] << 3) & 0x18)];
756 if (!(flags & APR_ENCODE_NOPADDING)) {
757 *bufout++ = '=';
758 }
759 }
760 }
761
762 if (len) {
763 *len = bufout - dest;
764 }
765
766 *bufout++ = '\0';
767
768 return APR_SUCCESS;
769 }
770
771 if (len) {
772 *len = ((slen + 4) / 5 * 8) + 1;
773 }
774
775 return APR_SUCCESS;
776 }
777
apr_pencode_base32(apr_pool_t * p,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)778 APR_DECLARE(const char *)apr_pencode_base32(apr_pool_t * p, const char *src,
779 apr_ssize_t slen, int flags, apr_size_t * len)
780 {
781 apr_size_t size;
782
783 switch (apr_encode_base32(NULL, src, slen, flags, &size)) {
784 case APR_SUCCESS:{
785 char *cmd = apr_palloc(p, size);
786 apr_encode_base32(cmd, src, slen, flags, len);
787 return cmd;
788 }
789 case APR_NOTFOUND:{
790 break;
791 }
792 }
793
794 return NULL;
795 }
796
apr_pencode_base32_binary(apr_pool_t * p,const unsigned char * src,apr_ssize_t slen,int flags,apr_size_t * len)797 APR_DECLARE(const char *)apr_pencode_base32_binary(apr_pool_t * p, const unsigned char *src,
798 apr_ssize_t slen, int flags, apr_size_t * len)
799 {
800 apr_size_t size;
801
802 switch (apr_encode_base32_binary(NULL, src, slen, flags, &size)) {
803 case APR_SUCCESS:{
804 char *cmd = apr_palloc(p, size);
805 apr_encode_base32_binary(cmd, src, slen, flags, len);
806 return cmd;
807 }
808 case APR_NOTFOUND:{
809 break;
810 }
811 }
812
813 return NULL;
814 }
815
apr_decode_base32(char * dest,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)816 APR_DECLARE(apr_status_t) apr_decode_base32(char *dest, const char *src,
817 apr_ssize_t slen, int flags, apr_size_t * len)
818 {
819 if (!src) {
820 return APR_NOTFOUND;
821 }
822
823 if (APR_ENCODE_STRING == slen) {
824 slen = strlen(src);
825 }
826
827 if (dest) {
828 register const unsigned char *bufin;
829 register unsigned char *bufout;
830 register apr_size_t nprbytes;
831 register apr_size_t count = slen;
832
833 const unsigned char *pr2;
834
835 apr_status_t status;
836
837 if ((flags & APR_ENCODE_BASE32HEX)) {
838 pr2 = pr2fivehex;
839 }
840 else {
841 pr2 = pr2five;
842 }
843
844 bufin = (const unsigned char *)src;
845 while (pr2[*(bufin++)] < 32 && count)
846 count--;
847 nprbytes = (bufin - (const unsigned char *)src) - 1;
848 while (pr2[*(bufin++)] > 32 && count)
849 count--;
850
851 status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
852 count ? APR_BADCH : APR_SUCCESS;
853
854 bufout = (unsigned char *)dest;
855 bufin = (const unsigned char *)src;
856
857 while (nprbytes > 8) {
858 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[0]] << 3
859 | pr2[bufin[1]] >> 2);
860 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[1]] << 6
861 | pr2[bufin[2]] << 1 | pr2[bufin[3]] >> 4);
862 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[3]] << 4
863 | pr2[bufin[4]] >> 1);
864 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[4]] << 7
865 | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
866 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[6]] << 5
867 | pr2[bufin[7]]);
868 bufin += 8;
869 nprbytes -= 8;
870 }
871
872 if (nprbytes == 1) {
873 status = APR_BADCH;
874 }
875 if (nprbytes >= 2) {
876 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
877 pr2[bufin[0]] << 3 | pr2[bufin[1]] >> 2);
878 }
879 if (nprbytes == 3) {
880 status = APR_BADCH;
881 }
882 if (nprbytes >= 4) {
883 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
884 pr2[bufin[1]] << 6 | pr2[bufin[2]] << 1
885 | pr2[bufin[3]] >> 4);
886 }
887 if (nprbytes >= 5) {
888 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[3]] << 4
889 | pr2[bufin[4]] >> 1);
890 }
891 if (nprbytes == 6) {
892 status = APR_BADCH;
893 }
894 if (nprbytes >= 7) {
895 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[4]] << 7
896 | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
897 }
898 if (nprbytes == 8) {
899 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[6]] << 5
900 | pr2[bufin[7]]);
901 }
902
903 if (len) {
904 *len = bufout - (unsigned char *)dest;
905 }
906
907 *(bufout++) = 0;
908
909 return status;
910 }
911
912 if (len) {
913 *len = (((int)slen + 7) / 8) * 5 + 1;
914 }
915
916 return APR_SUCCESS;
917 }
918
apr_decode_base32_binary(unsigned char * dest,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)919 APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest,
920 const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
921 {
922 if (!src) {
923 return APR_NOTFOUND;
924 }
925
926 if (APR_ENCODE_STRING == slen) {
927 slen = strlen(src);
928 }
929
930 if (dest) {
931 register const unsigned char *bufin;
932 register unsigned char *bufout;
933 register apr_size_t nprbytes;
934 register apr_size_t count = slen;
935
936 const unsigned char *pr2;
937
938 apr_status_t status;
939
940 if ((flags & APR_ENCODE_BASE32HEX)) {
941 pr2 = pr2fivehex;
942 }
943 else {
944 pr2 = pr2five;
945 }
946
947 bufin = (const unsigned char *)src;
948 while (pr2[*(bufin++)] < 32 && count)
949 count--;
950 nprbytes = (bufin - (const unsigned char *)src) - 1;
951 while (pr2[*(bufin++)] > 32 && count)
952 count--;
953
954 status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
955 count ? APR_BADCH : APR_SUCCESS;
956
957 bufout = (unsigned char *)dest;
958 bufin = (const unsigned char *)src;
959
960 while (nprbytes > 8) {
961 *(bufout++) = (unsigned char)(pr2[bufin[0]] << 3
962 | pr2[bufin[1]] >> 2);
963 *(bufout++) = (unsigned char)(pr2[bufin[1]] << 6
964 | pr2[bufin[2]] << 1 | pr2[bufin[3]] >> 4);
965 *(bufout++) = (unsigned char)(pr2[bufin[3]] << 4
966 | pr2[bufin[4]] >> 1);
967 *(bufout++) = (unsigned char)(pr2[bufin[4]] << 7
968 | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
969 *(bufout++) = (unsigned char)(pr2[bufin[6]] << 5
970 | pr2[bufin[7]]);
971 bufin += 8;
972 nprbytes -= 8;
973 }
974
975 if (nprbytes == 1) {
976 status = APR_BADCH;
977 }
978 if (nprbytes >= 2) {
979 *(bufout++) = (unsigned char)(
980 pr2[bufin[0]] << 3 | pr2[bufin[1]] >> 2);
981 }
982 if (nprbytes == 3) {
983 status = APR_BADCH;
984 }
985 if (nprbytes >= 4) {
986 *(bufout++) = (unsigned char)(
987 pr2[bufin[1]] << 6 | pr2[bufin[2]] << 1
988 | pr2[bufin[3]] >> 4);
989 }
990 if (nprbytes >= 5) {
991 *(bufout++) = (unsigned char)(pr2[bufin[3]] << 4
992 | pr2[bufin[4]] >> 1);
993 }
994 if (nprbytes == 6) {
995 status = APR_BADCH;
996 }
997 if (nprbytes >= 7) {
998 *(bufout++) = (unsigned char)(pr2[bufin[4]] << 7
999 | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
1000 }
1001 if (nprbytes == 8) {
1002 *(bufout++) = (unsigned char)(pr2[bufin[6]] << 5
1003 | pr2[bufin[7]]);
1004 }
1005
1006 if (len) {
1007 *len = bufout - dest;
1008 }
1009
1010 return status;
1011 }
1012
1013 if (len) {
1014 *len = (((int)slen + 7) / 8) * 5;
1015 }
1016
1017 return APR_SUCCESS;
1018 }
1019
apr_pdecode_base32(apr_pool_t * p,const char * str,apr_ssize_t slen,int flags,apr_size_t * len)1020 APR_DECLARE(const char *)apr_pdecode_base32(apr_pool_t * p, const char *str,
1021 apr_ssize_t slen, int flags, apr_size_t * len)
1022 {
1023 apr_size_t size;
1024
1025 switch (apr_decode_base32(NULL, str, slen, flags, &size)) {
1026 case APR_SUCCESS:{
1027 void *cmd = apr_palloc(p, size);
1028 apr_decode_base32(cmd, str, slen, flags, len);
1029 return cmd;
1030 }
1031 case APR_BADCH:
1032 case APR_NOTFOUND:{
1033 break;
1034 }
1035 }
1036
1037 return NULL;
1038 }
1039
apr_pdecode_base32_binary(apr_pool_t * p,const char * str,apr_ssize_t slen,int flags,apr_size_t * len)1040 APR_DECLARE(const unsigned char *)apr_pdecode_base32_binary(apr_pool_t * p,
1041 const char *str, apr_ssize_t slen, int flags, apr_size_t * len)
1042 {
1043 apr_size_t size;
1044
1045 switch (apr_decode_base32_binary(NULL, str, slen, flags, &size)) {
1046 case APR_SUCCESS:{
1047 unsigned char *cmd = apr_palloc(p, size + 1);
1048 cmd[size] = 0;
1049 apr_decode_base32_binary(cmd, str, slen, flags, len);
1050 return cmd;
1051 }
1052 case APR_BADCH:
1053 case APR_NOTFOUND:{
1054 break;
1055 }
1056 }
1057
1058 return NULL;
1059 }
1060
apr_encode_base16(char * dest,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)1061 APR_DECLARE(apr_status_t) apr_encode_base16(char *dest,
1062 const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1063 {
1064 const char *in = src;
1065 apr_size_t size;
1066
1067 if (!src) {
1068 return APR_NOTFOUND;
1069 }
1070
1071 if (dest) {
1072 register char *bufout = dest;
1073 const char *base;
1074
1075 if ((flags & APR_ENCODE_LOWER)) {
1076 base = base16lower;
1077 }
1078 else {
1079 base = base16;
1080 }
1081
1082 for (size = 0; (APR_ENCODE_STRING == slen) ? in[size] : size < slen; size++) {
1083 if ((flags & APR_ENCODE_COLON) && size) {
1084 *(bufout++) = ':';
1085 }
1086 *(bufout++) = base[(const unsigned char)(ENCODE_TO_ASCII(in[size])) >> 4];
1087 *(bufout++) = base[(const unsigned char)(ENCODE_TO_ASCII(in[size])) & 0xf];
1088 }
1089
1090 if (len) {
1091 *len = bufout - dest;
1092 }
1093
1094 *bufout = '\0';
1095
1096 return APR_SUCCESS;
1097 }
1098
1099 if (len) {
1100 if (APR_ENCODE_STRING == slen) {
1101 slen = strlen(src);
1102 }
1103 if ((flags & APR_ENCODE_COLON) && slen) {
1104 *len = slen * 3;
1105 }
1106 else {
1107 *len = slen * 2 + 1;
1108 }
1109 }
1110
1111 return APR_SUCCESS;
1112 }
1113
apr_encode_base16_binary(char * dest,const unsigned char * src,apr_ssize_t slen,int flags,apr_size_t * len)1114 APR_DECLARE(apr_status_t) apr_encode_base16_binary(char *dest,
1115 const unsigned char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1116 {
1117 const unsigned char *in = src;
1118 apr_size_t size;
1119
1120 if (!src) {
1121 return APR_NOTFOUND;
1122 }
1123
1124 if (dest) {
1125 register char *bufout = dest;
1126 const char *base;
1127
1128 if ((flags & APR_ENCODE_LOWER)) {
1129 base = base16lower;
1130 }
1131 else {
1132 base = base16;
1133 }
1134
1135 for (size = 0; size < slen; size++) {
1136 if ((flags & APR_ENCODE_COLON) && size) {
1137 *(bufout++) = ':';
1138 }
1139 *(bufout++) = base[in[size] >> 4];
1140 *(bufout++) = base[in[size] & 0xf];
1141 }
1142
1143 if (len) {
1144 *len = bufout - dest;
1145 }
1146
1147 *bufout = 0;
1148
1149 return APR_SUCCESS;
1150 }
1151
1152 if (len) {
1153 if ((flags & APR_ENCODE_COLON) && slen) {
1154 *len = slen * 3;
1155 }
1156 else {
1157 *len = slen * 2 + 1;
1158 }
1159 }
1160
1161 return APR_SUCCESS;
1162 }
1163
apr_pencode_base16(apr_pool_t * p,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)1164 APR_DECLARE(const char *)apr_pencode_base16(apr_pool_t * p,
1165 const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1166 {
1167 apr_size_t size;
1168
1169 switch (apr_encode_base16(NULL, src, slen, flags, &size)) {
1170 case APR_SUCCESS:{
1171 char *cmd = apr_palloc(p, size);
1172 apr_encode_base16(cmd, src, slen, flags, len);
1173 return cmd;
1174 }
1175 case APR_NOTFOUND:{
1176 break;
1177 }
1178 }
1179
1180 return NULL;
1181 }
1182
apr_pencode_base16_binary(apr_pool_t * p,const unsigned char * src,apr_ssize_t slen,int flags,apr_size_t * len)1183 APR_DECLARE(const char *)apr_pencode_base16_binary(apr_pool_t * p,
1184 const unsigned char *src, apr_ssize_t slen, int flags,
1185 apr_size_t * len)
1186 {
1187 apr_size_t size;
1188
1189 switch (apr_encode_base16_binary(NULL, src, slen, flags, &size)) {
1190 case APR_SUCCESS:{
1191 char *cmd = apr_palloc(p, size);
1192 apr_encode_base16_binary(cmd, src, slen, flags, len);
1193 return cmd;
1194 }
1195 case APR_NOTFOUND:{
1196 break;
1197 }
1198 }
1199
1200 return NULL;
1201 }
1202
apr_decode_base16(char * dest,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)1203 APR_DECLARE(apr_status_t) apr_decode_base16(char *dest,
1204 const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1205 {
1206 register const unsigned char *bufin;
1207 register unsigned char *bufout;
1208 register apr_size_t nprbytes;
1209 register apr_size_t count;
1210
1211 apr_status_t status;
1212
1213 if (!src) {
1214 return APR_NOTFOUND;
1215 }
1216
1217 if (APR_ENCODE_STRING == slen) {
1218 slen = strlen(src);
1219 }
1220
1221 count = slen;
1222 bufin = (const unsigned char *)src;
1223 while (pr2two[*(bufin++)] != 16 && count)
1224 count--;
1225 nprbytes = (bufin - (const unsigned char *)src) - 1;
1226 while (pr2two[*(bufin++)] > 16 && count)
1227 count--;
1228
1229 status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
1230 count ? APR_BADCH : APR_SUCCESS;
1231
1232 if (dest) {
1233
1234 bufout = (unsigned char *)dest;
1235 bufin = (const unsigned char *)src;
1236
1237 while (nprbytes >= 2) {
1238 if (pr2two[bufin[0]] > 16) {
1239 bufin += 1;
1240 nprbytes -= 1;
1241 }
1242 else {
1243 *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
1244 pr2two[bufin[0]] << 4 | pr2two[bufin[1]]);
1245 bufin += 2;
1246 nprbytes -= 2;
1247 }
1248 }
1249
1250 if (nprbytes == 1) {
1251 status = APR_BADCH;
1252 }
1253
1254 if (len) {
1255 *len = bufout - (unsigned char *)dest;
1256 }
1257
1258 *(bufout++) = 0;
1259
1260 return status;
1261 }
1262
1263 else {
1264
1265 count = 0;
1266 bufin = (const unsigned char *)src;
1267
1268 while (nprbytes >= 2) {
1269 if (pr2two[bufin[0]] > 16) {
1270 bufin += 1;
1271 nprbytes -= 1;
1272 }
1273 else {
1274 count++;
1275 bufin += 2;
1276 nprbytes -= 2;
1277 }
1278 }
1279
1280 if (nprbytes == 1) {
1281 status = APR_BADCH;
1282 }
1283
1284 if (len) {
1285 *len = count + 1;
1286 }
1287
1288 return status;
1289 }
1290
1291 }
1292
apr_decode_base16_binary(unsigned char * dest,const char * src,apr_ssize_t slen,int flags,apr_size_t * len)1293 APR_DECLARE(apr_status_t) apr_decode_base16_binary(unsigned char *dest,
1294 const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
1295 {
1296 register const unsigned char *bufin;
1297 register unsigned char *bufout;
1298 register apr_size_t nprbytes;
1299 register apr_size_t count;
1300
1301 apr_status_t status;
1302
1303 if (!src) {
1304 return APR_NOTFOUND;
1305 }
1306
1307 if (APR_ENCODE_STRING == slen) {
1308 slen = strlen(src);
1309 }
1310
1311 count = slen;
1312 bufin = (const unsigned char *)src;
1313 while (pr2two[*(bufin++)] != 16 && count)
1314 count--;
1315 nprbytes = (bufin - (const unsigned char *)src) - 1;
1316 while (pr2two[*(bufin++)] > 16 && count)
1317 count--;
1318
1319 status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
1320 count ? APR_BADCH : APR_SUCCESS;
1321
1322 if (dest) {
1323
1324 bufout = (unsigned char *)dest;
1325 bufin = (const unsigned char *)src;
1326
1327 while (nprbytes >= 2) {
1328 if (pr2two[bufin[0]] > 16) {
1329 bufin += 1;
1330 nprbytes -= 1;
1331 }
1332 else {
1333 *(bufout++) = (unsigned char)(
1334 pr2two[bufin[0]] << 4 | pr2two[bufin[1]]);
1335 bufin += 2;
1336 nprbytes -= 2;
1337 }
1338 }
1339
1340 if (nprbytes == 1) {
1341 status = APR_BADCH;
1342 }
1343
1344 if (len) {
1345 *len = bufout - (unsigned char *)dest;
1346 }
1347
1348 return status;
1349 }
1350
1351 else {
1352
1353 count = 0;
1354 bufin = (const unsigned char *)src;
1355
1356 while (nprbytes >= 2) {
1357 if (pr2two[bufin[0]] > 16) {
1358 bufin += 1;
1359 nprbytes -= 1;
1360 }
1361 else {
1362 count++;
1363 bufin += 2;
1364 nprbytes -= 2;
1365 }
1366 }
1367
1368 if (nprbytes == 1) {
1369 status = APR_BADCH;
1370 }
1371
1372 if (len) {
1373 *len = count;
1374 }
1375
1376 return status;
1377 }
1378 }
1379
apr_pdecode_base16(apr_pool_t * p,const char * str,apr_ssize_t slen,int flags,apr_size_t * len)1380 APR_DECLARE(const char *)apr_pdecode_base16(apr_pool_t * p,
1381 const char *str, apr_ssize_t slen, int flags, apr_size_t * len)
1382 {
1383 apr_size_t size;
1384
1385 switch (apr_decode_base16(NULL, str, slen, flags, &size)) {
1386 case APR_SUCCESS:{
1387 void *cmd = apr_palloc(p, size);
1388 apr_decode_base16(cmd, str, slen, flags, len);
1389 return cmd;
1390 }
1391 case APR_BADCH:
1392 case APR_NOTFOUND:{
1393 break;
1394 }
1395 }
1396
1397 return NULL;
1398 }
1399
apr_pdecode_base16_binary(apr_pool_t * p,const char * str,apr_ssize_t slen,int flags,apr_size_t * len)1400 APR_DECLARE(const unsigned char *)apr_pdecode_base16_binary(apr_pool_t * p,
1401 const char *str, apr_ssize_t slen, int flags, apr_size_t * len)
1402 {
1403 apr_size_t size;
1404
1405 switch (apr_decode_base16_binary(NULL, str, slen, flags, &size)) {
1406 case APR_SUCCESS:{
1407 unsigned char *cmd = apr_palloc(p, size + 1);
1408 cmd[size] = 0;
1409 apr_decode_base16_binary(cmd, str, slen, flags, len);
1410 return cmd;
1411 }
1412 case APR_BADCH:
1413 case APR_NOTFOUND:{
1414 break;
1415 }
1416 }
1417
1418 return NULL;
1419 }
1420