PolarSSL v1.1.4
|
00001 /* 00002 * RFC 1521 base64 encoding/decoding 00003 * 00004 * Copyright (C) 2006-2010, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License along 00022 * with this program; if not, write to the Free Software Foundation, Inc., 00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00024 */ 00025 00026 #include "polarssl/config.h" 00027 00028 #if defined(POLARSSL_BASE64_C) 00029 00030 #include "polarssl/base64.h" 00031 00032 static const unsigned char base64_enc_map[64] = 00033 { 00034 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 00035 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 00036 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 00037 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 00038 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 00039 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 00040 '8', '9', '+', '/' 00041 }; 00042 00043 static const unsigned char base64_dec_map[128] = 00044 { 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, 127, 127, 127, 127, 127, 127, 127, 00048 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 00049 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, 00050 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, 00051 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, 00052 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 00053 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 00054 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, 00055 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 00056 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 00057 49, 50, 51, 127, 127, 127, 127, 127 00058 }; 00059 00060 /* 00061 * Encode a buffer into base64 format 00062 */ 00063 int base64_encode( unsigned char *dst, size_t *dlen, 00064 const unsigned char *src, size_t slen ) 00065 { 00066 size_t i, n; 00067 int C1, C2, C3; 00068 unsigned char *p; 00069 00070 if( slen == 0 ) 00071 return( 0 ); 00072 00073 n = (slen << 3) / 6; 00074 00075 switch( (slen << 3) - (n * 6) ) 00076 { 00077 case 2: n += 3; break; 00078 case 4: n += 2; break; 00079 default: break; 00080 } 00081 00082 if( *dlen < n + 1 ) 00083 { 00084 *dlen = n + 1; 00085 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); 00086 } 00087 00088 n = (slen / 3) * 3; 00089 00090 for( i = 0, p = dst; i < n; i += 3 ) 00091 { 00092 C1 = *src++; 00093 C2 = *src++; 00094 C3 = *src++; 00095 00096 *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 00097 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 00098 *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; 00099 *p++ = base64_enc_map[C3 & 0x3F]; 00100 } 00101 00102 if( i < slen ) 00103 { 00104 C1 = *src++; 00105 C2 = ((i + 1) < slen) ? *src++ : 0; 00106 00107 *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 00108 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 00109 00110 if( (i + 1) < slen ) 00111 *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; 00112 else *p++ = '='; 00113 00114 *p++ = '='; 00115 } 00116 00117 *dlen = p - dst; 00118 *p = 0; 00119 00120 return( 0 ); 00121 } 00122 00123 /* 00124 * Decode a base64-formatted buffer 00125 */ 00126 int base64_decode( unsigned char *dst, size_t *dlen, 00127 const unsigned char *src, size_t slen ) 00128 { 00129 size_t i, j, n; 00130 unsigned long x; 00131 unsigned char *p; 00132 00133 for( i = j = n = 0; i < slen; i++ ) 00134 { 00135 if( ( slen - i ) >= 2 && 00136 src[i] == '\r' && src[i + 1] == '\n' ) 00137 continue; 00138 00139 if( src[i] == '\n' ) 00140 continue; 00141 00142 if( src[i] == '=' && ++j > 2 ) 00143 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); 00144 00145 if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) 00146 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); 00147 00148 if( base64_dec_map[src[i]] < 64 && j != 0 ) 00149 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); 00150 00151 n++; 00152 } 00153 00154 if( n == 0 ) 00155 return( 0 ); 00156 00157 n = ((n * 6) + 7) >> 3; 00158 00159 if( *dlen < n ) 00160 { 00161 *dlen = n; 00162 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); 00163 } 00164 00165 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) 00166 { 00167 if( *src == '\r' || *src == '\n' ) 00168 continue; 00169 00170 j -= ( base64_dec_map[*src] == 64 ); 00171 x = (x << 6) | ( base64_dec_map[*src] & 0x3F ); 00172 00173 if( ++n == 4 ) 00174 { 00175 n = 0; 00176 if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); 00177 if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); 00178 if( j > 2 ) *p++ = (unsigned char)( x ); 00179 } 00180 } 00181 00182 *dlen = p - dst; 00183 00184 return( 0 ); 00185 } 00186 00187 #if defined(POLARSSL_SELF_TEST) 00188 00189 #include <string.h> 00190 #include <stdio.h> 00191 00192 static const unsigned char base64_test_dec[64] = 00193 { 00194 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, 00195 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, 00196 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, 00197 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, 00198 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, 00199 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, 00200 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, 00201 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 00202 }; 00203 00204 static const unsigned char base64_test_enc[] = 00205 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" 00206 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; 00207 00208 /* 00209 * Checkup routine 00210 */ 00211 int base64_self_test( int verbose ) 00212 { 00213 size_t len; 00214 unsigned char *src, buffer[128]; 00215 00216 if( verbose != 0 ) 00217 printf( " Base64 encoding test: " ); 00218 00219 len = sizeof( buffer ); 00220 src = (unsigned char *) base64_test_dec; 00221 00222 if( base64_encode( buffer, &len, src, 64 ) != 0 || 00223 memcmp( base64_test_enc, buffer, 88 ) != 0 ) 00224 { 00225 if( verbose != 0 ) 00226 printf( "failed\n" ); 00227 00228 return( 1 ); 00229 } 00230 00231 if( verbose != 0 ) 00232 printf( "passed\n Base64 decoding test: " ); 00233 00234 len = sizeof( buffer ); 00235 src = (unsigned char *) base64_test_enc; 00236 00237 if( base64_decode( buffer, &len, src, 88 ) != 0 || 00238 memcmp( base64_test_dec, buffer, 64 ) != 0 ) 00239 { 00240 if( verbose != 0 ) 00241 printf( "failed\n" ); 00242 00243 return( 1 ); 00244 } 00245 00246 if( verbose != 0 ) 00247 printf( "passed\n\n" ); 00248 00249 return( 0 ); 00250 } 00251 00252 #endif 00253 00254 #endif