fuck! don't perform ssl handshake for blocked hosts!
[mediator.git] / src / libpolarssl / base64.c
blobac922a4744ec12e400f3554ee0e9d6fc989eaca2
1 /*
2 * RFC 1521 base64 encoding/decoding
4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
6 * This file is part of mbed TLS (https://tls.mbed.org)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #if !defined(POLARSSL_CONFIG_FILE)
24 #include "polarssl/config.h"
25 #else
26 #include POLARSSL_CONFIG_FILE
27 #endif
29 #if defined(POLARSSL_BASE64_C)
31 #include "polarssl/base64.h"
33 #if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
34 #include <basetsd.h>
35 typedef UINT32 uint32_t;
36 #else
37 #include <inttypes.h>
38 #endif
40 #if defined(POLARSSL_SELF_TEST)
41 #include <string.h>
42 #if defined(POLARSSL_PLATFORM_C)
43 #include "polarssl/platform.h"
44 #else
45 #include <stdio.h>
46 #define polarssl_printf printf
47 #endif /* POLARSSL_PLATFORM_C */
48 #endif /* POLARSSL_SELF_TEST */
50 static const unsigned char base64_enc_map[64] =
52 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
53 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
54 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
55 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
56 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
57 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
58 '8', '9', '+', '/'
61 static const unsigned char base64_dec_map[128] =
63 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
64 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
65 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
66 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
67 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
68 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
69 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
70 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
71 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
72 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
73 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
74 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
75 49, 50, 51, 127, 127, 127, 127, 127
79 * Encode a buffer into base64 format
81 int base64_encode( unsigned char *dst, size_t *dlen,
82 const unsigned char *src, size_t slen )
84 size_t i, n;
85 int C1, C2, C3;
86 unsigned char *p;
88 if( slen == 0 )
90 *dlen = 0;
91 return( 0 );
94 n = ( slen << 3 ) / 6;
96 switch( ( slen << 3 ) - ( n * 6 ) )
98 case 2: n += 3; break;
99 case 4: n += 2; break;
100 default: break;
103 if( *dlen < n + 1 )
105 *dlen = n + 1;
106 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
109 n = ( slen / 3 ) * 3;
111 for( i = 0, p = dst; i < n; i += 3 )
113 C1 = *src++;
114 C2 = *src++;
115 C3 = *src++;
117 *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
118 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
119 *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
120 *p++ = base64_enc_map[C3 & 0x3F];
123 if( i < slen )
125 C1 = *src++;
126 C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
128 *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
129 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
131 if( ( i + 1 ) < slen )
132 *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
133 else *p++ = '=';
135 *p++ = '=';
138 *dlen = p - dst;
139 *p = 0;
141 return( 0 );
145 * Decode a base64-formatted buffer
147 int base64_decode( unsigned char *dst, size_t *dlen,
148 const unsigned char *src, size_t slen )
150 size_t i, n;
151 uint32_t j, x;
152 unsigned char *p;
154 /* First pass: check for validity and get output length */
155 for( i = n = j = 0; i < slen; i++ )
157 /* Skip spaces before checking for EOL */
158 x = 0;
159 while( i < slen && src[i] == ' ' )
161 ++i;
162 ++x;
165 /* Spaces at end of buffer are OK */
166 if( i == slen )
167 break;
169 if( ( slen - i ) >= 2 &&
170 src[i] == '\r' && src[i + 1] == '\n' )
171 continue;
173 if( src[i] == '\n' )
174 continue;
176 /* Space inside a line is an error */
177 if( x != 0 )
178 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
180 if( src[i] == '=' && ++j > 2 )
181 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
183 if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
184 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
186 if( base64_dec_map[src[i]] < 64 && j != 0 )
187 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
189 n++;
192 if( n == 0 )
193 return( 0 );
195 n = ( ( n * 6 ) + 7 ) >> 3;
196 n -= j;
198 if( dst == NULL || *dlen < n )
200 *dlen = n;
201 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
204 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
206 if( *src == '\r' || *src == '\n' || *src == ' ' )
207 continue;
209 j -= ( base64_dec_map[*src] == 64 );
210 x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
212 if( ++n == 4 )
214 n = 0;
215 if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
216 if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
217 if( j > 2 ) *p++ = (unsigned char)( x );
221 *dlen = p - dst;
223 return( 0 );
226 #if defined(POLARSSL_SELF_TEST)
228 static const unsigned char base64_test_dec[64] =
230 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
231 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
232 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
233 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
234 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
235 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
236 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
237 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
240 static const unsigned char base64_test_enc[] =
241 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
242 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
245 * Checkup routine
247 int base64_self_test( int verbose )
249 size_t len;
250 const unsigned char *src;
251 unsigned char buffer[128];
253 if( verbose != 0 )
254 polarssl_printf( " Base64 encoding test: " );
256 len = sizeof( buffer );
257 src = base64_test_dec;
259 if( base64_encode( buffer, &len, src, 64 ) != 0 ||
260 memcmp( base64_test_enc, buffer, 88 ) != 0 )
262 if( verbose != 0 )
263 polarssl_printf( "failed\n" );
265 return( 1 );
268 if( verbose != 0 )
269 polarssl_printf( "passed\n Base64 decoding test: " );
271 len = sizeof( buffer );
272 src = base64_test_enc;
274 if( base64_decode( buffer, &len, src, 88 ) != 0 ||
275 memcmp( base64_test_dec, buffer, 64 ) != 0 )
277 if( verbose != 0 )
278 polarssl_printf( "failed\n" );
280 return( 1 );
283 if( verbose != 0 )
284 polarssl_printf( "passed\n\n" );
286 return( 0 );
289 #endif /* POLARSSL_SELF_TEST */
291 #endif /* POLARSSL_BASE64_C */