1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251876Speter * contributor license agreements. See the NOTICE file distributed with 3251876Speter * this work for additional information regarding copyright ownership. 4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251876Speter * (the "License"); you may not use this file except in compliance with 6251876Speter * the License. You may obtain a copy of the License at 7251876Speter * 8251876Speter * http://www.apache.org/licenses/LICENSE-2.0 9251876Speter * 10251876Speter * Unless required by applicable law or agreed to in writing, software 11251876Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251876Speter * See the License for the specific language governing permissions and 14251876Speter * limitations under the License. 15251876Speter */ 16251876Speter 17251876Speter/* base64 encoder/decoder. Originally part of main/util.c 18251876Speter * but moved here so that support/ab and apr_sha1.c could 19251876Speter * use it. This meant removing the apr_palloc()s and adding 20251876Speter * ugly 'len' functions, which is quite a nasty cost. 21251876Speter */ 22251876Speter 23251876Speter#include "apr_base64.h" 24251876Speter#if APR_CHARSET_EBCDIC 25251876Speter#include "apr_xlate.h" 26251876Speter#endif /* APR_CHARSET_EBCDIC */ 27251876Speter 28251876Speter/* aaaack but it's fast and const should make it shared text page. */ 29251876Speterstatic const unsigned char pr2six[256] = 30251876Speter{ 31251876Speter#if !APR_CHARSET_EBCDIC 32251876Speter /* ASCII table */ 33251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 34251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 35251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 36251876Speter 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 37251876Speter 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 38251876Speter 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 39251876Speter 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 40251876Speter 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 41251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 42251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 43251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 44251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 45251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 46251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 47251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 48251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 49251876Speter#else /*APR_CHARSET_EBCDIC*/ 50251876Speter /* EBCDIC table */ 51251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 52251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 53251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 54251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 55251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 56251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 57251876Speter 64, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 58251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 59251876Speter 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64, 60251876Speter 64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64, 61251876Speter 64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 62251876Speter 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63251876Speter 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 64, 64, 64, 64, 64, 64, 64251876Speter 64, 9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64, 65251876Speter 64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 66251876Speter 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64 67251876Speter#endif /*APR_CHARSET_EBCDIC*/ 68251876Speter}; 69251876Speter 70251876Speter#if APR_CHARSET_EBCDIC 71251876Speterstatic apr_xlate_t *xlate_to_ebcdic; 72251876Speterstatic unsigned char os_toascii[256]; 73251876Speter 74251876SpeterAPU_DECLARE(apr_status_t) apr_base64init_ebcdic(apr_xlate_t *to_ascii, 75251876Speter apr_xlate_t *to_ebcdic) 76251876Speter{ 77251876Speter int i; 78251876Speter apr_size_t inbytes_left, outbytes_left; 79251876Speter apr_status_t rv; 80251876Speter int onoff; 81251876Speter 82251876Speter /* Only single-byte conversion is supported. 83251876Speter */ 84251876Speter rv = apr_xlate_sb_get(to_ascii, &onoff); 85251876Speter if (rv) { 86251876Speter return rv; 87251876Speter } 88251876Speter if (!onoff) { /* If conversion is not single-byte-only */ 89251876Speter return APR_EINVAL; 90251876Speter } 91251876Speter rv = apr_xlate_sb_get(to_ebcdic, &onoff); 92251876Speter if (rv) { 93251876Speter return rv; 94251876Speter } 95251876Speter if (!onoff) { /* If conversion is not single-byte-only */ 96251876Speter return APR_EINVAL; 97251876Speter } 98251876Speter xlate_to_ebcdic = to_ebcdic; 99251876Speter for (i = 0; i < sizeof(os_toascii); i++) { 100251876Speter os_toascii[i] = i; 101251876Speter } 102251876Speter inbytes_left = outbytes_left = sizeof(os_toascii); 103251876Speter apr_xlate_conv_buffer(to_ascii, os_toascii, &inbytes_left, 104251876Speter os_toascii, &outbytes_left); 105251876Speter 106251876Speter return APR_SUCCESS; 107251876Speter} 108251876Speter#endif /*APR_CHARSET_EBCDIC*/ 109251876Speter 110251876SpeterAPU_DECLARE(int) apr_base64_decode_len(const char *bufcoded) 111251876Speter{ 112251876Speter int nbytesdecoded; 113251876Speter register const unsigned char *bufin; 114251876Speter register apr_size_t nprbytes; 115251876Speter 116251876Speter bufin = (const unsigned char *) bufcoded; 117251876Speter while (pr2six[*(bufin++)] <= 63); 118251876Speter 119251876Speter nprbytes = (bufin - (const unsigned char *) bufcoded) - 1; 120251876Speter nbytesdecoded = (((int)nprbytes + 3) / 4) * 3; 121251876Speter 122251876Speter return nbytesdecoded + 1; 123251876Speter} 124251876Speter 125251876SpeterAPU_DECLARE(int) apr_base64_decode(char *bufplain, const char *bufcoded) 126251876Speter{ 127251876Speter#if APR_CHARSET_EBCDIC 128251876Speter apr_size_t inbytes_left, outbytes_left; 129251876Speter#endif /* APR_CHARSET_EBCDIC */ 130251876Speter int len; 131251876Speter 132251876Speter len = apr_base64_decode_binary((unsigned char *) bufplain, bufcoded); 133251876Speter#if APR_CHARSET_EBCDIC 134251876Speter inbytes_left = outbytes_left = len; 135251876Speter apr_xlate_conv_buffer(xlate_to_ebcdic, bufplain, &inbytes_left, 136251876Speter bufplain, &outbytes_left); 137251876Speter#endif /* APR_CHARSET_EBCDIC */ 138251876Speter bufplain[len] = '\0'; 139251876Speter return len; 140251876Speter} 141251876Speter 142251876Speter/* This is the same as apr_base64_decode() except on EBCDIC machines, where 143251876Speter * the conversion of the output to ebcdic is left out. 144251876Speter */ 145251876SpeterAPU_DECLARE(int) apr_base64_decode_binary(unsigned char *bufplain, 146251876Speter const char *bufcoded) 147251876Speter{ 148251876Speter int nbytesdecoded; 149251876Speter register const unsigned char *bufin; 150251876Speter register unsigned char *bufout; 151251876Speter register apr_size_t nprbytes; 152251876Speter 153251876Speter bufin = (const unsigned char *) bufcoded; 154251876Speter while (pr2six[*(bufin++)] <= 63); 155251876Speter nprbytes = (bufin - (const unsigned char *) bufcoded) - 1; 156251876Speter nbytesdecoded = (((int)nprbytes + 3) / 4) * 3; 157251876Speter 158251876Speter bufout = (unsigned char *) bufplain; 159251876Speter bufin = (const unsigned char *) bufcoded; 160251876Speter 161251876Speter while (nprbytes > 4) { 162251876Speter *(bufout++) = 163251876Speter (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); 164251876Speter *(bufout++) = 165251876Speter (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); 166251876Speter *(bufout++) = 167251876Speter (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); 168251876Speter bufin += 4; 169251876Speter nprbytes -= 4; 170251876Speter } 171251876Speter 172251876Speter /* Note: (nprbytes == 1) would be an error, so just ingore that case */ 173251876Speter if (nprbytes > 1) { 174251876Speter *(bufout++) = 175251876Speter (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); 176251876Speter } 177251876Speter if (nprbytes > 2) { 178251876Speter *(bufout++) = 179251876Speter (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); 180251876Speter } 181251876Speter if (nprbytes > 3) { 182251876Speter *(bufout++) = 183251876Speter (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); 184251876Speter } 185251876Speter 186251876Speter nbytesdecoded -= (4 - (int)nprbytes) & 3; 187251876Speter return nbytesdecoded; 188251876Speter} 189251876Speter 190251876Speterstatic const char basis_64[] = 191251876Speter "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 192251876Speter 193251876SpeterAPU_DECLARE(int) apr_base64_encode_len(int len) 194251876Speter{ 195251876Speter return ((len + 2) / 3 * 4) + 1; 196251876Speter} 197251876Speter 198251876SpeterAPU_DECLARE(int) apr_base64_encode(char *encoded, const char *string, int len) 199251876Speter{ 200251876Speter#if !APR_CHARSET_EBCDIC 201251876Speter return apr_base64_encode_binary(encoded, (const unsigned char *) string, len); 202251876Speter#else /* APR_CHARSET_EBCDIC */ 203251876Speter int i; 204251876Speter char *p; 205251876Speter 206251876Speter p = encoded; 207251876Speter for (i = 0; i < len - 2; i += 3) { 208251876Speter *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; 209251876Speter *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) | 210251876Speter ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; 211251876Speter *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) | 212251876Speter ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)]; 213251876Speter *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F]; 214251876Speter } 215251876Speter if (i < len) { 216251876Speter *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; 217251876Speter if (i == (len - 1)) { 218251876Speter *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4)]; 219251876Speter *p++ = '='; 220251876Speter } 221251876Speter else { 222251876Speter *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) | 223251876Speter ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; 224251876Speter *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)]; 225251876Speter } 226251876Speter *p++ = '='; 227251876Speter } 228251876Speter 229251876Speter *p++ = '\0'; 230251876Speter return p - encoded; 231251876Speter#endif /* APR_CHARSET_EBCDIC */ 232251876Speter} 233251876Speter 234251876Speter/* This is the same as apr_base64_encode() except on EBCDIC machines, where 235251876Speter * the conversion of the input to ascii is left out. 236251876Speter */ 237251876SpeterAPU_DECLARE(int) apr_base64_encode_binary(char *encoded, 238251876Speter const unsigned char *string, int len) 239251876Speter{ 240251876Speter int i; 241251876Speter char *p; 242251876Speter 243251876Speter p = encoded; 244251876Speter for (i = 0; i < len - 2; i += 3) { 245251876Speter *p++ = basis_64[(string[i] >> 2) & 0x3F]; 246251876Speter *p++ = basis_64[((string[i] & 0x3) << 4) | 247251876Speter ((int) (string[i + 1] & 0xF0) >> 4)]; 248251876Speter *p++ = basis_64[((string[i + 1] & 0xF) << 2) | 249251876Speter ((int) (string[i + 2] & 0xC0) >> 6)]; 250251876Speter *p++ = basis_64[string[i + 2] & 0x3F]; 251251876Speter } 252251876Speter if (i < len) { 253251876Speter *p++ = basis_64[(string[i] >> 2) & 0x3F]; 254251876Speter if (i == (len - 1)) { 255251876Speter *p++ = basis_64[((string[i] & 0x3) << 4)]; 256251876Speter *p++ = '='; 257251876Speter } 258251876Speter else { 259251876Speter *p++ = basis_64[((string[i] & 0x3) << 4) | 260251876Speter ((int) (string[i + 1] & 0xF0) >> 4)]; 261251876Speter *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; 262251876Speter } 263251876Speter *p++ = '='; 264251876Speter } 265251876Speter 266251876Speter *p++ = '\0'; 267251876Speter return (int)(p - encoded); 268251876Speter} 269