~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/polarssl/library/ssl_cache.c

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  SSL session cache implementation
 
3
 *
 
4
 *  Copyright (C) 2006-2012, Brainspark B.V.
 
5
 *
 
6
 *  This file is part of PolarSSL (http://www.polarssl.org)
 
7
 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
 
8
 *
 
9
 *  All rights reserved.
 
10
 *
 
11
 *  This program is free software; you can redistribute it and/or modify
 
12
 *  it under the terms of the GNU General Public License as published by
 
13
 *  the Free Software Foundation; either version 2 of the License, or
 
14
 *  (at your option) any later version.
 
15
 *
 
16
 *  This program is distributed in the hope that it will be useful,
 
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
 *  GNU General Public License for more details.
 
20
 *
 
21
 *  You should have received a copy of the GNU General Public License along
 
22
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 
23
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
24
 */
 
25
/*
 
26
 * These session callbacks use a simple chained list
 
27
 * to store and retrieve the session information.
 
28
 */
 
29
 
 
30
#include "polarssl/config.h"
 
31
 
 
32
#if defined(POLARSSL_SSL_CACHE_C)
 
33
 
 
34
#include "polarssl/ssl_cache.h"
 
35
 
 
36
#include <stdlib.h>
 
37
 
 
38
void ssl_cache_init( ssl_cache_context *cache )
 
39
{
 
40
    memset( cache, 0, sizeof( ssl_cache_context ) );
 
41
 
 
42
    cache->timeout = SSL_CACHE_DEFAULT_TIMEOUT;
 
43
    cache->max_entries = SSL_CACHE_DEFAULT_MAX_ENTRIES;
 
44
}
 
45
 
 
46
int ssl_cache_get( void *data, ssl_session *session )
 
47
{
 
48
    time_t t = time( NULL );
 
49
    ssl_cache_context *cache = (ssl_cache_context *) data;
 
50
    ssl_cache_entry *cur, *entry;
 
51
 
 
52
    cur = cache->chain;
 
53
    entry = NULL;
 
54
 
 
55
    while( cur != NULL )
 
56
    {
 
57
        entry = cur;
 
58
        cur = cur->next;
 
59
 
 
60
        if( cache->timeout != 0 &&
 
61
            (int) ( t - entry->timestamp ) > cache->timeout )
 
62
            continue;
 
63
 
 
64
        if( session->ciphersuite != entry->session.ciphersuite ||
 
65
            session->compression != entry->session.compression ||
 
66
            session->length != entry->session.length )
 
67
            continue;
 
68
 
 
69
        if( memcmp( session->id, entry->session.id,
 
70
                    entry->session.length ) != 0 )
 
71
            continue;
 
72
 
 
73
        memcpy( session->master, entry->session.master, 48 );
 
74
 
 
75
        /*
 
76
         * Restore peer certificate (without rest of the original chain)
 
77
         */
 
78
        if( entry->peer_cert.p != NULL )
 
79
        {
 
80
            session->peer_cert = (x509_cert *) malloc( sizeof(x509_cert) );
 
81
            if( session->peer_cert == NULL )
 
82
                return( 1 );
 
83
 
 
84
            memset( session->peer_cert, 0, sizeof(x509_cert) );
 
85
            if( x509parse_crt( session->peer_cert, entry->peer_cert.p,
 
86
                               entry->peer_cert.len ) != 0 )
 
87
            {
 
88
                free( session->peer_cert );
 
89
                session->peer_cert = NULL;
 
90
                return( 1 );
 
91
            }
 
92
        }
 
93
 
 
94
        return( 0 );
 
95
    }
 
96
 
 
97
    return( 1 );
 
98
}
 
99
 
 
100
int ssl_cache_set( void *data, const ssl_session *session )
 
101
{
 
102
    time_t t = time( NULL ), oldest = 0;
 
103
    ssl_cache_context *cache = (ssl_cache_context *) data;
 
104
    ssl_cache_entry *cur, *prv, *old = NULL;
 
105
    int count = 0;
 
106
 
 
107
    cur = cache->chain;
 
108
    prv = NULL;
 
109
 
 
110
    while( cur != NULL )
 
111
    {
 
112
        count++;
 
113
 
 
114
        if( cache->timeout != 0 &&
 
115
            (int) ( t - cur->timestamp ) > cache->timeout )
 
116
        {
 
117
            cur->timestamp = t;
 
118
            break; /* expired, reuse this slot, update timestamp */
 
119
        }
 
120
 
 
121
        if( memcmp( session->id, cur->session.id, cur->session.length ) == 0 )
 
122
            break; /* client reconnected, keep timestamp for session id */
 
123
 
 
124
        if( oldest == 0 || cur->timestamp < oldest )
 
125
        {
 
126
            oldest = cur->timestamp;
 
127
            old = cur;
 
128
        }
 
129
 
 
130
        prv = cur;
 
131
        cur = cur->next;
 
132
    }
 
133
 
 
134
    if( cur == NULL )
 
135
    {
 
136
        /*
 
137
         * Reuse oldest entry if max_entries reached
 
138
         */
 
139
        if( old != NULL && count >= cache->max_entries )
 
140
        {
 
141
            cur = old;
 
142
            memset( &cur->session, 0, sizeof(ssl_session) );
 
143
            if( cur->peer_cert.p != NULL )
 
144
            {
 
145
                free( cur->peer_cert.p );
 
146
                memset( &cur->peer_cert, 0, sizeof(x509_buf) );
 
147
            }
 
148
        }
 
149
        else
 
150
        {
 
151
            cur = (ssl_cache_entry *) malloc( sizeof(ssl_cache_entry) );
 
152
            if( cur == NULL )
 
153
                return( 1 );
 
154
 
 
155
            memset( cur, 0, sizeof(ssl_cache_entry) );
 
156
 
 
157
            if( prv == NULL )
 
158
                cache->chain = cur;
 
159
            else
 
160
                prv->next = cur;
 
161
        }
 
162
 
 
163
        cur->timestamp = t;
 
164
    }
 
165
 
 
166
    memcpy( &cur->session, session, sizeof( ssl_session ) );
 
167
    
 
168
    /*
 
169
     * Store peer certificate
 
170
     */
 
171
    if( session->peer_cert != NULL )
 
172
    {
 
173
        cur->peer_cert.p = (unsigned char *) malloc( session->peer_cert->raw.len );
 
174
        if( cur->peer_cert.p == NULL )
 
175
            return( 1 );
 
176
 
 
177
        memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
 
178
                session->peer_cert->raw.len );
 
179
        cur->peer_cert.len = session->peer_cert->raw.len;
 
180
 
 
181
        cur->session.peer_cert = NULL;
 
182
    }
 
183
 
 
184
    return( 0 );
 
185
}
 
186
 
 
187
void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout )
 
188
{
 
189
    if( timeout < 0 ) timeout = 0;
 
190
 
 
191
    cache->timeout = timeout;
 
192
}
 
193
 
 
194
void ssl_cache_set_max_entries( ssl_cache_context *cache, int max )
 
195
{
 
196
    if( max < 0 ) max = 0;
 
197
 
 
198
    cache->max_entries = max;
 
199
}
 
200
 
 
201
void ssl_cache_free( ssl_cache_context *cache )
 
202
{
 
203
    ssl_cache_entry *cur, *prv;
 
204
 
 
205
    cur = cache->chain;
 
206
 
 
207
    while( cur != NULL )
 
208
    {
 
209
        prv = cur;
 
210
        cur = cur->next;
 
211
 
 
212
        ssl_session_free( &prv->session );
 
213
 
 
214
        if( prv->peer_cert.p != NULL )
 
215
            free( prv->peer_cert.p );
 
216
 
 
217
        free( prv );
 
218
    }
 
219
}
 
220
 
 
221
#endif /* POLARSSL_SSL_CACHE_C */