/*
 *  SSL session cache implementation
 *
 *  Copyright (C) 2006-2012, Brainspark B.V.
 *
 *  This file is part of PolarSSL (http://www.polarssl.org)
 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
 *
 *  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
/*
 * These session callbacks use a simple chained list
 * to store and retrieve the session information.
 */

#include "polarssl/config.h"

#if defined(POLARSSL_SSL_CACHE_C)

#include "polarssl/ssl_cache.h"

#if defined(POLARSSL_MEMORY_C)
#include "polarssl/memory.h"
#else
#define polarssl_malloc     malloc
#define polarssl_free       free
#endif

#include <stdlib.h>

void ssl_cache_init( ssl_cache_context *cache )
{
    memset( cache, 0, sizeof( ssl_cache_context ) );

    cache->timeout = SSL_CACHE_DEFAULT_TIMEOUT;
    cache->max_entries = SSL_CACHE_DEFAULT_MAX_ENTRIES;
}

int ssl_cache_get( void *data, ssl_session *session )
{
#if defined(POLARSSL_HAVE_TIME)
    time_t t = time( NULL );
#endif
    ssl_cache_context *cache = (ssl_cache_context *) data;
    ssl_cache_entry *cur, *entry;

    cur = cache->chain;
    entry = NULL;

    while( cur != NULL )
    {
        entry = cur;
        cur = cur->next;

#if defined(POLARSSL_HAVE_TIME)
        if( cache->timeout != 0 &&
            (int) ( t - entry->timestamp ) > cache->timeout )
            continue;
#endif

        if( session->ciphersuite != entry->session.ciphersuite ||
            session->compression != entry->session.compression ||
            session->length != entry->session.length )
            continue;

        if( memcmp( session->id, entry->session.id,
                    entry->session.length ) != 0 )
            continue;

        memcpy( session->master, entry->session.master, 48 );

        session->verify_result = entry->session.verify_result;

#if defined(POLARSSL_X509_CRT_PARSE_C)
        /*
         * Restore peer certificate (without rest of the original chain)
         */
        if( entry->peer_cert.p != NULL )
        {
            session->peer_cert = (x509_crt *) polarssl_malloc( sizeof(x509_crt) );
            if( session->peer_cert == NULL )
                return( 1 );

            memset( session->peer_cert, 0, sizeof(x509_crt) );
            if( x509_crt_parse( session->peer_cert, entry->peer_cert.p,
                                entry->peer_cert.len ) != 0 )
            {
                polarssl_free( session->peer_cert );
                session->peer_cert = NULL;
                return( 1 );
            }
        }
#endif /* POLARSSL_X509_CRT_PARSE_C */

        return( 0 );
    }

    return( 1 );
}

int ssl_cache_set( void *data, const ssl_session *session )
{
#if defined(POLARSSL_HAVE_TIME)
    time_t t = time( NULL ), oldest = 0;
    ssl_cache_entry *old = NULL;
#endif
    ssl_cache_context *cache = (ssl_cache_context *) data;
    ssl_cache_entry *cur, *prv;
    int count = 0;

    cur = cache->chain;
    prv = NULL;

    while( cur != NULL )
    {
        count++;

#if defined(POLARSSL_HAVE_TIME)
        if( cache->timeout != 0 &&
            (int) ( t - cur->timestamp ) > cache->timeout )
        {
            cur->timestamp = t;
            break; /* expired, reuse this slot, update timestamp */
        }
#endif

        if( memcmp( session->id, cur->session.id, cur->session.length ) == 0 )
            break; /* client reconnected, keep timestamp for session id */

#if defined(POLARSSL_HAVE_TIME)
        if( oldest == 0 || cur->timestamp < oldest )
        {
            oldest = cur->timestamp;
            old = cur;
        }
#endif

        prv = cur;
        cur = cur->next;
    }

    if( cur == NULL )
    {
#if defined(POLARSSL_HAVE_TIME)
        /*
         * Reuse oldest entry if max_entries reached
         */
        if( old != NULL && count >= cache->max_entries )
        {
            cur = old;
            memset( &cur->session, 0, sizeof(ssl_session) );
#if defined(POLARSSL_X509_CRT_PARSE_C)
            if( cur->peer_cert.p != NULL )
            {
                polarssl_free( cur->peer_cert.p );
                memset( &cur->peer_cert, 0, sizeof(x509_buf) );
            }
#endif /* POLARSSL_X509_CRT_PARSE_C */
        }
#else /* POLARSSL_HAVE_TIME */
        /*
         * Reuse first entry in chain if max_entries reached,
         * but move to last place
         */
        if( count >= cache->max_entries )
        {
            if( cache->chain == NULL )
                return( 1 );

            cur = cache->chain;
            cache->chain = cur->next;

#if defined(POLARSSL_X509_CRT_PARSE_C)
            if( cur->peer_cert.p != NULL )
            {
                polarssl_free( cur->peer_cert.p );
                memset( &cur->peer_cert, 0, sizeof(x509_buf) );
            }
#endif /* POLARSSL_X509_CRT_PARSE_C */

            memset( cur, 0, sizeof(ssl_cache_entry) );
            prv->next = cur;
        }
#endif /* POLARSSL_HAVE_TIME */
        else
        {
            cur = (ssl_cache_entry *) polarssl_malloc( sizeof(ssl_cache_entry) );
            if( cur == NULL )
                return( 1 );

            memset( cur, 0, sizeof(ssl_cache_entry) );

            if( prv == NULL )
                cache->chain = cur;
            else
                prv->next = cur;
        }

#if defined(POLARSSL_HAVE_TIME)
        cur->timestamp = t;
#endif
    }

    memcpy( &cur->session, session, sizeof( ssl_session ) );

#if defined(POLARSSL_X509_CRT_PARSE_C)
    /*
     * Store peer certificate
     */
    if( session->peer_cert != NULL )
    {
        cur->peer_cert.p = (unsigned char *) polarssl_malloc( session->peer_cert->raw.len );
        if( cur->peer_cert.p == NULL )
            return( 1 );

        memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
                session->peer_cert->raw.len );
        cur->peer_cert.len = session->peer_cert->raw.len;

        cur->session.peer_cert = NULL;
    }
#endif /* POLARSSL_X509_CRT_PARSE_C */

    return( 0 );
}

#if defined(POLARSSL_HAVE_TIME)
void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout )
{
    if( timeout < 0 ) timeout = 0;

    cache->timeout = timeout;
}
#endif /* POLARSSL_HAVE_TIME */

void ssl_cache_set_max_entries( ssl_cache_context *cache, int max )
{
    if( max < 0 ) max = 0;

    cache->max_entries = max;
}

void ssl_cache_free( ssl_cache_context *cache )
{
    ssl_cache_entry *cur, *prv;

    cur = cache->chain;

    while( cur != NULL )
    {
        prv = cur;
        cur = cur->next;

        ssl_session_free( &prv->session );

#if defined(POLARSSL_X509_CRT_PARSE_C)
        if( prv->peer_cert.p != NULL )
            polarssl_free( prv->peer_cert.p );
#endif /* POLARSSL_X509_CRT_PARSE_C */

        polarssl_free( prv );
    }
}

#endif /* POLARSSL_SSL_CACHE_C */
