From 64938c63f0f15d530655311ac969b3d73de51c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 15 Oct 2014 21:45:39 +0200 Subject: [PATCH] Accept spaces at end of line/buffer in base64 --- ChangeLog | 1 + library/base64.c | 19 ++++++- tests/data_files/server7_all_space.crt | 4 +- tests/data_files/server7_pem_space.crt | 2 +- tests/suites/test_suite_base64.data | 73 +++++++++++++++++++++++++ tests/suites/test_suite_base64.function | 24 +++++++- 6 files changed, 118 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6244af3a1..8e74c0b6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,6 +35,7 @@ Changes POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE on harmless alerts. * POLARSSL_MPI_MAX_SIZE now defaults to 1024 in order to allow 8192 bits RSA keys. + * Accept spaces at end of line or end of buffer in base64_decode(). = PolarSSL 1.3.8 released 2014-07-11 Security diff --git a/library/base64.c b/library/base64.c index 39a8323e8..e6c3569b8 100644 --- a/library/base64.c +++ b/library/base64.c @@ -147,8 +147,21 @@ int base64_decode( unsigned char *dst, size_t *dlen, uint32_t j, x; unsigned char *p; + /* First pass: check for validity and get output length */ for( i = n = j = 0; i < slen; i++ ) { + /* Skip spaces before checking for EOL */ + x = 0; + while( i < slen && src[i] == ' ' ) + { + ++i; + ++x; + } + + /* Spaces at end of buffer are OK */ + if( i == slen ) + break; + if( ( slen - i ) >= 2 && src[i] == '\r' && src[i + 1] == '\n' ) continue; @@ -156,6 +169,10 @@ int base64_decode( unsigned char *dst, size_t *dlen, if( src[i] == '\n' ) continue; + /* Space inside a line is an error */ + if( x != 0 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + if( src[i] == '=' && ++j > 2 ) return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); @@ -182,7 +199,7 @@ int base64_decode( unsigned char *dst, size_t *dlen, for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) { - if( *src == '\r' || *src == '\n' ) + if( *src == '\r' || *src == '\n' || *src == ' ' ) continue; j -= ( base64_dec_map[*src] == 64 ); diff --git a/tests/data_files/server7_all_space.crt b/tests/data_files/server7_all_space.crt index 12b5e0539..a979830ba 100644 --- a/tests/data_files/server7_all_space.crt +++ b/tests/data_files/server7_all_space.crt @@ -1,7 +1,7 @@ -----BEGIN CERTIFICATE----- MIIDwjCCAaqgAwIBAgIBEDANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJOTDER MA8GA1UEChMIUG9sYXJTU0wxJjAkBgNVBAMTHVBvbGFyU1NMIFRlc3QgSW50ZXJt -ZWRpYXRlIENBMB4XDTEzMDkyNDE2MTIyNFoXDTIzMDkyMjE2MTIyNFowNDELMAkG +ZWRpYXRlIENBMB4XDTEzMDkyNDE2MTIyNFoXDTIzMDkyMjE2MTIyNFowNDELMAk G A1UEBhMCTkwxETAPBgNVBAoTCFBvbGFyU1NMMRIwEAYDVQQDEwlsb2NhbGhvc3Qw WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQcbffp2qXqoZyychmoCRxzrd4Vu96m 47NPBehtEC46aTeXgDnBdf++znABrAtfXBRNQz8ARIeYBmskr22rlKjyo4GVMIGS @@ -37,7 +37,7 @@ uCfGGTWQ6me7Bjan3t0NzoTdDq6IpKTesbaY+/9e2xn8DCrhBKLXQMZFDZqUoLYA kGPOEGgvlPnIIXAawouxCaNYEh5Uw871YMSPT28rLdFr49dwYOtDg9foA8hDIW2P d6KXbrZteesvA1nYzEOs+3AjrbT79Md2W8Bz9bqBVNlNOESSqm4kiCJFmslm/6br Np0MSQd+o22PQ4xRtmP6UsTfU0ueiMpYc8TYYhMbfnfFyo4m707ebcflPbBEN2dg -updQ66cvfCJB0QJt9upafY0lpdV1qUkCAwEAAaOBoDCBnTAdBgNVHQ4EFgQUOHfY +updQ66cvfCJB0QJt9upafY0lpdV1qUkCAwEAAaOBoDCBnTAdBgNVHQ4EFgQUOHf Y a3ecKHeCi07YG6ke95QWtw4wbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7 NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w diff --git a/tests/data_files/server7_pem_space.crt b/tests/data_files/server7_pem_space.crt index e28e0e7f9..0ef0fc7bd 100644 --- a/tests/data_files/server7_pem_space.crt +++ b/tests/data_files/server7_pem_space.crt @@ -1,7 +1,7 @@ -----BEGIN CERTIFICATE----- MIIDwjCCAaqgAwIBAgIBEDANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJOTDER MA8GA1UEChMIUG9sYXJTU0wxJjAkBgNVBAMTHVBvbGFyU1NMIFRlc3QgSW50ZXJt -ZWRpYXRlIENBMB4XDTEzMDkyNDE2MTIyNFoXDTIzMDkyMjE2MTIyNFowNDELMAkG +ZWRpYXRlIENBMB4XDTEzMDkyNDE2MTIyNFoXDTIzMDkyMjE2MTIyNFowNDELMAk G A1UEBhMCTkwxETAPBgNVBAoTCFBvbGFyU1NMMRIwEAYDVQQDEwlsb2NhbGhvc3Qw WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQcbffp2qXqoZyychmoCRxzrd4Vu96m 47NPBehtEC46aTeXgDnBdf++znABrAtfXBRNQz8ARIeYBmskr22rlKjyo4GVMIGS diff --git a/tests/suites/test_suite_base64.data b/tests/suites/test_suite_base64.data index 4508d892b..117adc585 100644 --- a/tests/suites/test_suite_base64.data +++ b/tests/suites/test_suite_base64.data @@ -55,6 +55,78 @@ base64_decode:"zm===":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER Base64 decode (Invalid char after equal signs) base64_decode:"zm=masd":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER +Base64 decode (Space inside string) +base64_decode:"zm masd":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER + +Base64 decode "Zm9vYmFy" (no newline nor '\0' at end) +base64_decode_hex_src:"5a6d3976596d4679":"foobar":0 + +Base64 decode "Zm9vYmFy\n" (LF at end) +base64_decode_hex_src:"5a6d3976596d46790a":"foobar":0 + +Base64 decode "Zm9vYmFy\r\n" (CRLF at end) +base64_decode_hex_src:"5a6d3976596d46790d0a":"foobar":0 + +Base64 decode "Zm9vYmFy\r" (CR at end) +base64_decode_hex_src:"5a6d3976596d46790d":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER + +Base64 decode "Zm9vYmFy " (SP at end) +base64_decode_hex_src:"5a6d3976596d467920":"foobar":0 + +Base64 decode "Zm9vYmFy \n" (SP+LF at end) +base64_decode_hex_src:"5a6d3976596d4679200a":"foobar":0 + +Base64 decode "Zm9vYmFy \r\n" (SP+CRLF at end) +base64_decode_hex_src:"5a6d3976596d4679200d0a":"foobar":0 + +Base64 decode "Zm9vYmFy \r" (SP+CR at end) +base64_decode_hex_src:"5a6d3976596d4679200d":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER + +Base64 decode "Zm9vYmFy " (2SP at end) +base64_decode_hex_src:"5a6d3976596d46792020":"foobar":0 + +Base64 decode "Zm9vYmFy \n" (2SP+LF at end) +base64_decode_hex_src:"5a6d3976596d467920200a":"foobar":0 + +Base64 decode "Zm9vYmFy \r\n" (2SP+CRLF at end) +base64_decode_hex_src:"5a6d3976596d467920200d0a":"foobar":0 + +Base64 decode "Zm9vYmFy \r" (2SP+CR at end) +base64_decode_hex_src:"5a6d3976596d467920200d":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER + +Base64 decode "Zm9vYmF\ny" (LF inside) +base64_decode_hex_src:"5a6d3976596d460a79":"foobar":0 + +Base64 decode "Zm9vYmF\ry" (CRLF inside) +base64_decode_hex_src:"5a6d3976596d460d0a79":"foobar":0 + +Base64 decode "Zm9vYmF\ry" (CR inside) +base64_decode_hex_src:"5a6d3976596d460d79":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER + +Base64 decode "Zm9vYmF y" (SP inside) +base64_decode_hex_src:"5a6d3976596d462079":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER + +Base64 decode "Zm9vYmF \ny" (SP+LF inside) +base64_decode_hex_src:"5a6d3976596d46200a79":"foobar":0 + +Base64 decode "Zm9vYmF \ry" (SP+CRLF inside) +base64_decode_hex_src:"5a6d3976596d46200d0a79":"foobar":0 + +Base64 decode "Zm9vYmF \ry" (SP+CR inside) +base64_decode_hex_src:"5a6d3976596d46200d79":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER + +Base64 decode "Zm9vYmF y" (2SP inside) +base64_decode_hex_src:"5a6d3976596d46202079":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER + +Base64 decode "Zm9vYmF \ny" (2SP+LF inside) +base64_decode_hex_src:"5a6d3976596d4620200a79":"foobar":0 + +Base64 decode "Zm9vYmF \ry" (2SP+CRLF inside) +base64_decode_hex_src:"5a6d3976596d4620200d0a79":"foobar":0 + +Base64 decode "Zm9vYmF \ry" (2SP+CR inside) +base64_decode_hex_src:"5a6d3976596d4620200d79":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER + Base64 encode hex #1 base64_encode_hex:"010203040506070809":"AQIDBAUGBwgJ":13:0 @@ -85,3 +157,4 @@ base64_decode_hex:"AQIDBAUGBw==":"01020304050607":6:POLARSSL_ERR_BASE64_BUFFER_T Base64 Selftest depends_on:POLARSSL_SELF_TEST base64_selftest: + diff --git a/tests/suites/test_suite_base64.function b/tests/suites/test_suite_base64.function index de39df685..01d8aa6f9 100644 --- a/tests/suites/test_suite_base64.function +++ b/tests/suites/test_suite_base64.function @@ -33,7 +33,7 @@ void base64_decode( char *src_string, char *dst_string, int result ) unsigned char src_str[1000]; unsigned char dst_str[1000]; size_t len = 1000; - int res; + int res; memset(src_str, 0x00, 1000); memset(dst_str, 0x00, 1000); @@ -95,6 +95,28 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void base64_decode_hex_src( char *src_hex, char *dst_ref, int result ) +{ + unsigned char dst[1000] = { 0 }; + unsigned char *src; + size_t src_len, len; + + src = unhexify_alloc( src_hex, &src_len ); + + len = sizeof( dst ); + TEST_ASSERT( base64_decode( dst, &len, src, src_len ) == result ); + if( result == 0 ) + { + TEST_ASSERT( len == strlen( dst_ref ) ); + TEST_ASSERT( memcmp( dst, dst_ref, len ) == 0 ); + } + +exit: + polarssl_free( src ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:POLARSSL_SELF_TEST */ void base64_selftest() {