/home/dko/projects/mobilec/trunk/src/security/xyssl-0.9/library/base64.c

Go to the documentation of this file.
00001 /*
00002  * RFC 1521 base64 encoding/decoding
00003  *
00004  * Copyright (C) 2006-2007 Christophe Devine
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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  * Encode a buffer into base64 format
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  * Decode a base64-formatted buffer
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  * Checkup routine
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

Generated on Tue Oct 28 17:03:22 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /