Merge server-side enforced renegotiation requests
diff --git a/ChangeLog b/ChangeLog
index 3f5cf88..070e55e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -61,6 +61,8 @@
      exchange that caused some handshakes to fail with other implementations.
      (Failure rate <= 1/255 with common DHM moduli.)
    * Disable broken Sparc64 bn_mul assembly (found by Florian Obser).
+   * Fix base64_decode() to return and check length correctly (in case of
+     tight buffers)
 
 = PolarSSL 1.3.7 released on 2014-05-02
 Features
diff --git a/library/base64.c b/library/base64.c
index 5b1418b..39a8323 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -172,6 +172,7 @@
         return( 0 );
 
     n = ( ( n * 6 ) + 7 ) >> 3;
+    n -= j;
 
     if( dst == NULL || *dlen < n )
     {
diff --git a/tests/suites/test_suite_base64.data b/tests/suites/test_suite_base64.data
index c400ccb..4508d89 100644
--- a/tests/suites/test_suite_base64.data
+++ b/tests/suites/test_suite_base64.data
@@ -55,6 +55,33 @@
 Base64 decode (Invalid char after equal signs)
 base64_decode:"zm=masd":"":POLARSSL_ERR_BASE64_INVALID_CHARACTER
 
+Base64 encode hex #1
+base64_encode_hex:"010203040506070809":"AQIDBAUGBwgJ":13:0
+
+Base64 encode hex #2 (buffer too small)
+base64_encode_hex:"010203040506070809":"AQIDBAUGBwgJ":12:POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL
+
+Base64 encode hex #3
+base64_encode_hex:"0102030405060708":"AQIDBAUGBwg=":13:0
+
+Base64 encode hex #4
+base64_encode_hex:"01020304050607":"AQIDBAUGBw==":13:0
+
+Base64 decode hex #1
+base64_decode_hex:"AQIDBAUGBwgJ":"010203040506070809":9:0
+
+Base64 decode hex #2 (buffer too small)
+base64_decode_hex:"AQIDBAUGBwgJ":"010203040506070809":8:POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL
+
+Base64 decode hex #3
+base64_decode_hex:"AQIDBAUGBwg=":"0102030405060708":8:0
+
+Base64 decode hex #4
+base64_decode_hex:"AQIDBAUGBw==":"01020304050607":7:0
+
+Base64 decode hex #5 (buffer too small)
+base64_decode_hex:"AQIDBAUGBw==":"01020304050607":6:POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL
+
 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 3ba59dc..a9a580c 100644
--- a/tests/suites/test_suite_base64.function
+++ b/tests/suites/test_suite_base64.function
@@ -48,6 +48,45 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void base64_encode_hex( char *src_hex, char *dst, int dst_buf_size,
+                        int result )
+{
+    unsigned char *src, *res;
+    size_t len = dst_buf_size, src_len;
+
+    src = unhexify_alloc( src_hex, &src_len );
+    res = zero_alloc( dst_buf_size );
+
+    TEST_ASSERT( base64_encode( res, &len, src, src_len ) == result );
+    if( result == 0 )
+    {
+        TEST_ASSERT( len == strlen( dst ) );
+        TEST_ASSERT( memcmp( dst, res, len ) == 0 );
+    }
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void base64_decode_hex( char *src, char *dst_hex, int dst_buf_size,
+                        int result )
+{
+    unsigned char *dst, *res;
+    size_t len = dst_buf_size, dst_len;
+
+    dst = unhexify_alloc( dst_hex, &dst_len );
+    res = zero_alloc( dst_buf_size );
+
+    TEST_ASSERT( base64_decode( res, &len, (unsigned char *) src,
+                                strlen( src ) ) == result );
+    if( result == 0 )
+    {
+        TEST_ASSERT( len == dst_len );
+        TEST_ASSERT( memcmp( dst, res, len ) == 0 );
+    }
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:POLARSSL_SELF_TEST */
 void base64_selftest()
 {