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