$search
00001 /* 00002 * Base64 encoding/decoding (RFC1341) 00003 * Copyright (c) 2005, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "os.h" 00018 #include "base64.h" 00019 00020 static const unsigned char base64_table[65] = 00021 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 00022 00035 unsigned char * base64_encode(const unsigned char *src, size_t len, 00036 size_t *out_len) 00037 { 00038 unsigned char *out, *pos; 00039 const unsigned char *end, *in; 00040 size_t olen; 00041 int line_len; 00042 00043 olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ 00044 olen += olen / 72; /* line feeds */ 00045 olen++; /* nul termination */ 00046 if (olen < len) 00047 return NULL; /* integer overflow */ 00048 out = os_malloc(olen); 00049 if (out == NULL) 00050 return NULL; 00051 00052 end = src + len; 00053 in = src; 00054 pos = out; 00055 line_len = 0; 00056 while (end - in >= 3) { 00057 *pos++ = base64_table[in[0] >> 2]; 00058 *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; 00059 *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; 00060 *pos++ = base64_table[in[2] & 0x3f]; 00061 in += 3; 00062 line_len += 4; 00063 if (line_len >= 72) { 00064 *pos++ = '\n'; 00065 line_len = 0; 00066 } 00067 } 00068 00069 if (end - in) { 00070 *pos++ = base64_table[in[0] >> 2]; 00071 if (end - in == 1) { 00072 *pos++ = base64_table[(in[0] & 0x03) << 4]; 00073 *pos++ = '='; 00074 } else { 00075 *pos++ = base64_table[((in[0] & 0x03) << 4) | 00076 (in[1] >> 4)]; 00077 *pos++ = base64_table[(in[1] & 0x0f) << 2]; 00078 } 00079 *pos++ = '='; 00080 line_len += 4; 00081 } 00082 00083 if (line_len) 00084 *pos++ = '\n'; 00085 00086 *pos = '\0'; 00087 if (out_len) 00088 *out_len = pos - out; 00089 return out; 00090 } 00091 00092 00103 unsigned char * base64_decode(const unsigned char *src, size_t len, 00104 size_t *out_len) 00105 { 00106 unsigned char dtable[256], *out, *pos, in[4], block[4], tmp; 00107 size_t i, count, olen; 00108 00109 os_memset(dtable, 0x80, 256); 00110 for (i = 0; i < sizeof(base64_table) - 1; i++) 00111 dtable[base64_table[i]] = (unsigned char) i; 00112 dtable['='] = 0; 00113 00114 count = 0; 00115 for (i = 0; i < len; i++) { 00116 if (dtable[src[i]] != 0x80) 00117 count++; 00118 } 00119 00120 if (count == 0 || count % 4) 00121 return NULL; 00122 00123 olen = count / 4 * 3; 00124 pos = out = os_malloc(olen); 00125 if (out == NULL) 00126 return NULL; 00127 00128 count = 0; 00129 for (i = 0; i < len; i++) { 00130 tmp = dtable[src[i]]; 00131 if (tmp == 0x80) 00132 continue; 00133 00134 in[count] = src[i]; 00135 block[count] = tmp; 00136 count++; 00137 if (count == 4) { 00138 *pos++ = (block[0] << 2) | (block[1] >> 4); 00139 *pos++ = (block[1] << 4) | (block[2] >> 2); 00140 *pos++ = (block[2] << 6) | block[3]; 00141 count = 0; 00142 } 00143 } 00144 00145 if (pos > out) { 00146 if (in[2] == '=') 00147 pos -= 2; 00148 else if (in[3] == '=') 00149 pos--; 00150 } 00151 00152 *out_len = pos - out; 00153 return out; 00154 }