00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "xyssl/config.h"
00022
00023 #if defined(XYSSL_BASE64_C)
00024
00025 #include "xyssl/base64.h"
00026
00027 static const unsigned char 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 unsigned char 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( XYSSL_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
00105 if( (i + 1) < slen )
00106 *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
00107 else *p++ = '=';
00108
00109 *p++ = '=';
00110 }
00111
00112 *dlen = p - dst;
00113 *p = 0;
00114
00115 return( 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( XYSSL_ERR_BASE64_INVALID_CHARACTER );
00139
00140 if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
00141 return( XYSSL_ERR_BASE64_INVALID_CHARACTER );
00142
00143 if( base64_dec_map[src[i]] < 64 && j != 0 )
00144 return( XYSSL_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( XYSSL_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 if( j > 0 ) *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 #if defined(XYSSL_SELF_TEST)
00183
00184 #include <string.h>
00185 #include <stdio.h>
00186
00187 static const unsigned char base64_test_dec[64] =
00188 {
00189 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
00190 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
00191 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
00192 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
00193 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
00194 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
00195 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
00196 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
00197 };
00198
00199 static const unsigned char base64_test_enc[] =
00200 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
00201 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
00202
00203
00204
00205
00206 int base64_self_test( int verbose )
00207 {
00208 int len;
00209 unsigned char *src, buffer[128];
00210
00211 if( verbose != 0 )
00212 printf( " Base64 encoding test: " );
00213
00214 len = sizeof( buffer );
00215 src = (unsigned char *) base64_test_dec;
00216
00217 if( base64_encode( buffer, &len, src, 64 ) != 0 ||
00218 memcmp( base64_test_enc, buffer, 88 ) != 0 )
00219 {
00220 if( verbose != 0 )
00221 printf( "failed\n" );
00222
00223 return( 1 );
00224 }
00225
00226 if( verbose != 0 )
00227 printf( "passed\n Base64 decoding test: " );
00228
00229 len = sizeof( buffer );
00230 src = (unsigned char *) base64_test_enc;
00231
00232 if( base64_decode( buffer, &len, src, 88 ) != 0 ||
00233 memcmp( base64_test_dec, buffer, 64 ) != 0 )
00234 {
00235 if( verbose != 0 )
00236 printf( "failed\n" );
00237
00238 return( 1 );
00239 }
00240
00241 if( verbose != 0 )
00242 printf( "passed\n\n" );
00243
00244 return( 0 );
00245 }
00246
00247 #endif
00248
00249 #endif