2 * RFC 1521 base64 encoding/decoding
4 * Copyright (C) 2006-2010, Brainspark B.V.
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "polarssl/config.h"
28 #if defined(POLARSSL_BASE64_C)
30 #include "polarssl/base64.h"
32 static const unsigned char base64_enc_map[64] =
34 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
35 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
36 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
37 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
38 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
39 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
43 static const unsigned char base64_dec_map[128] =
45 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
46 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
47 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
48 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
49 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
50 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
51 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
52 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
53 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
54 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
55 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
56 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
57 49, 50, 51, 127, 127, 127, 127, 127
61 * Encode a buffer into base64 format
63 int base64_encode( unsigned char *dst, int *dlen,
64 const unsigned char *src, int slen )
75 switch( (slen << 3) - (n * 6) )
77 case 2: n += 3; break;
78 case 4: n += 2; break;
85 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
90 for( i = 0, p = dst; i < n; i += 3 )
96 *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
97 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
98 *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
99 *p++ = base64_enc_map[C3 & 0x3F];
105 C2 = ((i + 1) < slen) ? *src++ : 0;
107 *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
108 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
111 *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
124 * Decode a base64-formatted buffer
126 int base64_decode( unsigned char *dst, int *dlen,
127 const unsigned char *src, int slen )
133 for( i = j = n = 0; i < slen; i++ )
135 unsigned char c = src[i];
137 if( ( slen - i ) >= 2 &&
138 c == '\r' && src[i + 1] == '\n' )
141 if( c == '\n' || c == ' ' || c == '\t' )
144 if( c == '=' && ++j > 2 )
145 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
147 if( c > 127 || base64_dec_map[src[i]] == 127 )
148 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
150 if( base64_dec_map[c] < 64 && j != 0 )
151 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
159 n = ((n * 6) + 7) >> 3;
164 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
167 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
169 unsigned char c = *src;
171 if( c == '\r' || c == '\n' || c == ' ' || c == '\t' )
174 j -= ( base64_dec_map[c] == 64 );
175 x = (x << 6) | ( base64_dec_map[c] & 0x3F );
180 if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
181 if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
182 if( j > 2 ) *p++ = (unsigned char)( x );
191 #if defined(POLARSSL_SELF_TEST)
196 static const unsigned char base64_test_dec[64] =
198 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
199 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
200 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
201 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
202 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
203 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
204 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
205 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
208 static const unsigned char base64_test_enc[] =
209 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
210 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
215 int base64_self_test( int verbose )
218 unsigned char *src, buffer[128];
221 printf( " Base64 encoding test: " );
223 len = sizeof( buffer );
224 src = (unsigned char *) base64_test_dec;
226 if( base64_encode( buffer, &len, src, 64 ) != 0 ||
227 memcmp( base64_test_enc, buffer, 88 ) != 0 )
230 printf( "failed\n" );
236 printf( "passed\n Base64 decoding test: " );
238 len = sizeof( buffer );
239 src = (unsigned char *) base64_test_enc;
241 if( base64_decode( buffer, &len, src, 88 ) != 0 ||
242 memcmp( base64_test_dec, buffer, 64 ) != 0 )
245 printf( "failed\n" );
251 printf( "passed\n\n" );