<commit_before>/*
 *  SSLv3/TLSv1 server-side functions
 *
 *  Copyright (C) 2006-2013, Brainspark B.V.
 *
 *  This file is part of PolarSSL (http://www.polarssl.org)
 *  Lead Maintainer: <NAME> <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.
 */

#include "polarssl/config.h"

#if defined(POLARSSL_SSL_SRV_C)

#include "polarssl/debug.h"
#include "polarssl/ssl.h"
#if defined(POLARSSL_ECP_C)
#include "polarssl/ecp.h"
#endif

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

#include <stdlib.h>
#include <stdio.h>

#if defined(POLARSSL_HAVE_TIME)
#include <time.h>
#endif

#if defined(POLARSSL_SSL_SESSION_TICKETS)
/*
 * Serialize a session in the following format:
 *  0   .   n-1     session structure, n = sizeof(ssl_session)
 *  n   .   n+2     peer_cert length = m (0 if no certificate)
 *  n+3 .   n+2+m   peer cert ASN.1
 *
 *  Assumes ticket is NULL (always true on server side).
 */
static int ssl_save_session( const ssl_session *session,
                             unsigned char *buf, size_t buf_len,
                             size_t *olen )
{
    unsigned char *p = buf;
    size_t left = buf_len;
#if defined(POLARSSL_X509_PARSE_C)
    size_t cert_len;
#endif /* POLARSSL_X509_PARSE_C */

    if( left < sizeof( ssl_session ) )
        return( -1 );

    memcpy( p, session, sizeof( ssl_session ) );
    p += sizeof( ssl_session );
    left -= sizeof( ssl_session );

#if defined(POLARSSL_X509_PARSE_C)
    ((ssl_session *) buf)->peer_cert = NULL;

    if( session->peer_cert == NULL )
        cert_len = 0;
    else
        cert_len = session->peer_cert->raw.len;

    if( left < 3 + cert_len )
        return( -1 );

    *p++ = (unsigned char)( cert_len >> 16 & 0xFF );
    *p++ = (unsigned char)( cert_len >>  8 & 0xFF );
    *p++ = (unsigned char)( cert_len       & 0xFF );

    if( session->peer_cert != NULL )
        memcpy( p, session->peer_cert->raw.p, cert_len );

    p += cert_len;
#endif /* POLARSSL_X509_PARSE_C */

    *olen = p - buf;

    return( 0 );
}

/*
 * Unserialise session, see ssl_save_session()
 */
static int ssl_load_session( ssl_session *session,
                             const unsigned char *buf, size_t len )
{
    int ret;
    const unsigned char *p = buf;
    const unsigned char * const end = buf + len;
#if defined(POLARSSL_X509_PARSE_C)
    size_t cert_len;
#endif /* POLARSSL_X509_PARSE_C */

    if( p + sizeof( ssl_session ) > end )
        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );

    memcpy( session, p, sizeof( ssl_session ) );
    p += sizeof( ssl_session );

#if defined(POLARSSL_X509_PARSE_C)
    if( p + 3 > end )
        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );

    cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
    p += 3;

    if( cert_len == 0 )
    {
        session->peer_cert = NULL;
    }
    else
    {
        if( p + cert_len > end )
            return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );

        session->peer_cert = polarssl_malloc( cert_len );

        if( session->peer_cert == NULL )
            return( POLARSSL_ERR_SSL_MALLOC_FAILED );

        memset( session->peer_cert, 0, sizeof( x509_cert ) );

        if( ( ret = x509parse_crt( session->peer_cert, p, cert_len ) ) != 0 )
        {
            polarssl_free( session->peer_cert );
            free( session->peer_cert );
            session->peer_cert = NULL;
            return( ret );
        }

        p += cert_len;
    }
#endif /* POLARSSL_X509_PARSE_C */

    if( p != end )
        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );

    return( 0 );
}

/*
 * Create session ticket, secured as recommended in RFC 5077 section 4:
 *
 *    struct {
 *        opaque key_name[16];
 *        opaque iv[16];
 *        opaque encrypted_state<0..2^16-1>;
 *        opaque mac[32];
 *    } ticket;
 *
 * (the internal state structure differs, however).
 */
static int ssl_write_ticket( ssl_context *ssl, size_t *tlen )
{
    int ret;
    unsigned char * const start = ssl->out_msg + 10;
    unsigned char *p = start;
    unsigned char *state;
    unsigned char iv[16];
    size_t clear_len, enc_len, pad_len, i;

    if( ssl->ticket_keys == NULL )<commit_msg>Fix compiler warning from gcc -Os<commit_after>/*
 *  SSLv3/TLSv1 server-side functions
 *
 *  Copyright (C) 2006-2013, Brainspark B.V.
 *
 *  This file is part of PolarSSL (http://www.polarssl.org)
 *  Lead Maintainer: <NAME> <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.
 */

#include "polarssl/config.h"

#if defined(POLARSSL_SSL_SRV_C)

#include "polarssl/debug.h"
#include "polarssl/ssl.h"
#if defined(POLARSSL_ECP_C)
#include "polarssl/ecp.h"
#endif

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

#include <stdlib.h>
#include <stdio.h>

#if defined(POLARSSL_HAVE_TIME)
#include <time.h>
#endif

#if defined(POLARSSL_SSL_SESSION_TICKETS)
/*
 * Serialize a session in the following format:
 *  0   .   n-1     session structure, n = sizeof(ssl_session)
 *  n   .   n+2     peer_cert length = m (0 if no certificate)
 *  n+3 .   n+2+m   peer cert ASN.1
 *
 *  Assumes ticket is NULL (always true on server side).
 */
static int ssl_save_session( const ssl_session *session,
                             unsigned char *buf, size_t buf_len,
                             size_t *olen )
{
    unsigned char *p = buf;
    size_t left = buf_len;
#if defined(POLARSSL_X509_PARSE_C)
    size_t cert_len;
#endif /* POLARSSL_X509_PARSE_C */

    if( left < sizeof( ssl_session ) )
        return( -1 );

    memcpy( p, session, sizeof( ssl_session ) );
    p += sizeof( ssl_session );
    left -= sizeof( ssl_session );

#if defined(POLARSSL_X509_PARSE_C)
    ((ssl_session *) buf)->peer_cert = NULL;

    if( session->peer_cert == NULL )
        cert_len = 0;
    else
        cert_len = session->peer_cert->raw.len;

    if( left < 3 + cert_len )
        return( -1 );

    *p++ = (unsigned char)( cert_len >> 16 & 0xFF );
    *p++ = (unsigned char)( cert_len >>  8 & 0xFF );
    *p++ = (unsigned char)( cert_len       & 0xFF );

    if( session->peer_cert != NULL )
        memcpy( p, session->peer_cert->raw.p, cert_len );

    p += cert_len;
#endif /* POLARSSL_X509_PARSE_C */

    *olen = p - buf;

    return( 0 );
}

/*
 * Unserialise session, see ssl_save_session()
 */
static int ssl_load_session( ssl_session *session,
                             const unsigned char *buf, size_t len )
{
    int ret;
    const unsigned char *p = buf;
    const unsigned char * const end = buf + len;
#if defined(POLARSSL_X509_PARSE_C)
    size_t cert_len;
#endif /* POLARSSL_X509_PARSE_C */

    if( p + sizeof( ssl_session ) > end )
        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );

    memcpy( session, p, sizeof( ssl_session ) );
    p += sizeof( ssl_session );

#if defined(POLARSSL_X509_PARSE_C)
    if( p + 3 > end )
        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );

    cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
    p += 3;

    if( cert_len == 0 )
    {
        session->peer_cert = NULL;
    }
    else
    {
        if( p + cert_len > end )
            return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );

        session->peer_cert = polarssl_malloc( cert_len );

        if( session->peer_cert == NULL )
            return( POLARSSL_ERR_SSL_MALLOC_FAILED );

        memset( session->peer_cert, 0, sizeof( x509_cert ) );

        if( ( ret = x509parse_crt( session->peer_cert, p, cert_len ) ) != 0 )
        {
            polarssl_free( session->peer_cert );
            free( session->peer_cert );
            session->peer_cert = NULL;
            return( ret );
        }

        p += cert_len;
    }
#endif /* POLARSSL_X509_PARSE_C */

    if( p != end )
        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );

    return( 0 );
}

/*
 * Create session ticket, secured as recommended in RFC 5077 section 4:
 *
 *    struct {
 *        opaque key_name[16];
 *        opaque iv[16];
 *        opaque encrypted_state<0..2^16-1>;
 *        opaque mac[32];
 *    } ticket;
 *
 * (the internal state structure differs, however).
 */
static int ssl_write_ticket( ssl_context *ssl, size_t *tlen )
{
    int ret;
    unsigned char * const start = ssl->out_msg + 10;
    unsigned char *p = start;
    unsigned char *state;
    unsigned char iv[16];
    size_t clear_len, enc_len, pad_len, i;

    *tlen = 0;

    if( ssl->ticket_keys == NULL )
{'fraction_non_alphanumeric': 0.11276681433749497, 'fraction_numerical': 0.020640354409987918, 'mean_word_length': 2.6002174700978617, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2923963', 'n_tokens_mistral': 3596, 'n_tokens_neox': 3368, 'n_words': 971}