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 }