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