Merge pull request #3127 from piotr-now/ssl_base64_dump

Add program for deserializing from base64 code
diff --git a/programs/.gitignore b/programs/.gitignore
index d19162d..b2685a9 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -40,6 +40,7 @@
 ssl/dtls_server
 ssl/ssl_client1
 ssl/ssl_client2
+ssl/ssl_context_info
 ssl/ssl_fork_server
 ssl/ssl_mail_client
 ssl/ssl_pthread_server
diff --git a/programs/Makefile b/programs/Makefile
index deb19b6..68bcfc2 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -84,6 +84,7 @@
 	ssl/ssl_client2$(EXEXT) \
 	ssl/ssl_server$(EXEXT) \
 	ssl/ssl_server2$(EXEXT) \
+	ssl/ssl_context_info$(EXEXT) \
 	ssl/ssl_fork_server$(EXEXT) \
 	ssl/mini_client$(EXEXT) \
 	ssl/ssl_mail_client$(EXEXT) \
@@ -282,6 +283,10 @@
 	echo "  CC    ssl/ssl_server2.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server2.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+ssl/ssl_context_info$(EXEXT): ssl/ssl_context_info.c test/query_config.c $(DEP)
+	echo "  CC    ssl/ssl_context_info.c"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_context_info.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 ssl/ssl_fork_server$(EXEXT): ssl/ssl_fork_server.c $(DEP)
 	echo "  CC    ssl/ssl_fork_server.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_fork_server.c   $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/programs/ssl/CMakeLists.txt b/programs/ssl/CMakeLists.txt
index f28a47d..481e2b0 100644
--- a/programs/ssl/CMakeLists.txt
+++ b/programs/ssl/CMakeLists.txt
@@ -44,6 +44,9 @@
 target_sources(ssl_server2 PUBLIC ../test/query_config.c)
 target_link_libraries(ssl_server2 ${libs})
 
+add_executable(ssl_context_info ssl_context_info.c)
+target_link_libraries(ssl_context_info ${libs})
+
 add_executable(ssl_fork_server ssl_fork_server.c)
 target_link_libraries(ssl_fork_server ${libs})
 
diff --git a/programs/ssl/ssl_context_info.c b/programs/ssl/ssl_context_info.c
new file mode 100644
index 0000000..9bea31c
--- /dev/null
+++ b/programs/ssl/ssl_context_info.c
@@ -0,0 +1,1112 @@
+/*
+ *  MbedTLS SSL context deserializer from base64 code
+ *
+ *  Copyright (C) 2006-2020, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_ERROR_C)
+int main( void )
+{
+    printf("MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_ERROR_C not defined.\n");
+    return( 0 );
+}
+#else
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include "mbedtls/ssl.h"
+#include "mbedtls/error.h"
+#include "mbedtls/base64.h"
+#include "mbedtls/md.h"
+#include "mbedtls/md_internal.h"
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/ssl_ciphersuites.h"
+
+/*
+ * This program version
+ */
+#define PROG_NAME "ssl_context_info"
+#define VER_MAJOR 0
+#define VER_MINOR 1
+
+/*
+ * Flags copied from the Mbed TLS library.
+ */
+#define SESSION_CONFIG_TIME_BIT          ( 1 << 0 )
+#define SESSION_CONFIG_CRT_BIT           ( 1 << 1 )
+#define SESSION_CONFIG_CLIENT_TICKET_BIT ( 1 << 2 )
+#define SESSION_CONFIG_MFL_BIT           ( 1 << 3 )
+#define SESSION_CONFIG_TRUNC_HMAC_BIT    ( 1 << 4 )
+#define SESSION_CONFIG_ETM_BIT           ( 1 << 5 )
+#define SESSION_CONFIG_TICKET_BIT        ( 1 << 6 )
+
+#define CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT    ( 1 << 0 )
+#define CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT     ( 1 << 1 )
+#define CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT      ( 1 << 2 )
+#define CONTEXT_CONFIG_ALPN_BIT                  ( 1 << 3 )
+
+#define TRANSFORM_RANDBYTE_LEN  64
+
+/*
+ * Minimum and maximum number of bytes for specific data: context, sessions,
+ * certificates, tickets and buffers in the program. The context and session
+ * size values have been calculated based on the 'print_deserialized_ssl_context()'
+ * and 'print_deserialized_ssl_session()' content.
+ */
+#define MIN_CONTEXT_LEN     84
+#define MIN_SESSION_LEN     88
+
+#define MAX_CONTEXT_LEN     875     /* without session data */
+#define MAX_SESSION_LEN     109     /* without certificate and ticket data */
+#define MAX_CERTIFICATE_LEN ( ( 1 << 24 ) - 1 )
+#define MAX_TICKET_LEN      ( ( 1 << 24 ) - 1 )
+
+#define MIN_SERIALIZED_DATA ( MIN_CONTEXT_LEN + MIN_SESSION_LEN )
+#define MAX_SERIALIZED_DATA ( MAX_CONTEXT_LEN + MAX_SESSION_LEN + \
+                              MAX_CERTIFICATE_LEN + MAX_TICKET_LEN )
+
+#define MIN_BASE64_LEN      ( MIN_SERIALIZED_DATA * 4 / 3 )
+#define MAX_BASE64_LEN      ( MAX_SERIALIZED_DATA * 4 / 3 + 3 )
+
+/*
+ * A macro that prevents from reading out of the ssl buffer range.
+ */
+#define CHECK_SSL_END( LEN )            \
+do                                      \
+{                                       \
+    if( end - ssl < (int)( LEN ) )      \
+    {                                   \
+        printf_err( "%s", buf_ln_err ); \
+        return;                         \
+    }                                   \
+} while( 0 )
+
+/*
+ * Global values
+ */
+FILE *b64_file = NULL;                  /* file with base64 codes to deserialize */
+char conf_keep_peer_certificate = 1;    /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE from mbedTLS configuration */
+char conf_dtls_proto = 1;               /* MBEDTLS_SSL_PROTO_DTLS from mbedTLS configuration */
+char debug = 0;                         /* flag for debug messages */
+const char alloc_err[] = "Cannot allocate memory\n";
+const char buf_ln_err[] = "Buffer does not have enough data to complete the parsing\n";
+
+/*
+ * Basic printing functions
+ */
+void print_version( )
+{
+    printf( "%s v%d.%d\n", PROG_NAME, VER_MAJOR, VER_MINOR );
+}
+
+void print_usage( )
+{
+    print_version();
+    printf( "\nThis program is used to deserialize an Mbed TLS SSL session from the base64 code provided\n"
+            "in the text file. The program can deserialize many codes from one file, but they must be\n"
+            "separated, e.g. by a newline.\n\n" );
+    printf(
+        "Usage:\n"
+        "\t-f path            - Path to the file with base64 code\n"
+        "\t-v                 - Show version\n"
+        "\t-h                 - Show this usage\n"
+        "\t-d                 - Print more information\n"
+        "\t--keep-peer-cert=0 - Use this option if you know that the Mbed TLS library\n"
+        "\t                     has been compiled with the MBEDTLS_SSL_KEEP_PEER_CERTIFICATE\n"
+        "\t                     flag. You can also use it if there are some problems with reading\n"
+        "\t                     the information about certificate\n"
+        "\t--dtls-protocol=0  - Use this option if you know that the Mbed TLS library\n"
+        "\t                     has been compiled without the MBEDTLS_SSL_PROTO_DTLS flag\n"
+        "\n"
+    );
+}
+
+void printf_dbg( const char *str, ... )
+{
+    if( debug )
+    {
+        va_list args;
+        va_start( args, str );
+        printf( "debug: " );
+        vprintf( str, args );
+        fflush( stdout );
+        va_end( args );
+    }
+}
+
+void printf_err( const char *str, ... )
+{
+    va_list args;
+    va_start( args, str );
+    fflush( stdout );
+    fprintf( stderr, "ERROR: " );
+    vfprintf( stderr, str, args );
+    fflush( stderr );
+    va_end( args );
+}
+
+/*
+ * Exit from the program in case of error
+ */
+void error_exit()
+{
+    if( NULL != b64_file )
+    {
+        fclose( b64_file );
+    }
+    exit( -1 );
+}
+
+/*
+ * This function takes the input arguments of this program
+ */
+void parse_arguments( int argc, char *argv[] )
+{
+    int i = 1;
+
+    if( argc < 2 )
+    {
+        print_usage();
+        error_exit();
+    }
+
+    while( i < argc )
+    {
+        if( strcmp( argv[i], "-d" ) == 0 )
+        {
+            debug = 1;
+        }
+        else if( strcmp( argv[i], "-h" ) == 0 )
+        {
+            print_usage();
+        }
+        else if( strcmp( argv[i], "-v" ) == 0 )
+        {
+            print_version();
+        }
+        else if( strcmp( argv[i], "-f" ) == 0 )
+        {
+            if( ++i >= argc )
+            {
+                printf_err( "File path is empty\n" );
+                error_exit();
+            }
+
+            if( ( b64_file = fopen( argv[i], "r" ) ) == NULL )
+            {
+                printf_err( "Cannot find file \"%s\"\n", argv[i] );
+                error_exit();
+            }
+        }
+        else if( strcmp( argv[i], "--keep-peer-cert=0" ) == 0 )
+        {
+            conf_keep_peer_certificate = 0;
+        }
+        else if( strcmp( argv[i], "--dtls-protocol=0" ) == 0 )
+        {
+            conf_dtls_proto = 0;
+        }
+        else
+        {
+            print_usage();
+            error_exit();
+        }
+
+        i++;
+    }
+}
+
+/*
+ * This function prints base64 code to the stdout
+ */
+void print_b64( const uint8_t *b, size_t len )
+{
+    size_t i = 0;
+    const uint8_t *end = b + len;
+    printf("\t");
+    while( b < end )
+    {
+        if( ++i > 75 )
+        {
+            printf( "\n\t" );
+            i = 0;
+        }
+        printf( "%c", *b++ );
+    }
+    printf( "\n" );
+    fflush( stdout );
+}
+
+/*
+ * This function prints hex code from the buffer to the stdout.
+ *
+ * /p b         buffer with data to print
+ * /p len       number of bytes to print
+ * /p in_line   number of bytes in one line
+ * /p prefix    prefix for the new lines
+ */
+void print_hex( const uint8_t *b, size_t len,
+                const size_t in_line, const char *prefix )
+{
+    size_t i = 0;
+    const uint8_t *end = b + len;
+
+    if( prefix == NULL )
+    {
+        prefix = "";
+    }
+
+    while( b < end )
+    {
+        if( ++i > in_line )
+        {
+            printf( "\n%s", prefix );
+            i = 1;
+        }
+        printf( "%02X ", (uint8_t) *b++ );
+    }
+    printf("\n");
+    fflush(stdout);
+}
+
+/*
+ *  Print the value of time_t in format e.g. 2020-01-23 13:05:59
+ */
+void print_time( const time_t *time )
+{
+    char buf[20];
+    struct tm *t = gmtime( time );
+    static const char format[] = "%Y-%m-%d %H:%M:%S";
+    if( NULL != t )
+    {
+        strftime( buf, sizeof( buf ), format, t );
+        printf( "%s\n", buf );
+    }
+    else
+    {
+        printf( "unknown\n" );
+    }
+}
+
+/*
+ * Print the input string if the bit is set in the value
+ */
+void print_if_bit( const char *str, int bit, int val )
+{
+    if( bit & val )
+    {
+        printf( "\t%s\n", str );
+    }
+}
+
+/*
+ * Return pointer to hardcoded "enabled" or "disabled" depending on the input value
+ */
+const char * get_enabled_str( int is_en )
+{
+    return ( is_en ) ? "enabled" : "disabled";
+}
+
+/*
+ * Return pointer to hardcoded MFL string value depending on the MFL code at the input
+ */
+const char * get_mfl_str( int mfl_code )
+{
+    switch( mfl_code )
+    {
+        case MBEDTLS_SSL_MAX_FRAG_LEN_NONE:
+            return "none";
+        case MBEDTLS_SSL_MAX_FRAG_LEN_512:
+            return "512";
+        case MBEDTLS_SSL_MAX_FRAG_LEN_1024:
+            return "1024";
+        case MBEDTLS_SSL_MAX_FRAG_LEN_2048:
+            return "2048";
+        case MBEDTLS_SSL_MAX_FRAG_LEN_4096:
+            return "4096";
+        default:
+            return "error";
+    }
+}
+
+/*
+ * Read next base64 code from the 'b64_file'. The 'b64_file' must be opened
+ * previously. After each call to this function, the internal file position
+ * indicator of the global b64_file is advanced.
+ *
+ * Note - This function checks the size of the input buffer and if necessary,
+ *        increases it to the maximum MAX_BASE64_LEN
+ *
+ * /p b64       pointer to the pointer of the buffer for input data
+ * /p max_len   pointer to the current buffer capacity. It can be changed if
+ *              the buffer needs to be increased
+ *
+ * \retval      number of bytes written in to the b64 buffer or 0 in case no more
+ *              data was found
+ */
+size_t read_next_b64_code( uint8_t **b64, size_t *max_len )
+{
+    int valid_balance = 0;  /* balance between valid and invalid characters */
+    size_t len = 0;
+    char pad = 0;
+    char c = 0;
+
+    while( EOF != c )
+    {
+        char c_valid = 0;
+
+        c = (char) fgetc( b64_file );
+
+        if( pad > 0 )
+        {
+            if( c == '=' && pad == 1 )
+            {
+                c_valid = 1;
+                pad = 2;
+            }
+        }
+        else if( ( c >= 'A' && c <= 'Z' ) ||
+                 ( c >= 'a' && c <= 'z' ) ||
+                 ( c >= '0' && c <= '9' ) ||
+                   c == '+' || c == '/' )
+        {
+            c_valid = 1;
+        }
+        else if( c == '=' )
+        {
+            c_valid = 1;
+            pad = 1;
+        }
+        else if( c == '-' )
+        {
+            c = '+';
+            c_valid = 1;
+        }
+        else if( c == '_' )
+        {
+            c = '/';
+            c_valid = 1;
+        }
+
+        if( c_valid )
+        {
+            /* A string of characters that could be a base64 code. */
+            valid_balance++;
+
+            if( len < *max_len )
+            {
+                ( *b64 )[ len++ ] = c;
+            }
+            else if( *max_len < MAX_BASE64_LEN )
+            {
+                /* Current buffer is too small, but can be resized. */
+                void *ptr;
+                size_t new_size = ( MAX_BASE64_LEN - 4096 > *max_len ) ?
+                                  *max_len + 4096 : MAX_BASE64_LEN;
+
+                ptr = realloc( *b64, new_size );
+                if( NULL == ptr )
+                {
+                    printf_err( alloc_err );
+                    return 0;
+                }
+                *b64 = ptr;
+                *max_len = new_size;
+                ( *b64 )[ len++ ] = c;
+            }
+            else
+            {
+                /* Too much data so it will be treated as invalid */
+                len++;
+            }
+        }
+        else if( len > 0 )
+        {
+            /* End of a string that could be a base64 code, but need to check
+             * that the length of the characters is correct. */
+
+            valid_balance--;
+
+            if( len < MIN_CONTEXT_LEN )
+            {
+                printf_dbg( "The code found is too small to be a SSL context.\n" );
+                len = pad = 0;
+            }
+            else if( len > *max_len )
+            {
+                printf_err( "The code found is too large by %u bytes.\n", len - *max_len );
+                len = pad = 0;
+            }
+            else if( len % 4 != 0 )
+            {
+                printf_err( "The length of the base64 code found should be a multiple of 4.\n" );
+                len = pad = 0;
+            }
+            else
+            {
+                /* Base64 code with valid character length. */
+                return len;
+            }
+        }
+        else
+        {
+            valid_balance--;
+        }
+
+        /* Detection of potentially wrong file format like: binary, zip, ISO, etc. */
+        if( valid_balance < -100 )
+        {
+            printf_err( "Too many bad symbols detected. File check aborted.\n" );
+            return 0;
+        }
+    }
+
+    printf_dbg( "End of file\n" );
+    return 0;
+}
+
+/*
+ * This function deserializes and prints to the stdout all obtained information
+ * about the certificates from provided data.
+ *
+ * /p ssl   pointer to serialized certificate
+ * /p len   number of bytes in the buffer
+*/
+void print_deserialized_ssl_cert( const uint8_t *ssl, uint32_t len )
+{
+    enum { STRLEN = 4096 };
+    mbedtls_x509_crt crt;
+    int ret;
+    char str[STRLEN];
+
+    printf( "\nCertificate:\n" );
+
+    mbedtls_x509_crt_init( &crt );
+    ret = mbedtls_x509_crt_parse_der( &crt, ssl, len );
+    if( 0 != ret )
+    {
+        mbedtls_strerror( ret, str, STRLEN );
+        printf_err( "Invalid format of X.509 - %s\n", str );
+        printf( "Cannot deserialize:\n\t" );
+        print_hex( ssl, len, 25, "\t" );
+    }
+    else
+    {
+        mbedtls_x509_crt *current = &crt;
+
+        while( current != NULL )
+        {
+            ret = mbedtls_x509_crt_info( str, STRLEN, "\t", current );
+            if( 0 > ret )
+            {
+                mbedtls_strerror( ret, str, STRLEN );
+                printf_err( "Cannot write to the output - %s\n", str );
+            }
+            else
+            {
+                printf( "%s", str );
+            }
+
+            current = current->next;
+
+            if( current )
+            {
+                printf( "\n" );
+            }
+
+        }
+    }
+
+   mbedtls_x509_crt_free( &crt );
+}
+
+/*
+ * This function deserializes and prints to the stdout all obtained information
+ * about the session from provided data. This function was built based on
+ * mbedtls_ssl_session_load(). mbedtls_ssl_session_load() could not be used
+ * due to dependencies on the mbedTLS configuration.
+ *
+ * The data structure in the buffer:
+ *  uint64 start_time;
+ *  uint8 ciphersuite[2];        // defined by the standard
+ *  uint8 compression;           // 0 or 1
+ *  uint8 session_id_len;        // at most 32
+ *  opaque session_id[32];
+ *  opaque master[48];           // fixed length in the standard
+ *  uint32 verify_result;
+ *  opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
+ *  opaque ticket<0..2^24-1>;    // length 0 means no ticket
+ *  uint32 ticket_lifetime;
+ *  uint8 mfl_code;              // up to 255 according to standard
+ *  uint8 trunc_hmac;            // 0 or 1
+ *  uint8 encrypt_then_mac;      // 0 or 1
+ *
+ * /p ssl               pointer to serialized session
+ * /p len               number of bytes in the buffer
+ * /p session_cfg_flag  session configuration flags
+ */
+void print_deserialized_ssl_session( const uint8_t *ssl, uint32_t len,
+                                     int session_cfg_flag )
+{
+    const struct mbedtls_ssl_ciphersuite_t * ciphersuite_info;
+    int ciphersuite_id;
+    uint32_t cert_len, ticket_len;
+    uint32_t verify_result, ticket_lifetime;
+    const uint8_t *end = ssl + len;
+
+    printf( "\nSession info:\n" );
+
+    if( session_cfg_flag & SESSION_CONFIG_TIME_BIT )
+    {
+        uint64_t start;
+        CHECK_SSL_END( 8 );
+        start = ( (uint64_t) ssl[0] << 56 ) |
+                ( (uint64_t) ssl[1] << 48 ) |
+                ( (uint64_t) ssl[2] << 40 ) |
+                ( (uint64_t) ssl[3] << 32 ) |
+                ( (uint64_t) ssl[4] << 24 ) |
+                ( (uint64_t) ssl[5] << 16 ) |
+                ( (uint64_t) ssl[6] <<  8 ) |
+                ( (uint64_t) ssl[7] );
+        ssl += 8;
+        printf( "\tstart time     : " );
+        print_time( (time_t*) &start );
+    }
+
+    CHECK_SSL_END( 2 );
+    ciphersuite_id = ( (int) ssl[0] << 8 ) | (int) ssl[1];
+    printf_dbg( "Ciphersuite ID: %d\n", ciphersuite_id );
+    ssl += 2;
+
+    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
+    if( ciphersuite_info == NULL )
+    {
+        printf_err( "Cannot find ciphersuite info\n" );
+    }
+    else
+    {
+        const mbedtls_cipher_info_t *cipher_info;
+        const mbedtls_md_info_t *md_info;
+
+        printf( "\tciphersuite    : %s\n", ciphersuite_info->name );
+        printf( "\tcipher flags   : 0x%02X\n", ciphersuite_info->flags );
+
+        cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
+        if( cipher_info == NULL )
+        {
+            printf_err( "Cannot find cipher info\n" );
+        }
+        else
+        {
+            printf( "\tcipher         : %s\n", cipher_info->name );
+        }
+
+        md_info = mbedtls_md_info_from_type( ciphersuite_info->mac );
+        if( md_info == NULL )
+        {
+            printf_err( "Cannot find Message-Digest info\n" );
+        }
+        else
+        {
+            printf( "\tMessage-Digest : %s\n", md_info->name );
+        }
+    }
+
+    CHECK_SSL_END( 1 );
+    printf( "\tcompression    : %s\n", get_enabled_str( *ssl++ ) );
+
+    /* Note - Here we can get session ID length from serialized data, but we
+     * use hardcoded 32-bytes length. This approach was taken from
+     * 'mbedtls_ssl_session_load()'. */
+    CHECK_SSL_END( 1 + 32 );
+    printf_dbg( "Session id length: %u\n", (uint32_t) *ssl++ );
+    printf( "\tsession ID     : ");
+    print_hex( ssl, 32, 16, "\t                 " );
+    ssl += 32;
+
+    printf( "\tmaster secret  : ");
+    CHECK_SSL_END( 48 );
+    print_hex( ssl, 48, 16, "\t                 " );
+    ssl += 48;
+
+    CHECK_SSL_END( 4 );
+    verify_result = ( (uint32_t) ssl[0] << 24 ) |
+                    ( (uint32_t) ssl[1] << 16 ) |
+                    ( (uint32_t) ssl[2] <<  8 ) |
+                    ( (uint32_t) ssl[3] );
+    ssl += 4;
+    printf( "\tverify result  : 0x%08X\n", verify_result );
+
+    if( SESSION_CONFIG_CRT_BIT & session_cfg_flag )
+    {
+        if( conf_keep_peer_certificate )
+        {
+            CHECK_SSL_END( 3 );
+            cert_len = ( (uint32_t) ssl[0] << 16 ) |
+                       ( (uint32_t) ssl[1] <<  8 ) |
+                       ( (uint32_t) ssl[2] );
+            ssl += 3;
+            printf_dbg( "Certificate length: %u\n", cert_len );
+
+            if( cert_len > 0 )
+            {
+                CHECK_SSL_END( cert_len );
+                print_deserialized_ssl_cert( ssl, cert_len );
+                ssl += cert_len;
+            }
+        }
+        else
+        {
+            printf( "\tPeer digest    : " );
+
+            CHECK_SSL_END( 1 );
+            switch( (mbedtls_md_type_t) *ssl++ )
+            {
+                case MBEDTLS_MD_NONE:
+                    printf( "none\n" );
+                    break;
+                case MBEDTLS_MD_MD2:
+                    printf( "MD2\n" );
+                    break;
+                case MBEDTLS_MD_MD4:
+                    printf( "MD4\n" );
+                    break;
+                case MBEDTLS_MD_MD5:
+                    printf( "MD5\n" );
+                    break;
+                case MBEDTLS_MD_SHA1:
+                    printf( "SHA1\n" );
+                    break;
+                case MBEDTLS_MD_SHA224:
+                    printf( "SHA224\n" );
+                    break;
+                case MBEDTLS_MD_SHA256:
+                    printf( "SHA256\n" );
+                    break;
+                case MBEDTLS_MD_SHA384:
+                    printf( "SHA384\n" );
+                    break;
+                case MBEDTLS_MD_SHA512:
+                    printf( "SHA512\n" );
+                    break;
+                case MBEDTLS_MD_RIPEMD160:
+                    printf( "RIPEMD160\n" );
+                    break;
+                default:
+                    printf( "undefined or erroneous\n" );
+                    break;
+            }
+
+            CHECK_SSL_END( 1 );
+            cert_len  = (uint32_t) *ssl++;
+            printf_dbg( "Message-Digest length: %u\n", cert_len );
+
+            if( cert_len > 0 )
+            {
+                printf( "\tPeer digest cert : " );
+                CHECK_SSL_END( cert_len );
+                print_hex( ssl, cert_len, 16, "\t                   " );
+                ssl += cert_len;
+            }
+        }
+    }
+
+    if( SESSION_CONFIG_CLIENT_TICKET_BIT & session_cfg_flag )
+    {
+        printf( "\nTicket:\n" );
+
+        CHECK_SSL_END( 3 );
+        ticket_len = ( (uint32_t) ssl[0] << 16 ) |
+                     ( (uint32_t) ssl[1] <<  8 ) |
+                     ( (uint32_t) ssl[2] );
+        ssl += 3;
+        printf_dbg( "Ticket length: %u\n", ticket_len );
+
+        if( ticket_len > 0 )
+        {
+            printf( "\t" );
+            CHECK_SSL_END( ticket_len );
+            print_hex( ssl, ticket_len, 22, "\t" );
+            ssl += ticket_len;
+            printf( "\n" );
+        }
+
+        CHECK_SSL_END( 4 );
+        ticket_lifetime = ( (uint32_t) ssl[0] << 24 ) |
+                          ( (uint32_t) ssl[1] << 16 ) |
+                          ( (uint32_t) ssl[2] <<  8 ) |
+                          ( (uint32_t) ssl[3] );
+        ssl += 4;
+        printf( "\tlifetime : %u sec.\n", ticket_lifetime );
+    }
+
+    if( ssl < end )
+    {
+        printf( "\nSession others:\n" );
+    }
+
+    if( SESSION_CONFIG_MFL_BIT & session_cfg_flag )
+    {
+        CHECK_SSL_END( 1 );
+        printf( "\tMFL                      : %s\n", get_mfl_str( *ssl++ ) );
+    }
+
+    if( SESSION_CONFIG_TRUNC_HMAC_BIT & session_cfg_flag )
+    {
+        CHECK_SSL_END( 1 );
+        printf( "\tnegotiate truncated HMAC : %s\n", get_enabled_str( *ssl++ ) );
+    }
+
+    if( SESSION_CONFIG_ETM_BIT & session_cfg_flag )
+    {
+        CHECK_SSL_END( 1 );
+        printf( "\tEncrypt-then-MAC         : %s\n", get_enabled_str( *ssl++ ) );
+    }
+
+    if( 0 != ( end - ssl ) )
+    {
+        printf_err( "%i bytes left to analyze from session\n", (int32_t)( end - ssl ) );
+    }
+}
+
+/*
+ * This function deserializes and prints to the stdout all obtained information
+ * about the context from provided data. This function was built based on
+ * mbedtls_ssl_context_load(). mbedtls_ssl_context_load() could not be used
+ * due to dependencies on the mbedTLS configuration and the configuration of
+ * the context when serialization was created.
+ *
+ * The data structure in the buffer:
+ *  // header
+ *  uint8 version[3];
+ *  uint8 configuration[5];
+ *  // session sub-structure
+ *  uint32_t session_len;
+ *  opaque session<1..2^32-1>;  // see mbedtls_ssl_session_save()
+ *  // transform sub-structure
+ *  uint8 random[64];           // ServerHello.random+ClientHello.random
+ *  uint8 in_cid_len;
+ *  uint8 in_cid<0..2^8-1>      // Connection ID: expected incoming value
+ *  uint8 out_cid_len;
+ *  uint8 out_cid<0..2^8-1>     // Connection ID: outgoing value to use
+ *  // fields from ssl_context
+ *  uint32 badmac_seen;         // DTLS: number of records with failing MAC
+ *  uint64 in_window_top;       // DTLS: last validated record seq_num
+ *  uint64 in_window;           // DTLS: bitmask for replay protection
+ *  uint8 disable_datagram_packing; // DTLS: only one record per datagram
+ *  uint64 cur_out_ctr;         // Record layer: outgoing sequence number
+ *  uint16 mtu;                 // DTLS: path mtu (max outgoing fragment size)
+ *  uint8 alpn_chosen_len;
+ *  uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol
+ *
+ * /p ssl   pointer to serialized session
+ * /p len   number of bytes in the buffer
+ */
+void print_deserialized_ssl_context( const uint8_t *ssl, size_t len )
+{
+    const uint8_t *end = ssl + len;
+    uint32_t session_len;
+    int session_cfg_flag;
+    int context_cfg_flag;
+
+    printf( "\nMbed TLS version:\n" );
+
+    CHECK_SSL_END( 3 + 2 + 3 );
+
+    printf( "\tmajor    %u\n", (uint32_t) *ssl++ );
+    printf( "\tminor    %u\n", (uint32_t) *ssl++ );
+    printf( "\tpath     %u\n", (uint32_t) *ssl++ );
+
+    printf( "\nEnabled session and context configuration:\n" );
+
+    session_cfg_flag = ( (int) ssl[0] << 8 ) | ( (int) ssl[1] );
+    ssl += 2;
+
+    context_cfg_flag = ( (int) ssl[0] << 16 ) |
+                       ( (int) ssl[1] <<  8 ) |
+                       ( (int) ssl[2] ) ;
+    ssl += 3;
+
+    printf_dbg( "Session config flags 0x%04X\n", session_cfg_flag );
+    printf_dbg( "Context config flags 0x%06X\n", context_cfg_flag );
+
+    print_if_bit( "MBEDTLS_HAVE_TIME", SESSION_CONFIG_TIME_BIT, session_cfg_flag );
+    print_if_bit( "MBEDTLS_X509_CRT_PARSE_C", SESSION_CONFIG_CRT_BIT, session_cfg_flag );
+    print_if_bit( "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH", SESSION_CONFIG_MFL_BIT, session_cfg_flag );
+    print_if_bit( "MBEDTLS_SSL_TRUNCATED_HMAC", SESSION_CONFIG_TRUNC_HMAC_BIT, session_cfg_flag );
+    print_if_bit( "MBEDTLS_SSL_ENCRYPT_THEN_MAC", SESSION_CONFIG_ETM_BIT, session_cfg_flag );
+    print_if_bit( "MBEDTLS_SSL_SESSION_TICKETS", SESSION_CONFIG_TICKET_BIT, session_cfg_flag );
+    print_if_bit( "MBEDTLS_SSL_SESSION_TICKETS and client", SESSION_CONFIG_CLIENT_TICKET_BIT, session_cfg_flag );
+
+    print_if_bit( "MBEDTLS_SSL_DTLS_CONNECTION_ID", CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT, context_cfg_flag );
+    print_if_bit( "MBEDTLS_SSL_DTLS_BADMAC_LIMIT", CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT, context_cfg_flag );
+    print_if_bit( "MBEDTLS_SSL_DTLS_ANTI_REPLAY", CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT, context_cfg_flag );
+    print_if_bit( "MBEDTLS_SSL_ALPN", CONTEXT_CONFIG_ALPN_BIT, context_cfg_flag );
+
+    CHECK_SSL_END( 4 );
+    session_len = ( (uint32_t) ssl[0] << 24 ) |
+                  ( (uint32_t) ssl[1] << 16 ) |
+                  ( (uint32_t) ssl[2] <<  8 ) |
+                  ( (uint32_t) ssl[3] );
+    ssl += 4;
+    printf_dbg( "Session length %u\n", session_len );
+
+    CHECK_SSL_END( session_len );
+    print_deserialized_ssl_session( ssl, session_len, session_cfg_flag );
+    ssl += session_len;
+
+    printf( "\nRandom bytes:\n\t");
+
+    CHECK_SSL_END( TRANSFORM_RANDBYTE_LEN );
+    print_hex( ssl, TRANSFORM_RANDBYTE_LEN, 22, "\t" );
+    ssl += TRANSFORM_RANDBYTE_LEN;
+
+    printf( "\nContext others:\n" );
+
+    if( CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT & context_cfg_flag )
+    {
+        uint8_t cid_len;
+
+        CHECK_SSL_END( 1 );
+        cid_len = *ssl++;
+        printf_dbg( "In CID length %u\n", (uint32_t) cid_len );
+
+        printf( "\tin CID                             : " );
+        if( cid_len > 0 )
+        {
+            CHECK_SSL_END( cid_len );
+            print_hex( ssl, cid_len, 20, "\t" );
+            ssl += cid_len;
+        }
+        else
+        {
+            printf( "none\n" );
+        }
+
+        CHECK_SSL_END( 1 );
+        cid_len = *ssl++;
+        printf_dbg( "Out CID length %u\n", (uint32_t) cid_len );
+
+        printf( "\tout CID                            : " );
+        if( cid_len > 0 )
+        {
+            CHECK_SSL_END( cid_len );
+            print_hex( ssl, cid_len, 20, "\t" );
+            ssl += cid_len;
+        }
+        else
+        {
+            printf( "none\n" );
+        }
+    }
+
+    if( CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT & context_cfg_flag )
+    {
+        uint32_t badmac_seen;
+
+        CHECK_SSL_END( 4 );
+        badmac_seen = ( (uint32_t) ssl[0] << 24 ) |
+                      ( (uint32_t) ssl[1] << 16 ) |
+                      ( (uint32_t) ssl[2] <<  8 ) |
+                      ( (uint32_t) ssl[3] );
+        ssl += 4;
+        printf( "\tbad MAC seen number                : %u\n", badmac_seen );
+
+        /* value 'in_window_top' from mbedtls_ssl_context */
+        printf( "\tlast validated record sequence no. : " );
+        CHECK_SSL_END( 8 );
+        print_hex( ssl, 8, 20, "" );
+        ssl += 8;
+
+        /* value 'in_window' from mbedtls_ssl_context */
+        printf( "\tbitmask for replay detection       : " );
+        CHECK_SSL_END( 8 );
+        print_hex( ssl, 8, 20, "" );
+        ssl += 8;
+    }
+
+    if( conf_dtls_proto )
+    {
+        CHECK_SSL_END( 1 );
+        printf( "\tDTLS datagram packing              : %s\n",
+                get_enabled_str( ! ( *ssl++ ) ) );
+    }
+
+    /* value 'cur_out_ctr' from mbedtls_ssl_context */
+    printf( "\toutgoing record sequence no.       : ");
+    CHECK_SSL_END( 8 );
+    print_hex( ssl, 8, 20, "" );
+    ssl += 8;
+
+    if( conf_dtls_proto )
+    {
+        uint16_t mtu;
+        CHECK_SSL_END( 2 );
+        mtu = ( ssl[0] << 8 ) | ssl[1];
+        ssl += 2;
+        printf( "\tMTU                                : %u\n", mtu );
+    }
+
+
+    if( CONTEXT_CONFIG_ALPN_BIT & context_cfg_flag )
+    {
+        uint8_t alpn_len;
+
+        CHECK_SSL_END( 1 );
+        alpn_len = *ssl++;
+        printf_dbg( "ALPN length %u\n", (uint32_t) alpn_len );
+
+        printf( "\tALPN negotiation                   : " );
+        CHECK_SSL_END( alpn_len );
+        if( alpn_len > 0 )
+        {
+            if( strlen( (const char*) ssl ) == alpn_len )
+            {
+                printf( "%s\n", ssl );
+            }
+            else
+            {
+                printf( "\n" );
+                printf_err( "\tALPN negotiation is incorrect\n" );
+            }
+            ssl += alpn_len;
+        }
+        else
+        {
+            printf( "not selected\n" );
+        }
+    }
+
+    if( 0 != ( end - ssl ) )
+    {
+        printf_err( "%i bytes left to analyze from context\n", (int32_t)( end - ssl ) );
+    }
+    printf( "\n" );
+}
+
+int main( int argc, char *argv[] )
+{
+    enum { SSL_INIT_LEN = 4096 };
+
+    uint32_t b64_counter = 0;
+    uint8_t *b64_buf = NULL;
+    uint8_t *ssl_buf = NULL;
+    size_t b64_max_len = SSL_INIT_LEN;
+    size_t ssl_max_len = SSL_INIT_LEN;
+    size_t ssl_len = 0;
+
+     /* The 'b64_file' is opened when parsing arguments to check that the
+      * file name is correct */
+    parse_arguments( argc, argv );
+
+    if( NULL != b64_file )
+    {
+        b64_buf = malloc( SSL_INIT_LEN );
+        ssl_buf = malloc( SSL_INIT_LEN );
+
+        if( NULL == b64_buf || NULL == ssl_buf )
+        {
+            printf_err( alloc_err );
+            fclose( b64_file );
+            b64_file = NULL;
+        }
+    }
+
+    while( NULL != b64_file )
+    {
+        size_t b64_len = read_next_b64_code( &b64_buf, &b64_max_len );
+        if( b64_len > 0)
+        {
+            int ret;
+            size_t ssl_required_len = b64_len * 3 / 4 + 1;
+
+            /* Allocate more memory if necessary. */
+            if( ssl_required_len > ssl_max_len )
+            {
+                void *ptr = realloc( ssl_buf, ssl_required_len );
+                if( NULL == ptr )
+                {
+                    printf_err( alloc_err );
+                    fclose( b64_file );
+                    b64_file = NULL;
+                    break;
+                }
+                ssl_buf = ptr;
+                ssl_max_len = ssl_required_len;
+            }
+
+            printf( "\nDeserializing number %u:\n",  ++b64_counter );
+
+            printf( "\nBase64 code:\n" );
+            print_b64( b64_buf, b64_len );
+
+            ret = mbedtls_base64_decode( ssl_buf, ssl_max_len, &ssl_len, b64_buf, b64_len );
+            if( ret != 0)
+            {
+                mbedtls_strerror( ret, (char*) b64_buf, b64_max_len );
+                printf_err( "base64 code cannot be decoded - %s\n", b64_buf );
+                continue;
+            }
+
+            if( debug )
+            {
+                printf( "\nDecoded data in hex:\n\t");
+                print_hex( ssl_buf, ssl_len, 25, "\t" );
+            }
+
+            print_deserialized_ssl_context( ssl_buf, ssl_len );
+
+        }
+        else
+        {
+            fclose( b64_file );
+            b64_file = NULL;
+        }
+    }
+
+    free( b64_buf );
+    free( ssl_buf );
+
+    if( b64_counter > 0 )
+    {
+        printf_dbg( "Finished. Found %u base64 codes\n", b64_counter );
+    }
+    else
+    {
+        printf( "Finished. No valid base64 code found\n" );
+    }
+
+    return 0;
+}
+
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
diff --git a/tests/context-info.sh b/tests/context-info.sh
new file mode 100755
index 0000000..78aeb70
--- /dev/null
+++ b/tests/context-info.sh
@@ -0,0 +1,431 @@
+#!/bin/sh
+
+# context-info.sh
+#
+# This file is part of mbed TLS (https://tls.mbed.org)
+#
+# Copyright (c) 2012-2020, ARM Limited, All Rights Reserved
+#
+# This program is intended for testing the ssl_context_info program
+#
+
+set -eu
+
+if ! cd "$(dirname "$0")"; then
+    exit 125
+fi
+
+# Variables
+
+THIS_SCRIPT_NAME=$(basename "$0")
+PROG_PATH="../programs/ssl/ssl_context_info"
+OUT_FILE="ssl_context_info.log"
+IN_DIR="data_files/base64"
+
+USE_VALGRIND=0
+
+T_COUNT=0
+T_PASSED=0
+T_FAILED=0
+
+
+# Functions
+
+print_usage() {
+    echo "Usage: $0 [options]"
+    printf "  -h|--help\tPrint this help.\n"
+    printf "  -m|--memcheck\tUse valgrind to check the memory.\n"
+}
+
+# Print test name <name>
+print_name() {
+    printf "%s %.*s " "$1" $(( 71 - ${#1} )) \
+    "........................................................................"
+}
+
+# Print header to the test output file <test name> <file path> <test command>
+print_header()
+{
+    date="$(date)"
+    echo "******************************************************************" >  $2
+    echo "* File created by: $THIS_SCRIPT_NAME"                               >> $2
+    echo "* Test name:  $1"                                                   >> $2
+    echo "* Date:       $date"                                                >> $2
+    echo "* Command:    $3"                                                   >> $2
+    echo "******************************************************************" >> $2
+    echo ""                                                                   >> $2
+}
+
+# Print footer at the end of file <file path>
+print_footer()
+{
+    echo ""                                                                   >> $1
+    echo "******************************************************************" >> $1
+    echo "* End command"                                                      >> $1
+    echo "******************************************************************" >> $1
+    echo ""                                                                   >> $1
+}
+
+# Use the arguments of this script
+get_options() {
+    while [ $# -gt 0 ]; do
+        case "$1" in
+            -h|--help)
+                print_usage
+                exit 0
+                ;;
+            -m|--memcheck)
+                USE_VALGRIND=1
+                ;;
+            *)
+                echo "Unknown argument: '$1'"
+                print_usage
+                exit 1
+                ;;
+        esac
+        shift
+    done
+}
+
+# Current test failed
+fail()
+{
+    T_FAILED=$(( $T_FAILED + 1))
+    FAIL_OUT="Fail.$T_FAILED""_$OUT_FILE"
+
+    echo "FAIL"
+    echo "    Error: $1"
+
+    cp -f "$OUT_FILE" "$FAIL_OUT"
+    echo "Error: $1" >> "$FAIL_OUT"
+}
+
+# Current test passed
+pass()
+{
+    T_PASSED=$(( $T_PASSED + 1))
+    echo "PASS"
+}
+
+# Usage: run_test <name> <input file with b64 code> [ -arg <extra arguments for tested program> ] [option [...]]
+# Options:  -m <pattern that MUST be present in the output of tested program>
+#           -n <pattern that must NOT be present in the output of tested program>
+#           -u <pattern that must be UNIQUE in the output of tested program>
+run_test()
+{
+    TEST_NAME="$1"
+    RUN_CMD="$PROG_PATH -f $IN_DIR/$2"
+
+    if [ "-arg" = "$3" ]; then
+        RUN_CMD="$RUN_CMD $4"
+        shift 4
+    else
+        shift 2
+    fi
+
+    # prepend valgrind to our commands if active
+    if [ "$USE_VALGRIND" -gt 0 ]; then
+        RUN_CMD="valgrind --leak-check=full $RUN_CMD"
+    fi
+
+    T_COUNT=$(( $T_COUNT + 1))
+    print_name "$TEST_NAME"
+
+    # run tested program
+    print_header "$TEST_NAME" "$OUT_FILE" "$RUN_CMD"
+    eval "$RUN_CMD" >> "$OUT_FILE" 2>&1
+    print_footer "$OUT_FILE"
+
+    # check valgrind's results
+    if [ "$USE_VALGRIND" -gt 0 ]; then
+        if ! ( grep -F 'All heap blocks were freed -- no leaks are possible' "$OUT_FILE" &&
+             grep -F 'ERROR SUMMARY: 0 errors from 0 contexts' "$OUT_FILE" ) > /dev/null
+        then
+            fail "Memory error detected"
+            return
+        fi
+    fi
+
+    # check other assertions
+    # lines beginning with == are added by valgrind, ignore them, because we already checked them before
+    # lines with 'Serious error when reading debug info', are valgrind issues as well
+    # lines beginning with * are added by this script, ignore too
+    while [ $# -gt 0 ]
+    do
+        case $1 in
+            "-m")
+                if grep -v '^==' "$OUT_FILE" | grep -v 'Serious error when reading debug info' | grep -v "^*" | grep "$2" >/dev/null; then :; else
+                    fail "pattern '$2' MUST be present in the output"
+                    return
+                fi
+                ;;
+
+            "-n")
+                if grep -v '^==' "$OUT_FILE" | grep -v 'Serious error when reading debug info' | grep -v "^*" | grep "$2" >/dev/null; then
+                    fail "pattern '$2' MUST NOT be present in the output"
+                    return
+                fi
+                ;;
+
+            "-u")
+                if [ $(grep -v '^==' "$OUT_FILE"| grep -v 'Serious error when reading debug info' | grep -v "^*" | grep "$2" | wc -l) -ne 1 ]; then
+                    fail "lines following pattern '$2' must be once in the output"
+                    return
+                fi
+                ;;
+
+            *)
+                echo "Unknown test: $1" >&2
+                exit 1
+        esac
+        shift 2
+    done
+
+    rm -f "$OUT_FILE"
+
+    pass
+}
+
+get_options "$@"
+
+# Tests
+
+run_test "Default configuration, server" \
+         "srv_def.txt" \
+         -n "ERROR" \
+         -u "major.* 2$" \
+         -u "minor.* 21$" \
+         -u "path.* 0$" \
+         -u "MBEDTLS_HAVE_TIME$" \
+         -u "MBEDTLS_X509_CRT_PARSE_C$" \
+         -u "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH$" \
+         -u "MBEDTLS_SSL_TRUNCATED_HMAC$" \
+         -u "MBEDTLS_SSL_ENCRYPT_THEN_MAC$" \
+         -u "MBEDTLS_SSL_SESSION_TICKETS$" \
+         -u "MBEDTLS_SSL_SESSION_TICKETS and client$" \
+         -u "MBEDTLS_SSL_DTLS_BADMAC_LIMIT$" \
+         -u "MBEDTLS_SSL_DTLS_ANTI_REPLAY$" \
+         -u "MBEDTLS_SSL_ALPN$" \
+         -u "ciphersuite.* TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256$" \
+         -u "cipher flags.* 0x00$" \
+         -u "Message-Digest.* SHA256$" \
+         -u "compression.* disabled$" \
+         -u "DTLS datagram packing.* enabled$" \
+         -n "Certificate" \
+         -n "bytes left to analyze from context"
+
+run_test "Default configuration, client" \
+         "cli_def.txt" \
+         -n "ERROR" \
+         -u "major.* 2$" \
+         -u "minor.* 21$" \
+         -u "path.* 0$" \
+         -u "MBEDTLS_HAVE_TIME$" \
+         -u "MBEDTLS_X509_CRT_PARSE_C$" \
+         -u "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH$" \
+         -u "MBEDTLS_SSL_TRUNCATED_HMAC$" \
+         -u "MBEDTLS_SSL_ENCRYPT_THEN_MAC$" \
+         -u "MBEDTLS_SSL_SESSION_TICKETS$" \
+         -u "MBEDTLS_SSL_SESSION_TICKETS and client$" \
+         -u "MBEDTLS_SSL_DTLS_BADMAC_LIMIT$" \
+         -u "MBEDTLS_SSL_DTLS_ANTI_REPLAY$" \
+         -u "MBEDTLS_SSL_ALPN$" \
+         -u "ciphersuite.* TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256$" \
+         -u "cipher flags.* 0x00$" \
+         -u "Message-Digest.* SHA256$" \
+         -u "compression.* disabled$" \
+         -u "DTLS datagram packing.* enabled$" \
+         -u "cert. version .* 3$" \
+         -u "serial number.* 02$" \
+         -u "issuer name.* C=NL, O=PolarSSL, CN=PolarSSL Test CA$" \
+         -u "subject name.* C=NL, O=PolarSSL, CN=localhost$" \
+         -u "issued  on.* 2019-02-10 14:44:06$" \
+         -u "expires on.* 2029-02-10 14:44:06$" \
+         -u "signed using.* RSA with SHA-256$" \
+         -u "RSA key size.* 2048 bits$" \
+         -u "basic constraints.* CA=false$" \
+         -n "bytes left to analyze from context"
+
+run_test "Ciphersuite TLS-RSA-WITH-AES-256-CCM-8, server" \
+         "srv_ciphersuite.txt" \
+         -n "ERROR" \
+         -u "ciphersuite.* TLS-RSA-WITH-AES-256-CCM-8$" \
+
+run_test "Ciphersuite TLS-RSA-WITH-AES-256-CCM-8, client" \
+         "cli_ciphersuite.txt" \
+         -n "ERROR" \
+         -u "ciphersuite.* TLS-RSA-WITH-AES-256-CCM-8$" \
+
+run_test "No packing, server" \
+         "srv_no_packing.txt" \
+         -n "ERROR" \
+         -u "DTLS datagram packing.* disabled"
+
+run_test "No packing, client" \
+         "cli_no_packing.txt" \
+         -n "ERROR" \
+         -u "DTLS datagram packing.* disabled"
+
+run_test "DTLS CID, server" \
+         "srv_cid.txt" \
+         -n "ERROR" \
+         -u "in CID.* DE AD" \
+         -u "out CID.* BE EF"
+
+run_test "DTLS CID, client" \
+         "cli_cid.txt" \
+         -n "ERROR" \
+         -u "in CID.* BE EF" \
+         -u "out CID.* DE AD"
+
+run_test "No MBEDTLS_SSL_MAX_FRAGMENT_LENGTH, server" \
+         "srv_no_mfl.txt" \
+         -n "ERROR" \
+         -n "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
+
+run_test "No MBEDTLS_SSL_MAX_FRAGMENT_LENGTH, client" \
+         "cli_no_mfl.txt" \
+         -n "ERROR" \
+         -n "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
+
+run_test "No MBEDTLS_SSL_ALPN, server" \
+         "srv_no_alpn.txt" \
+         -n "ERROR" \
+         -n "MBEDTLS_SSL_ALPN"
+
+run_test "No MBEDTLS_SSL_ALPN, client" \
+         "cli_no_alpn.txt" \
+         -n "ERROR" \
+         -n "MBEDTLS_SSL_ALPN"
+
+run_test "No MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, server" \
+         "srv_no_keep_cert.txt" \
+         -arg "--keep-peer-cert=0" \
+         -u "ciphersuite.* TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256$" \
+         -u "cipher flags.* 0x00" \
+         -u "compression.* disabled" \
+         -u "DTLS datagram packing.* enabled" \
+         -n "ERROR"
+
+run_test "No MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, client" \
+         "cli_no_keep_cert.txt" \
+         -arg "--keep-peer-cert=0" \
+         -u "ciphersuite.* TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256$" \
+         -u "cipher flags.* 0x00" \
+         -u "compression.* disabled" \
+         -u "DTLS datagram packing.* enabled" \
+         -n "ERROR"
+
+run_test "No MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, negative, server" \
+         "srv_no_keep_cert.txt" \
+         -m "Deserializing" \
+         -m "ERROR"
+
+run_test "No MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, negative, client" \
+         "cli_no_keep_cert.txt" \
+         -m "Deserializing" \
+         -m "ERROR"
+
+run_test "Minimal configuration, server" \
+         "srv_min_cfg.txt" \
+         -n "ERROR" \
+         -n "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH$" \
+         -n "MBEDTLS_SSL_TRUNCATED_HMAC$" \
+         -n "MBEDTLS_SSL_ENCRYPT_THEN_MAC$" \
+         -n "MBEDTLS_SSL_SESSION_TICKETS$" \
+         -n "MBEDTLS_SSL_SESSION_TICKETS and client$" \
+         -n "MBEDTLS_SSL_DTLS_BADMAC_LIMIT$" \
+         -n "MBEDTLS_SSL_DTLS_ANTI_REPLAY$" \
+         -n "MBEDTLS_SSL_ALPN$" \
+
+run_test "Minimal configuration, client" \
+         "cli_min_cfg.txt" \
+         -n "ERROR" \
+         -n "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH$" \
+         -n "MBEDTLS_SSL_TRUNCATED_HMAC$" \
+         -n "MBEDTLS_SSL_ENCRYPT_THEN_MAC$" \
+         -n "MBEDTLS_SSL_SESSION_TICKETS$" \
+         -n "MBEDTLS_SSL_SESSION_TICKETS and client$" \
+         -n "MBEDTLS_SSL_DTLS_BADMAC_LIMIT$" \
+         -n "MBEDTLS_SSL_DTLS_ANTI_REPLAY$" \
+         -n "MBEDTLS_SSL_ALPN$" \
+
+run_test "MTU=10000" \
+         "mtu_10000.txt" \
+         -n "ERROR" \
+         -u "MTU.* 10000$"
+
+run_test "MFL=1024" \
+         "mfl_1024.txt" \
+         -n "ERROR" \
+         -u "MFL.* 1024$"
+
+run_test "Older version (v2.19.1)" \
+         "v2.19.1.txt" \
+         -n "ERROR" \
+         -u "major.* 2$" \
+         -u "minor.* 19$" \
+         -u "path.* 1$" \
+         -u "ciphersuite.* TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8$" \
+         -u "Message-Digest.* SHA256$" \
+         -u "compression.* disabled$" \
+         -u "serial number.* 01:70:AF:40:B4:E6$" \
+         -u "issuer name.* CN=ca$" \
+         -u "subject name.* L=160001, OU=acc1, CN=device01$" \
+         -u "issued  on.* 2020-03-06 09:50:18$" \
+         -u "expires on.* 2056-02-26 09:50:18$" \
+         -u "signed using.* ECDSA with SHA256$" \
+         -u "lifetime.* 0 sec.$" \
+         -u "MFL.* none$" \
+         -u "negotiate truncated HMAC.* disabled$" \
+         -u "Encrypt-then-MAC.* enabled$" \
+         -u "DTLS datagram packing.* enabled$" \
+         -u "verify result.* 0x00000000$" \
+         -n "bytes left to analyze from context"
+
+run_test "Wrong base64 format" \
+         "def_bad_b64.txt" \
+         -m "ERROR" \
+         -u "The length of the base64 code found should be a multiple of 4" \
+         -n "bytes left to analyze from context"
+
+run_test "Too much data at the beginning of base64 code" \
+         "def_b64_too_big_1.txt" \
+         -m "ERROR" \
+         -n "The length of the base64 code found should be a multiple of 4" \
+
+run_test "Too much data in the middle of base64 code" \
+         "def_b64_too_big_2.txt" \
+         -m "ERROR" \
+         -n "The length of the base64 code found should be a multiple of 4" \
+
+run_test "Too much data at the end of base64 code" \
+         "def_b64_too_big_3.txt" \
+         -m "ERROR" \
+         -n "The length of the base64 code found should be a multiple of 4" \
+         -u "bytes left to analyze from context"
+
+run_test "Empty file as input" \
+         "empty.txt" \
+         -u "Finished. No valid base64 code found"
+
+run_test "Not empty file without base64 code" \
+         "../../context-info.sh" \
+         -n "Deserializing"
+
+run_test "Binary file instead of text file" \
+         "../../../programs/ssl/ssl_context_info" \
+         -m "ERROR" \
+         -u "Too many bad symbols detected. File check aborted" \
+         -n "Deserializing"
+
+
+# End of tests
+
+if [ $T_FAILED -eq 0 ]; then
+    printf "\nPASSED ( $T_COUNT tests )\n"
+else
+    printf "\nFAILED ( $T_FAILED / $T_COUNT tests )\n"
+fi
+
+exit $T_FAILED
diff --git a/tests/data_files/base64/cli_cid.txt b/tests/data_files/base64/cli_cid.txt
new file mode 100644
index 0000000..8048aec
--- /dev/null
+++ b/tests/data_files/base64/cli_cid.txt
@@ -0,0 +1,2 @@
+// Client, CID 0xBEEF
+AhUAAH8AAA8AAAQ8AAAAAF6MZUPMqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABh7h8/aprLN1fS0KwLkZzKcsa5LNtDW7sYu7d1z7fNetuRjLJpX/A1mTSqeBY7li8AAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJRZtK1pHRuu/Uw+Y91KCaqMAHKWeVJvuqjiTaElrahsx+HYoZ1+8i5BMY1NOL/y4TR9qZdxY+7NvNrEdEoFgcI/DqUN0aKs0zAIPmk92pFnjnbro5LxWRm3JbtIFcG6PdN+9aAbISrewt6EERIPhS45aH+Si08NLrvM+CcEBfqBBqOD+4LCZqT8nDBtALJyRqiykibsAAFRgAAAAF6MZUNak74BhbcgvZ2M8WhZKjQyCix7GJzRs4SqnD7iXoxlQ7YXjsVI0K/xyMOJPkT9ZcPEi/2jHGIte1ZduW4Cvu8C3q0AAAAAAAAAAAAAAAIAAAAAAAAABwAAAQAAAAAAAwAAAA==
diff --git a/tests/data_files/base64/cli_ciphersuite.txt b/tests/data_files/base64/cli_ciphersuite.txt
new file mode 100644
index 0000000..432978d
--- /dev/null
+++ b/tests/data_files/base64/cli_ciphersuite.txt
@@ -0,0 +1,2 @@
+// TLS-RSA-WITH-AES-256-CCM-8
+AhUAAH8AAA4AAAQ8AAAAAF6K4ynAoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLBIQUrrPh7jxYz9e55cJvfpOkuBf2ZiVovlYa1Dkwbimp5q/CoWIn48C0x3Yj6N0AAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJQBiQTa148x1XQyGt9vU2JxAHIZ9HxLR87PewpTaslP0qJ4FK6cibG/U4ACVriGQMpNkJo6xRRn5dGyKE5L5iqcLQZ4zwcJT50NYlVQqzlXPArOaAzjVAX4k+TwL/VmNepmn3wvregAADeiGsvvbaAw2P9fhCgwX6Bm0YNzkWQsNwWENa6GoZLzvMM51G44611fFnKoAAFRgAAAAF6K4yksMvMV19qRq+eNokGn0j9Q5tjE88EK8jfM7gksXorjKR6zhXhttFGIFkNNAmmKuuDQGVmX1yCoHiJFonUAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA==
\ No newline at end of file
diff --git a/tests/data_files/base64/cli_def.txt b/tests/data_files/base64/cli_def.txt
new file mode 100644
index 0000000..ee47905
--- /dev/null
+++ b/tests/data_files/base64/cli_def.txt
@@ -0,0 +1,2 @@
+// Client context with default MbedTLS configuration
+AhUAAH8AAA4AAAQ8AAAAAF6HQx3MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACG2QbHbUj8eGpdx5KVIebiwk0jvRj9/3m6BOSzpA7qBXeEunhqr3D11NE7ciGjeHMAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJTfQC2Ek91INP5ihHNzImPOAHJCk+YTO/pQuEnNWwXbdmKAi+IRp671iAwtpkjSxCBXVzKX925F1A66caCOQptlw+9zFukDQgblM2JyAJLG0j6B4RtBTDWJ8ZTMUPHUoLJoEpm8APZgRi//DMRyCKP9pbBLGlDzgUvl0w11LzBAlJHkWau5NoqQBlG7w4HFrKweovskAAFRgAAAAF6HQx248L77RH0Z973tSYNQ8zBsz861CZG5/T09TJz3XodDHe/iJ+cgXb5An3zTdnTBtw3EWAb68T+gCE33GN8AAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA==
\ No newline at end of file
diff --git a/tests/data_files/base64/cli_min_cfg.txt b/tests/data_files/base64/cli_min_cfg.txt
new file mode 100644
index 0000000..8c1ef88
--- /dev/null
+++ b/tests/data_files/base64/cli_min_cfg.txt
@@ -0,0 +1,2 @@
+// Minimal configuration
+AhUAAAMAAAAAAAOeAAAAAF6LZlLMqAAgUGktPmpSPbzRPipeCpYJtp5SNIIjTr3R121WF9AeWN4tmKbRhhv+yPMjY0yWPrHLy7lLLhwNFBwCD6eQ0ULZZ15Fi2Rhae/4ZkAR0BN2iCMAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLdei2ZSQwLppTqzs7kieOYQR6DjJItmQ0N/RS3+zTr9wF6LZlL6SQpLewmyja7jXyOWuUqJ6zJQ5b7FfA4PxthlAAABAAAAAAACAAA=
\ No newline at end of file
diff --git a/tests/data_files/base64/cli_no_alpn.txt b/tests/data_files/base64/cli_no_alpn.txt
new file mode 100644
index 0000000..25923f6
--- /dev/null
+++ b/tests/data_files/base64/cli_no_alpn.txt
@@ -0,0 +1,3 @@
+// Without MBEDTLS_SSL_ALPN
+AhUAAH8AAAYAAAQ8AAAAAF6LDSzMqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1lCUO8B/805UzCOLZzWDAEA8anfLpbuWTrnFSR2puZktvEiR8nXdATN0yKS94oSAAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJQVUI/Wwt3q4XiqL74wCmkhAHKj0YgCvjZi3GKw0s7PJqjZzzLt+OuroC8Q2XeDf5nKKk8jkolZ+dXUftsPPizFgb2hGuYa4NhxXjiGlUpFEoXm7r78SwGfWxRgH5vJk6W3TdodkxTZkjMoWjlC2PANOHPeClw0szBmly7+s89LFZqnCXgyxE8xlv+l5IYSEPSj7UsmAAFRgAAAAF6LDSwWt0QWgmNg4Zv2yYhf4Pdexpi/QTIqWyD2AQVjXosNLLK1vz/upFHrJlizjH5uSBUJCpQZJczrBgxBmGoAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAA
+
diff --git a/tests/data_files/base64/cli_no_keep_cert.txt b/tests/data_files/base64/cli_no_keep_cert.txt
new file mode 100644
index 0000000..5272a7c
--- /dev/null
+++ b/tests/data_files/base64/cli_no_keep_cert.txt
@@ -0,0 +1,2 @@
+// Without MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+AhUAAAMAAAAAAACCAAAAAF6MKhTMqAAgSKCqXrcrmjqOBpxsGO3itQB09YgsSJwXmZB12QlB+wwhiof0mzAN0hupkLxu4Yyc9SgyFoEDPKJk8TiRo8bO2rkEfPItB5lUFkJwzdeuGVMAAAAABiCAy8MWqlj4vnIv0mswJvB35hyCOYWZ+fcZ6t5LzZgXPl6MKhRs69b+psiGUAo8OK3fU4HKOHNdi36tk22+ScctXowqFEyvzGcvbtI0VfWLKlOlDv+SwC08ZdCNa+RBZ/AAAAEAAAAAAAIAAA==
\ No newline at end of file
diff --git a/tests/data_files/base64/cli_no_mfl.txt b/tests/data_files/base64/cli_no_mfl.txt
new file mode 100644
index 0000000..5c1dfd9
--- /dev/null
+++ b/tests/data_files/base64/cli_no_mfl.txt
@@ -0,0 +1,2 @@
+// Without MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+AhUAAHcAAA4AAAQ6AAAAAF6LDLPMqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0fzGzO1ysljMgZr4gduigvRXr2AK5X8j8c6vHTOpc2ncFS3UN2ojwD2tOaM3+/XIAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJMiPbE45oAjg9Rx0iVnQDg2AHHKrrmSMTfVijgZbdL/ZFWYvFMioa7uqW0NmA0bSTxcsieRarndOq5fIdEIzmAgGkdaxJaGNDT105gwwIzUnLRapgP6H6IImSMFPXVp3Zks0zFfrq7aQnQMgc8o5kPqWq1/eYfdq8lysTO8Rgliv96lA/pe1SQmPL1mdChAwCa/4XEAAVGAAABeiwyzXGz4yPwEgvq/TWq0dZXvD6mzEbAty1oZJIvRpl6LDLOyQ94MIvSKw7OH4mg+DNL+ZW0xzQbKQalloUG6AAAAAAAAAAAAAAABAAAAAAAAAAMAAAEAAAAAAAIAAAA=
\ No newline at end of file
diff --git a/tests/data_files/base64/cli_no_packing.txt b/tests/data_files/base64/cli_no_packing.txt
new file mode 100644
index 0000000..068276b
--- /dev/null
+++ b/tests/data_files/base64/cli_no_packing.txt
@@ -0,0 +1,2 @@
+// Without DTLS packing
+AhUAAH8AAA4AAAQ8AAAAAF6LCM/MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfl0tXNmshIQEqiEflQGnVUKkIFl1on/Mu0pjWes3XwQgdwmy9xMzpVyYU5gBOsOEAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJRTvlE7NmNNLDESUBoGC+K2AHIKA+/lhdRVF4YcMvvqCBYFB5tj0oyCikftfjNbvjl9YPGqcRXk664YieWv/pz8U1FOENipbjXF9lFhgedG2Xanh/2FwHX5txYiHIJxJeLEKCXp5Sjt9XBvQsrryxLyX9l+zkLKm7bCAcrfk4h/YoqxecAI63isG9vnrS7o07iD/3mOAAFRgAAAAF6LCM+1uRpyaoyfzuNGBJK9DgBWIWtrPpu7KM8qsC/FXosIz/YIPhveZ8Z4IR0g/McAMQwzQoK5tScSE0DD3BwAAAAAAAAAAAAAAAEAAAAAAAAAAwEAAQAAAAAAAgAAAA==
\ No newline at end of file
diff --git a/tests/data_files/base64/def_b64_too_big_1.txt b/tests/data_files/base64/def_b64_too_big_1.txt
new file mode 100644
index 0000000..0fe8a18
--- /dev/null
+++ b/tests/data_files/base64/def_b64_too_big_1.txt
@@ -0,0 +1,2 @@
+// Context with added '1234' at the begining to simulate too much data in the base64 code
+1234AhUAAH8AAA4AAAQ8AAAAAF6HQx3MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACG2QbHbUj8eGpdx5KVIebiwk0jvRj9/3m6BOSzpA7qBXeEunhqr3D11NE7ciGjeHMAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJTfQC2Ek91INP5ihHNzImPOAHJCk+YTO/pQuEnNWwXbdmKAi+IRp671iAwtpkjSxCBXVzKX925F1A66caCOQptlw+9zFukDQgblM2JyAJLG0j6B4RtBTDWJ8ZTMUPHUoLJoEpm8APZgRi//DMRyCKP9pbBLGlDzgUvl0w11LzBAlJHkWau5NoqQBlG7w4HFrKweovskAAFRgAAAAF6HQx248L77RH0Z973tSYNQ8zBsz861CZG5/T09TJz3XodDHe/iJ+cgXb5An3zTdnTBtw3EWAb68T+gCE33GN8AAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA==
diff --git a/tests/data_files/base64/def_b64_too_big_2.txt b/tests/data_files/base64/def_b64_too_big_2.txt
new file mode 100644
index 0000000..7ec1dd0
--- /dev/null
+++ b/tests/data_files/base64/def_b64_too_big_2.txt
@@ -0,0 +1,2 @@
+// Context with added '1234' in the middle of code to simulate too much data
+AhUAAH8AAA4AAAQ8AAAAAF6HQx3MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACG2QbHbUj8eGpdx5KVIebiwk0jvRj9/3m6BOSzpA7qBXeEunhqr3D11NE7ciGjeHMAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7m1234gM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJTfQC2Ek91INP5ihHNzImPOAHJCk+YTO/pQuEnNWwXbdmKAi+IRp671iAwtpkjSxCBXVzKX925F1A66caCOQptlw+9zFukDQgblM2JyAJLG0j6B4RtBTDWJ8ZTMUPHUoLJoEpm8APZgRi//DMRyCKP9pbBLGlDzgUvl0w11LzBAlJHkWau5NoqQBlG7w4HFrKweovskAAFRgAAAAF6HQx248L77RH0Z973tSYNQ8zBsz861CZG5/T09TJz3XodDHe/iJ+cgXb5An3zTdnTBtw3EWAb68T+gCE33GN8AAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA==
diff --git a/tests/data_files/base64/def_b64_too_big_3.txt b/tests/data_files/base64/def_b64_too_big_3.txt
new file mode 100644
index 0000000..514754c
--- /dev/null
+++ b/tests/data_files/base64/def_b64_too_big_3.txt
@@ -0,0 +1,2 @@
+// Context with added '1234' before '==' add the end to simulate too much data in the base64 code
+AhUAAH8AAA4AAAQ8AAAAAF6HQx3MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACG2QbHbUj8eGpdx5KVIebiwk0jvRj9/3m6BOSzpA7qBXeEunhqr3D11NE7ciGjeHMAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJTfQC2Ek91INP5ihHNzImPOAHJCk+YTO/pQuEnNWwXbdmKAi+IRp671iAwtpkjSxCBXVzKX925F1A66caCOQptlw+9zFukDQgblM2JyAJLG0j6B4RtBTDWJ8ZTMUPHUoLJoEpm8APZgRi//DMRyCKP9pbBLGlDzgUvl0w11LzBAlJHkWau5NoqQBlG7w4HFrKweovskAAFRgAAAAF6HQx248L77RH0Z973tSYNQ8zBsz861CZG5/T09TJz3XodDHe/iJ+cgXb5An3zTdnTBtw3EWAb68T+gCE33GN8AAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA1234==
diff --git a/tests/data_files/base64/def_bad_b64.txt b/tests/data_files/base64/def_bad_b64.txt
new file mode 100644
index 0000000..d777658
--- /dev/null
+++ b/tests/data_files/base64/def_bad_b64.txt
@@ -0,0 +1,2 @@
+// Context with added extra 'A' before '==' add the end to simulate bad length of base64 code
+AhUAAH8AAA4AAAQ8AAAAAF6HQx3MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACG2QbHbUj8eGpdx5KVIebiwk0jvRj9/3m6BOSzpA7qBXeEunhqr3D11NE7ciGjeHMAAAAAAAM7MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcNMTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTNowCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKzNtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kMtQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8PhYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjyaHT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJhPqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6UHoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq91C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sva1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbopMZqLmbBm/7WPLcAAJTfQC2Ek91INP5ihHNzImPOAHJCk+YTO/pQuEnNWwXbdmKAi+IRp671iAwtpkjSxCBXVzKX925F1A66caCOQptlw+9zFukDQgblM2JyAJLG0j6B4RtBTDWJ8ZTMUPHUoLJoEpm8APZgRi//DMRyCKP9pbBLGlDzgUvl0w11LzBAlJHkWau5NoqQBlG7w4HFrKweovskAAFRgAAAAF6HQx248L77RH0Z973tSYNQ8zBsz861CZG5/T09TJz3XodDHe/iJ+cgXb5An3zTdnTBtw3EWAb68T+gCE33GN8AAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAAA==
diff --git a/tests/data_files/base64/empty.txt b/tests/data_files/base64/empty.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data_files/base64/empty.txt
diff --git a/tests/data_files/base64/mfl_1024.txt b/tests/data_files/base64/mfl_1024.txt
new file mode 100644
index 0000000..58dbe5f
--- /dev/null
+++ b/tests/data_files/base64/mfl_1024.txt
@@ -0,0 +1,2 @@
+// MFL=1024
+AhUAAH8AAA4AAABtAAAAAF6K+GLMqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACHeeQKPVt9RpB8nLTB6C2AhxRzB0r/OBbXbMPm6jb1rkR+qrXZAUFRvGfGxlqqGWwAAACAAAAAAAAAAAAAAAIAAV6K+GJIXNnpKTr9HZQW6WEH7YSYhhRRqOO6xvf8QL6/Xor4YhOxOJYk23w3AwDvVAofeWnVAfJnExe5ipdSxnAAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA===
\ No newline at end of file
diff --git a/tests/data_files/base64/mtu_10000.txt b/tests/data_files/base64/mtu_10000.txt
new file mode 100644
index 0000000..dc7c975
--- /dev/null
+++ b/tests/data_files/base64/mtu_10000.txt
@@ -0,0 +1,2 @@
+// MTU=10000
+AhUAAH8AAA4AAABtAAAAAF6LDkzMqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABx06kxYooMLGPyUMoB46EF2zTJzmZEM4le5aKihcHpFEfgrX/eWQZFWa7cak79ihwAAACAAAAAAAAAAAAAAAAAAV6LDkz9bigMk9q0WiDmgYhX8ppbfgbtMCfruvVQNiFWXosOTJ3R2+J+TaSChmjtS8sD+y1Zruhe/SJE7y9D+5YAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAicQAA==
\ No newline at end of file
diff --git a/tests/data_files/base64/srv_cid.txt b/tests/data_files/base64/srv_cid.txt
new file mode 100644
index 0000000..69aad5f
--- /dev/null
+++ b/tests/data_files/base64/srv_cid.txt
@@ -0,0 +1,2 @@
+// Server, CID 0xDEAD
+AhUAAH8AAA8AAABtAAAAAF6MZUPMqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABh7h8/aprLN1fS0KwLkZzKcsa5LNtDW7sYu7d1z7fNetuRjLJpX/A1mTSqeBY7li8AAACAAAAAAAAAAAAAAAAAAV6MZUNak74BhbcgvZ2M8WhZKjQyCix7GJzRs4SqnD7iXoxlQ7YXjsVI0K/xyMOJPkT9ZcPEi/2jHGIte1ZduW4C3q0Cvu8AAAAAAAAAAAAAAAIAAAAAAAAABwAAAQAAAAAAAwAAAA==
diff --git a/tests/data_files/base64/srv_ciphersuite.txt b/tests/data_files/base64/srv_ciphersuite.txt
new file mode 100644
index 0000000..5ddca63
--- /dev/null
+++ b/tests/data_files/base64/srv_ciphersuite.txt
@@ -0,0 +1,2 @@
+// TLS-RSA-WITH-AES-256-CCM-8
+AhUAAH8AAA4AAABtAAAAAF6K4ynAoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLBIQUrrPh7jxYz9e55cJvfpOkuBf2ZiVovlYa1Dkwbimp5q/CoWIn48C0x3Yj6N0AAACAAAAAAAAAAAAAAAAAAV6K4yksMvMV19qRq+eNokGn0j9Q5tjE88EK8jfM7gksXorjKR6zhXhttFGIFkNNAmmKuuDQGVmX1yCoHiJFonUAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA==
\ No newline at end of file
diff --git a/tests/data_files/base64/srv_def.txt b/tests/data_files/base64/srv_def.txt
new file mode 100644
index 0000000..ca81461
--- /dev/null
+++ b/tests/data_files/base64/srv_def.txt
@@ -0,0 +1,2 @@
+// Server context with default MbedTLS configuration
+AhUAAH8AAA4AAABtAAAAAF6HQx3MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACG2QbHbUj8eGpdx5KVIebiwk0jvRj9/3m6BOSzpA7qBXeEunhqr3D11NE7ciGjeHMAAACAAAAAAAAAAAAAAAAAAV6HQx248L77RH0Z973tSYNQ8zBsz861CZG5/T09TJz3XodDHe/iJ+cgXb5An3zTdnTBtw3EWAb68T+gCE33GN8AAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA==
diff --git a/tests/data_files/base64/srv_min_cfg.txt b/tests/data_files/base64/srv_min_cfg.txt
new file mode 100644
index 0000000..8be0288
--- /dev/null
+++ b/tests/data_files/base64/srv_min_cfg.txt
@@ -0,0 +1,2 @@
+// Minimal configuration
+AhUAAAMAAAAAAABjAAAAAF6LZlLMqAAgUGktPmpSPbzRPipeCpYJtp5SNIIjTr3R121WF9AeWN4tmKbRhhv+yPMjY0yWPrHLy7lLLhwNFBwCD6eQ0ULZZ15Fi2Rhae/4ZkAR0BN2iCMAAACAAAAAXotmUkMC6aU6s7O5InjmEEeg4ySLZkNDf0Ut/s06/cBei2ZS+kkKS3sJso2u418jlrlKiesyUOW+xXwOD8bYZQAAAQAAAAAAAgAA
\ No newline at end of file
diff --git a/tests/data_files/base64/srv_no_alpn.txt b/tests/data_files/base64/srv_no_alpn.txt
new file mode 100644
index 0000000..afc51f9
--- /dev/null
+++ b/tests/data_files/base64/srv_no_alpn.txt
@@ -0,0 +1,2 @@
+// Without MBEDTLS_SSL_ALPN
+AhUAAH8AAAYAAABtAAAAAF6LDSzMqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1lCUO8B/805UzCOLZzWDAEA8anfLpbuWTrnFSR2puZktvEiR8nXdATN0yKS94oSAAAACAAAAAAAAAAAAAAAAAAV6LDSwWt0QWgmNg4Zv2yYhf4Pdexpi/QTIqWyD2AQVjXosNLLK1vz/upFHrJlizjH5uSBUJCpQZJczrBgxBmGoAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAA
\ No newline at end of file
diff --git a/tests/data_files/base64/srv_no_keep_cert.txt b/tests/data_files/base64/srv_no_keep_cert.txt
new file mode 100644
index 0000000..be834b9
--- /dev/null
+++ b/tests/data_files/base64/srv_no_keep_cert.txt
@@ -0,0 +1,2 @@
+// Without MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+AhUAAAMAAAAAAABiAAAAAF6MKhTMqAAgSKCqXrcrmjqOBpxsGO3itQB09YgsSJwXmZB12QlB+wwhiof0mzAN0hupkLxu4Yyc9SgyFoEDPKJk8TiRo8bO2rkEfPItB5lUFkJwzdeuGVMAAACAAABejCoUbOvW/qbIhlAKPDit31OByjhzXYt+rZNtvknHLV6MKhRMr8xnL27SNFX1iypTpQ7/ksAtPGXQjWvkQWfwAAABAAAAAAACAAA=
diff --git a/tests/data_files/base64/srv_no_mfl.txt b/tests/data_files/base64/srv_no_mfl.txt
new file mode 100644
index 0000000..c684ec7
--- /dev/null
+++ b/tests/data_files/base64/srv_no_mfl.txt
@@ -0,0 +1,2 @@
+// Without MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+AhUAAHcAAA4AAABsAAAAAF6LDLPMqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0fzGzO1ysljMgZr4gduigvRXr2AK5X8j8c6vHTOpc2ncFS3UN2ojwD2tOaM3+/XIAAACAAAAAAAAAAAAAAAABXosMs1xs+Mj8BIL6v01qtHWV7w+psxGwLctaGSSL0aZeiwyzskPeDCL0isOzh+JoPgzS/mVtMc0GykGpZaFBugAAAAAAAAAAAAAAAQAAAAAAAAADAAABAAAAAAACAAAA
\ No newline at end of file
diff --git a/tests/data_files/base64/srv_no_packing.txt b/tests/data_files/base64/srv_no_packing.txt
new file mode 100644
index 0000000..bcc4228
--- /dev/null
+++ b/tests/data_files/base64/srv_no_packing.txt
@@ -0,0 +1,2 @@
+// Without DTLS packing
+AhUAAH8AAA4AAABtAAAAAF6LCM/MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfl0tXNmshIQEqiEflQGnVUKkIFl1on/Mu0pjWes3XwQgdwmy9xMzpVyYU5gBOsOEAAACAAAAAAAAAAAAAAAAAAV6LCM+1uRpyaoyfzuNGBJK9DgBWIWtrPpu7KM8qsC/FXosIz/YIPhveZ8Z4IR0g/McAMQwzQoK5tScSE0DD3BwAAAAAAAAAAAAAAAEAAAAAAAAAAwEAAQAAAAAAAgAAAA==
diff --git a/tests/data_files/base64/v2.19.1.txt b/tests/data_files/base64/v2.19.1.txt
new file mode 100644
index 0000000..b910e33
--- /dev/null
+++ b/tests/data_files/base64/v2.19.1.txt
@@ -0,0 +1,2 @@
+// Context creaded by MbedTLS v.2.19.1 
+AhMBAH8AAA8AAAGjAAAAAF5iHYLArgAgkQE4V2NJsjbOuO52ws/u75f6Cg126zWeI7a+kaxTqKLbdWWZmW3PP+SflLxBA7Trpb0qZ5MP8+m0leylnLcDt2TtIWR49MOuiJuvVuMJmtwAAAAAAAE2MIIBMjCB2qADAgECAgYBcK9AtOYwCgYIKoZIzj0EAwIwDTELMAkGA1UEAwwCY2EwIBcNMjAwMzA2MDk1MDE4WhgPMjA1NjAyMjYwOTUwMThaMDMxDzANBgNVBAcTBjE2MDAwMTENMAsGA1UECxMEYWNjMTERMA8GA1UEAxMIZGV2aWNlMDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARn0TtinN6/runzIuF2f2uTH1f0mQOFXu3uRPtQji2ObccSsw6Cn9z7XWK9fRgeoOKA0WZC+O9L9IEWieS13ajFMAoGCCqGSM49BAMCA0cAMEQCIFoavpekQjIqubJ09jkMR+iiUpkGdFRla1R7onnc5iEOAiBAvYr8j9QqjpM2jColTS1cI0z29PBbuasq4HI6YCj0wgAAAAAAAAAAAAFeYh2Ct3LnESwmdWzU+xs7vV2Q0T5HJ8y4ckhpO7wOoF5iHYJ38gKFI3Qdc3BR48GV7nuBUKZeI1YJExQchj1WCAY6dEyghLpHAAAAAAAAAAAAAAAAAQAAAAAAAAADAAABAAAAAAACAAAA
\ No newline at end of file
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 9b69aa2..c3d0f6f 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -664,6 +664,9 @@
 
     msg "test: compat.sh (ASan build)" # ~ 6 min
     if_build_succeeded tests/compat.sh
+
+    msg "test: context-info.sh (ASan build)" # ~ 15 sec
+    if_build_succeeded tests/context-info.sh
 }
 
 component_test_full_cmake_gcc_asan () {
@@ -680,6 +683,9 @@
 
     msg "test: compat.sh (full config, ASan build)"
     if_build_succeeded tests/compat.sh
+
+    msg "test: context-info.sh (full config, ASan build)" # ~ 15 sec
+    if_build_succeeded tests/context-info.sh
 }
 
 component_test_zlib_make() {
@@ -742,6 +748,9 @@
 
     msg "build: SSLv3 - ssl-opt.sh (ASan build)" # ~ 6 min
     if_build_succeeded tests/ssl-opt.sh
+
+    msg "build: SSLv3 - context-info.sh (ASan build)" # ~ 15 sec
+    if_build_succeeded tests/context-info.sh
 }
 
 component_test_no_renegotiation () {
@@ -787,6 +796,9 @@
 
     msg "test: RSA_NO_CRT - RSA-related part of compat.sh (ASan build)" # ~ 3 min
     if_build_succeeded tests/compat.sh -t RSA
+
+    msg "test: RSA_NO_CRT - RSA-related part of context-info.sh (ASan build)" # ~ 15 sec
+    if_build_succeeded tests/context-info.sh
 }
 
 component_test_new_ecdh_context () {
@@ -1149,6 +1161,9 @@
 
     msg "test: compat.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
     if_build_succeeded tests/compat.sh
+
+    msg "test: context-info.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
+    if_build_succeeded tests/context-info.sh
 }
 
 component_test_no_max_fragment_length_small_ssl_out_content_len () {
@@ -1161,6 +1176,9 @@
 
     msg "test: MFL tests (disabled MFL extension case) & large packet tests"
     if_build_succeeded tests/ssl-opt.sh -f "Max fragment length\|Large buffer"
+
+    msg "test: context-info.sh (disabled MFL extension case)"
+    if_build_succeeded tests/context-info.sh
 }
 
 component_test_variable_ssl_in_out_buffer_len () {
@@ -1679,6 +1697,11 @@
         msg "test: compat.sh --memcheck (Release)"
         if_build_succeeded tests/compat.sh --memcheck
     fi
+
+    if [ "$MEMORY" -gt 0 ]; then
+        msg "test: context-info.sh --memcheck (Release)"
+        if_build_succeeded tests/context-info.sh --memcheck
+    fi
 }
 
 component_test_cmake_out_of_source () {
diff --git a/visualc/VS2010/mbedTLS.sln b/visualc/VS2010/mbedTLS.sln
index 73102e1..6969bbb 100644
--- a/visualc/VS2010/mbedTLS.sln
+++ b/visualc/VS2010/mbedTLS.sln
@@ -168,6 +168,11 @@
 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

 	EndProjectSection

 EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssl_context_info", "ssl_context_info.vcxproj", "{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}"

+	ProjectSection(ProjectDependencies) = postProject

+		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

+	EndProjectSection

+EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssl_fork_server", "ssl_fork_server.vcxproj", "{918CD402-047D-8467-E11C-E1132053F916}"

 	ProjectSection(ProjectDependencies) = postProject

 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

@@ -538,6 +543,14 @@
 		{A4DA7463-1047-BDF5-E1B3-5632CB573F41}.Release|Win32.Build.0 = Release|Win32

 		{A4DA7463-1047-BDF5-E1B3-5632CB573F41}.Release|x64.ActiveCfg = Release|x64

 		{A4DA7463-1047-BDF5-E1B3-5632CB573F41}.Release|x64.Build.0 = Release|x64

+		{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}.Debug|Win32.ActiveCfg = Debug|Win32

+		{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}.Debug|Win32.Build.0 = Debug|Win32

+		{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}.Debug|x64.ActiveCfg = Debug|x64

+		{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}.Debug|x64.Build.0 = Debug|x64

+		{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}.Release|Win32.ActiveCfg = Release|Win32

+		{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}.Release|Win32.Build.0 = Release|Win32

+		{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}.Release|x64.ActiveCfg = Release|x64

+		{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}.Release|x64.Build.0 = Release|x64

 		{918CD402-047D-8467-E11C-E1132053F916}.Debug|Win32.ActiveCfg = Debug|Win32

 		{918CD402-047D-8467-E11C-E1132053F916}.Debug|Win32.Build.0 = Debug|Win32

 		{918CD402-047D-8467-E11C-E1132053F916}.Debug|x64.ActiveCfg = Debug|x64

diff --git a/visualc/VS2010/ssl_context_info.vcxproj b/visualc/VS2010/ssl_context_info.vcxproj
new file mode 100644
index 0000000..f252298
--- /dev/null
+++ b/visualc/VS2010/ssl_context_info.vcxproj
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <ItemGroup Label="ProjectConfigurations">

+    <ProjectConfiguration Include="Debug|Win32">

+      <Configuration>Debug</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Debug|x64">

+      <Configuration>Debug</Configuration>

+      <Platform>x64</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|Win32">

+      <Configuration>Release</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|x64">

+      <Configuration>Release</Configuration>

+      <Platform>x64</Platform>

+    </ProjectConfiguration>

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="..\..\programs\ssl\ssl_context_info.c" />

+  </ItemGroup>

+  <ItemGroup>

+    <ProjectReference Include="mbedTLS.vcxproj">
+      <Project>{46cf2d25-6a36-4189-b59c-e4815388e554}</Project>

+      <LinkLibraryDependencies>true</LinkLibraryDependencies>

+    </ProjectReference>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{017ECC7D-FB6D-46D8-076B-F64172E8E3BC}</ProjectGuid>

+    <Keyword>Win32Proj</Keyword>

+    <RootNamespace>ssl_context_info</RootNamespace>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

+  <ImportGroup Label="ExtensionSettings">

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <PropertyGroup Label="UserMacros" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <ClCompile>

+      <PrecompiledHeader>

+      </PrecompiledHeader>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>

+../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib      </AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <ShowProgress>NotSet</ShowProgress>

+      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

+    </Link>

+    <ProjectReference>

+      <LinkLibraryDependencies>false</LinkLibraryDependencies>

+    </ProjectReference>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

+    <ClCompile>

+      <PrecompiledHeader>

+      </PrecompiledHeader>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>

+../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib      </AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <ShowProgress>NotSet</ShowProgress>

+      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

+    </Link>

+    <ProjectReference>

+      <LinkLibraryDependencies>false</LinkLibraryDependencies>

+    </ProjectReference>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <PrecompiledHeader>

+      </PrecompiledHeader>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>

+../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib      </AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

+      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <PrecompiledHeader>

+      </PrecompiledHeader>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>

+../../include;../../3rdparty/everest/include/;../../3rdparty/everest/include/everest;../../3rdparty/everest/include/everest/vs2010;../../3rdparty/everest/include/everest/kremlib      </AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

+      <AdditionalDependencies>%(AdditionalDependencies);</AdditionalDependencies>

+    </Link>

+  </ItemDefinitionGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

+</Project>