apr_base64.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
  2. * applicable.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * 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. /* base64 encoder/decoder. Originally part of main/util.c
  17. * but moved here so that support/ab and apr_sha1.c could
  18. * use it. This meant removing the apr_palloc()s and adding
  19. * ugly 'len' functions, which is quite a nasty cost.
  20. */
  21. #include "apr_base64.h"
  22. #if APR_CHARSET_EBCDIC
  23. #include "apr_xlate.h"
  24. #endif /* APR_CHARSET_EBCDIC */
  25. /* aaaack but it's fast and const should make it shared text page. */
  26. static const unsigned char pr2six[256] =
  27. {
  28. #if !APR_CHARSET_EBCDIC
  29. /* ASCII table */
  30. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  31. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  32. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
  33. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
  34. 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  35. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
  36. 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  37. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
  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, 64, 64, 64, 64, 64,
  41. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  42. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  43. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  44. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  45. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
  46. #else /*APR_CHARSET_EBCDIC*/
  47. /* EBCDIC table */
  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, 62, 64,
  53. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  54. 64, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  55. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  56. 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64,
  57. 64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64,
  58. 64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 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, 0, 1, 2, 3, 4, 5, 6, 7, 8, 64, 64, 64, 64, 64, 64,
  61. 64, 9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64,
  62. 64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64,
  63. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64
  64. #endif /*APR_CHARSET_EBCDIC*/
  65. };
  66. #if APR_CHARSET_EBCDIC
  67. static apr_xlate_t *xlate_to_ebcdic;
  68. static unsigned char os_toascii[256];
  69. APU_DECLARE(apr_status_t) apr_base64init_ebcdic(apr_xlate_t *to_ascii,
  70. apr_xlate_t *to_ebcdic)
  71. {
  72. int i;
  73. apr_size_t inbytes_left, outbytes_left;
  74. apr_status_t rv;
  75. int onoff;
  76. /* Only single-byte conversion is supported.
  77. */
  78. rv = apr_xlate_sb_get(to_ascii, &onoff);
  79. if (rv) {
  80. return rv;
  81. }
  82. if (!onoff) { /* If conversion is not single-byte-only */
  83. return APR_EINVAL;
  84. }
  85. rv = apr_xlate_sb_get(to_ebcdic, &onoff);
  86. if (rv) {
  87. return rv;
  88. }
  89. if (!onoff) { /* If conversion is not single-byte-only */
  90. return APR_EINVAL;
  91. }
  92. xlate_to_ebcdic = to_ebcdic;
  93. for (i = 0; i < sizeof(os_toascii); i++) {
  94. os_toascii[i] = i;
  95. }
  96. inbytes_left = outbytes_left = sizeof(os_toascii);
  97. apr_xlate_conv_buffer(to_ascii, os_toascii, &inbytes_left,
  98. os_toascii, &outbytes_left);
  99. return APR_SUCCESS;
  100. }
  101. #endif /*APR_CHARSET_EBCDIC*/
  102. APU_DECLARE(int) apr_base64_decode_len(const char *bufcoded)
  103. {
  104. int nbytesdecoded;
  105. register const unsigned char *bufin;
  106. register int nprbytes;
  107. bufin = (const unsigned char *) bufcoded;
  108. while (pr2six[*(bufin++)] <= 63);
  109. nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
  110. nbytesdecoded = ((nprbytes + 3) / 4) * 3;
  111. return nbytesdecoded + 1;
  112. }
  113. APU_DECLARE(int) apr_base64_decode(char *bufplain, const char *bufcoded)
  114. {
  115. #if APR_CHARSET_EBCDIC
  116. apr_size_t inbytes_left, outbytes_left;
  117. #endif /* APR_CHARSET_EBCDIC */
  118. int len;
  119. len = apr_base64_decode_binary((unsigned char *) bufplain, bufcoded);
  120. #if APR_CHARSET_EBCDIC
  121. inbytes_left = outbytes_left = len;
  122. apr_xlate_conv_buffer(xlate_to_ebcdic, bufplain, &inbytes_left,
  123. bufplain, &outbytes_left);
  124. #endif /* APR_CHARSET_EBCDIC */
  125. bufplain[len] = '\0';
  126. return len;
  127. }
  128. /* This is the same as apr_base64_decode() except on EBCDIC machines, where
  129. * the conversion of the output to ebcdic is left out.
  130. */
  131. APU_DECLARE(int) apr_base64_decode_binary(unsigned char *bufplain,
  132. const char *bufcoded)
  133. {
  134. int nbytesdecoded;
  135. register const unsigned char *bufin;
  136. register unsigned char *bufout;
  137. register int nprbytes;
  138. bufin = (const unsigned char *) bufcoded;
  139. while (pr2six[*(bufin++)] <= 63);
  140. nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
  141. nbytesdecoded = ((nprbytes + 3) / 4) * 3;
  142. bufout = (unsigned char *) bufplain;
  143. bufin = (const unsigned char *) bufcoded;
  144. while (nprbytes > 4) {
  145. *(bufout++) =
  146. (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
  147. *(bufout++) =
  148. (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
  149. *(bufout++) =
  150. (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
  151. bufin += 4;
  152. nprbytes -= 4;
  153. }
  154. /* Note: (nprbytes == 1) would be an error, so just ingore that case */
  155. if (nprbytes > 1) {
  156. *(bufout++) =
  157. (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
  158. }
  159. if (nprbytes > 2) {
  160. *(bufout++) =
  161. (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
  162. }
  163. if (nprbytes > 3) {
  164. *(bufout++) =
  165. (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
  166. }
  167. nbytesdecoded -= (4 - nprbytes) & 3;
  168. return nbytesdecoded;
  169. }
  170. static const char basis_64[] =
  171. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  172. APU_DECLARE(int) apr_base64_encode_len(int len)
  173. {
  174. return ((len + 2) / 3 * 4) + 1;
  175. }
  176. APU_DECLARE(int) apr_base64_encode(char *encoded, const char *string, int len)
  177. {
  178. #if !APR_CHARSET_EBCDIC
  179. return apr_base64_encode_binary(encoded, (const unsigned char *) string, len);
  180. #else /* APR_CHARSET_EBCDIC */
  181. int i;
  182. char *p;
  183. p = encoded;
  184. for (i = 0; i < len - 2; i += 3) {
  185. *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
  186. *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
  187. ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
  188. *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) |
  189. ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)];
  190. *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F];
  191. }
  192. if (i < len) {
  193. *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
  194. if (i == (len - 1)) {
  195. *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4)];
  196. *p++ = '=';
  197. }
  198. else {
  199. *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
  200. ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
  201. *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)];
  202. }
  203. *p++ = '=';
  204. }
  205. *p++ = '\0';
  206. return p - encoded;
  207. #endif /* APR_CHARSET_EBCDIC */
  208. }
  209. /* This is the same as apr_base64_encode() except on EBCDIC machines, where
  210. * the conversion of the input to ascii is left out.
  211. */
  212. APU_DECLARE(int) apr_base64_encode_binary(char *encoded,
  213. const unsigned char *string, int len)
  214. {
  215. int i;
  216. char *p;
  217. p = encoded;
  218. for (i = 0; i < len - 2; i += 3) {
  219. *p++ = basis_64[(string[i] >> 2) & 0x3F];
  220. *p++ = basis_64[((string[i] & 0x3) << 4) |
  221. ((int) (string[i + 1] & 0xF0) >> 4)];
  222. *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
  223. ((int) (string[i + 2] & 0xC0) >> 6)];
  224. *p++ = basis_64[string[i + 2] & 0x3F];
  225. }
  226. if (i < len) {
  227. *p++ = basis_64[(string[i] >> 2) & 0x3F];
  228. if (i == (len - 1)) {
  229. *p++ = basis_64[((string[i] & 0x3) << 4)];
  230. *p++ = '=';
  231. }
  232. else {
  233. *p++ = basis_64[((string[i] & 0x3) << 4) |
  234. ((int) (string[i + 1] & 0xF0) >> 4)];
  235. *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
  236. }
  237. *p++ = '=';
  238. }
  239. *p++ = '\0';
  240. return p - encoded;
  241. }