00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _CRT_SECURE_NO_DEPRECATE
00022 #define _CRT_SECURE_NO_DEPRECATE 1
00023 #endif
00024
00025 #include "xyssl/base64.h"
00026
00027 static const int base64_enc_map[64] =
00028 {
00029 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
00030 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
00031 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
00032 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
00033 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
00034 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
00035 '8', '9', '+', '/'
00036 };
00037
00038 static const int base64_dec_map[128] =
00039 {
00040 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
00041 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
00042 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
00043 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
00044 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
00045 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
00046 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
00047 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
00048 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
00049 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
00050 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
00051 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
00052 49, 50, 51, 127, 127, 127, 127, 127
00053 };
00054
00055
00056
00057
00058 int base64_encode( unsigned char *dst, int *dlen,
00059 unsigned char *src, int slen )
00060 {
00061 int i, n;
00062 int C1, C2, C3;
00063 unsigned char *p;
00064
00065 if( slen == 0 )
00066 return( 0 );
00067
00068 n = ( slen << 3 ) / 6;
00069
00070 switch( ( slen << 3 ) - ( n * 6 ) )
00071 {
00072 case 2: n += 3; break;
00073 case 4: n += 2; break;
00074 default: break;
00075 }
00076
00077 if( *dlen < n + 1 )
00078 {
00079 *dlen = n + 1;
00080 return( ERR_BASE64_BUFFER_TOO_SMALL );
00081 }
00082
00083 n = ( slen / 3 ) * 3;
00084
00085 for( i = 0, p = dst; i < n; i += 3 )
00086 {
00087 C1 = *src++;
00088 C2 = *src++;
00089 C3 = *src++;
00090
00091 *p++ = base64_enc_map[( C1 >> 2 ) & 0x3F];
00092 *p++ = base64_enc_map[((( C1 & 3 ) << 4) + ( C2 >> 4 )) & 0x3F];
00093 *p++ = base64_enc_map[((( C2 & 15 ) << 2) + ( C3 >> 6 )) & 0x3F];
00094 *p++ = base64_enc_map[C3 & 0x3F];
00095 }
00096
00097 if( i < slen )
00098 {
00099 C1 = *src++;
00100 C2 = ((i + 1) < slen) ? *src++ : 0;
00101
00102 *p++ = base64_enc_map[( C1 >> 2 ) & 0x3F];
00103 *p++ = base64_enc_map[((( C1 & 3 ) << 4) + ( C2 >> 4 )) & 0x3F];
00104 *p++ = ((i + 1) < slen) ?
00105 base64_enc_map[((( C2 & 15 ) << 2)) & 0x3F] : '=';
00106
00107 *p++ = '=';
00108 }
00109
00110 *dlen = p - dst;
00111
00112 return( *p = 0 );
00113 }
00114
00115
00116
00117
00118 int base64_decode( unsigned char *dst, int *dlen,
00119 unsigned char *src, int slen )
00120 {
00121 int i, j, n;
00122 unsigned long x;
00123 unsigned char *p;
00124
00125 for( i = j = n = 0; i < slen; i++ )
00126 {
00127 if( ( slen - i ) >= 2 &&
00128 src[i] == '\r' && src[i + 1] == '\n' )
00129 continue;
00130
00131 if( src[i] == '\n' )
00132 continue;
00133
00134 if( src[i] == '=' && ++j > 2 )
00135 return( ERR_BASE64_INVALID_CHARACTER );
00136
00137 if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
00138 return( ERR_BASE64_INVALID_CHARACTER );
00139
00140 if( base64_dec_map[src[i]] < 64 && j != 0 )
00141 return( ERR_BASE64_INVALID_CHARACTER );
00142
00143 n++;
00144 }
00145
00146 if( n == 0 )
00147 return( 0 );
00148
00149 n = ( ( n * 6 ) + 7 ) >> 3;
00150
00151 if( *dlen < n )
00152 {
00153 *dlen = n;
00154 return( ERR_BASE64_BUFFER_TOO_SMALL );
00155 }
00156
00157 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
00158 {
00159 if( *src == '\r' || *src == '\n' )
00160 continue;
00161
00162 j -= ( base64_dec_map[*src] == 64 );
00163 x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
00164
00165 if( ++n == 4 )
00166 {
00167 n = 0;
00168 *p++ = (unsigned char) ( x >> 16 );
00169 if( j > 1 ) *p++ = (unsigned char) ( x >> 8 );
00170 if( j > 2 ) *p++ = (unsigned char ) x;
00171 }
00172 }
00173
00174 *dlen = p - dst;
00175
00176 return( 0 );
00177 }
00178
00179 static const char _base64_src[] = "_base64_src";
00180
00181 #if defined(SELF_TEST)
00182
00183 #include <string.h>
00184 #include <stdio.h>
00185
00186 static const unsigned char base64_test_dec[64] =
00187 {
00188 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
00189 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
00190 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
00191 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
00192 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
00193 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
00194 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
00195 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
00196 };
00197
00198 static const unsigned char base64_test_enc[] =
00199 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
00200 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
00201
00202
00203
00204
00205 int base64_self_test( int verbose )
00206 {
00207 int len;
00208 unsigned char *src, buffer[128];
00209
00210 if( verbose != 0 )
00211 printf( " Base64 encoding test: " );
00212
00213 len = sizeof( buffer );
00214 src = (unsigned char *) base64_test_dec;
00215
00216 if( base64_encode( buffer, &len, src, 64 ) != 0 ||
00217 memcmp( base64_test_enc, buffer, 88 ) != 0 )
00218 {
00219 if( verbose != 0 )
00220 printf( "failed\n" );
00221
00222 return( 1 );
00223 }
00224
00225 if( verbose != 0 )
00226 printf( "passed\n Base64 decoding test: " );
00227
00228 len = sizeof( buffer );
00229 src = (unsigned char *) base64_test_enc;
00230
00231 if( base64_decode( buffer, &len, src, 88 ) != 0 ||
00232 memcmp( base64_test_dec, buffer, 64 ) != 0 )
00233 {
00234 if( verbose != 0 )
00235 printf( "failed\n" );
00236
00237 return( 1 );
00238 }
00239
00240 if( verbose != 0 )
00241 printf( "passed\n\n" );
00242
00243 return( 0 );
00244 }
00245 #else
00246 int base64_self_test( int verbose )
00247 {
00248 return( 0 );
00249 }
00250 #endif