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. */ 34static 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 75static 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 116static 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 157static 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 198static const char base64[] = 199"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 200static const char base64url[] = 201"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; 202 203static const char base32[] = 204"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; 205static const char base32hex[] = 206"0123456789ABCDEFGHIJKLMNOPQRSTUV"; 207 208static const char base16[] = "0123456789ABCDEF"; 209static const char base16lower[] = "0123456789abcdef"; 210 211APR_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 277APR_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 339APR_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 358APR_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 377APR_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 452APR_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 525APR_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 545APR_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 566APR_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 674APR_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 778APR_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 797APR_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 816APR_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 919APR_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 1020APR_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 1040APR_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 1061APR_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 1114APR_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 1164APR_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 1183APR_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 1203APR_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 1293APR_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 1380APR_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 1400APR_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