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