00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "libts.h"
00035 #include "ink_assert.h"
00036
00037
00038
00039 bool
00040 ats_base64_encode(const unsigned char *inBuffer, size_t inBufferSize, char *outBuffer, size_t outBufSize, size_t *length)
00041 {
00042 static const char _codes[66] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00043 char *obuf = outBuffer;
00044 char in_tail[4];
00045
00046 if (outBufSize < ATS_BASE64_ENCODE_DSTLEN(inBufferSize))
00047 return false;
00048
00049 while (inBufferSize > 2) {
00050 *obuf++ = _codes[(inBuffer[0] >> 2) & 077];
00051 *obuf++ = _codes[((inBuffer[0] & 03) << 4) | ((inBuffer[1] >> 4) & 017)];
00052 *obuf++ = _codes[((inBuffer[1] & 017) << 2) | ((inBuffer[2] >> 6) & 017)];
00053 *obuf++ = _codes[inBuffer[2] & 077];
00054
00055 inBufferSize -= 3;
00056 inBuffer += 3;
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 if (inBufferSize == 0) {
00068 *obuf = '\0';
00069 if (length)
00070 *length = (obuf - outBuffer);
00071 } else {
00072 memset(in_tail, 0, sizeof(in_tail));
00073 memcpy(in_tail, inBuffer, inBufferSize);
00074
00075 *(obuf) = _codes[(in_tail[0] >> 2) & 077];
00076 *(obuf + 1) = _codes[((in_tail[0] & 03) << 4) | ((in_tail[1] >> 4) & 017)];
00077 *(obuf + 2) = _codes[((in_tail[1] & 017) << 2) | ((in_tail[2] >> 6) & 017)];
00078 *(obuf + 3) = _codes[in_tail[2] & 077];
00079
00080 if (inBufferSize == 1)
00081 *(obuf + 2) = '=';
00082 *(obuf + 3) = '=';
00083 *(obuf + 4) = '\0';
00084
00085 if (length)
00086 *length = (obuf + 4) - outBuffer;
00087 }
00088
00089 return true;
00090 }
00091
00092 bool
00093 ats_base64_encode(const char *inBuffer, size_t inBufferSize, char *outBuffer, size_t outBufSize, size_t *length)
00094 {
00095 return ats_base64_encode((const unsigned char *)inBuffer, inBufferSize, outBuffer, outBufSize, length);
00096 }
00097
00098
00099
00100
00101
00102 #ifdef DECODE
00103 #undef DECODE
00104 #endif
00105
00106 #define DECODE(x) printableToSixBit[(unsigned char)x]
00107 #define MAX_PRINT_VAL 63
00108
00109
00110 const unsigned char printableToSixBit[256] = {
00111 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00112 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 62, 64, 63,
00113 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
00114 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 63, 64, 26, 27,
00115 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
00116 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00117 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00118 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00119 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00120 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00121 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
00122 };
00123
00124 bool
00125 ats_base64_decode(const char *inBuffer, size_t inBufferSize, unsigned char *outBuffer, size_t outBufSize, size_t *length)
00126 {
00127 size_t inBytes = 0;
00128 size_t decodedBytes = 0;
00129 unsigned char *buf = outBuffer;
00130 int inputBytesDecoded = 0;
00131
00132
00133 if (outBufSize < ATS_BASE64_DECODE_DSTLEN(inBufferSize))
00134 return false;
00135
00136
00137
00138 while (printableToSixBit[(uint8_t)inBuffer[inBytes]] <= MAX_PRINT_VAL)
00139 ++inBytes;
00140
00141 for (size_t i = 0; i < inBytes; i += 4) {
00142 buf[0] = (unsigned char) (DECODE(inBuffer[0]) << 2 | DECODE(inBuffer[1]) >> 4);
00143 buf[1] = (unsigned char) (DECODE(inBuffer[1]) << 4 | DECODE(inBuffer[2]) >> 2);
00144 buf[2] = (unsigned char) (DECODE(inBuffer[2]) << 6 | DECODE(inBuffer[3]));
00145
00146 buf += 3;
00147 inBuffer += 4;
00148 decodedBytes += 3;
00149 inputBytesDecoded += 4;
00150 }
00151
00152
00153
00154 if ((inBytes - inputBytesDecoded) & 0x3) {
00155 if (DECODE(inBuffer[-2]) > MAX_PRINT_VAL) {
00156 decodedBytes -= 2;
00157 } else {
00158 decodedBytes -= 1;
00159 }
00160 }
00161 outBuffer[decodedBytes] = '\0';
00162
00163 if (length)
00164 *length = decodedBytes;
00165
00166 return true;
00167 }