PolarSSL v1.3.1
Main Page
Modules
Data Structures
Files
File List
Globals
library
ssl_cache.c
Go to the documentation of this file.
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
#if defined(POLARSSL_MEMORY_C)
37
#include "
polarssl/memory.h
"
38
#else
39
#define polarssl_malloc malloc
40
#define polarssl_free free
41
#endif
42
43
#include <stdlib.h>
44
45
void
ssl_cache_init
(
ssl_cache_context
*cache )
46
{
47
memset( cache, 0,
sizeof
(
ssl_cache_context
) );
48
49
cache->
timeout
=
SSL_CACHE_DEFAULT_TIMEOUT
;
50
cache->
max_entries
=
SSL_CACHE_DEFAULT_MAX_ENTRIES
;
51
52
#if defined(POLARSSL_THREADING_C)
53
polarssl_mutex_init
( &cache->mutex );
54
#endif
55
}
56
57
int
ssl_cache_get
(
void
*data,
ssl_session
*session )
58
{
59
int
ret = 1;
60
#if defined(POLARSSL_HAVE_TIME)
61
time_t t = time( NULL );
62
#endif
63
ssl_cache_context
*cache = (
ssl_cache_context
*) data;
64
ssl_cache_entry
*cur, *entry;
65
66
#if defined(POLARSSL_THREADING_C)
67
if
(
polarssl_mutex_lock
( &cache->mutex ) != 0 )
68
return
( 1 );
69
#endif
70
71
cur = cache->
chain
;
72
entry = NULL;
73
74
while
( cur != NULL )
75
{
76
entry = cur;
77
cur = cur->
next
;
78
79
#if defined(POLARSSL_HAVE_TIME)
80
if
( cache->
timeout
!= 0 &&
81
(
int
) ( t - entry->
timestamp
) > cache->
timeout
)
82
continue
;
83
#endif
84
85
if
( session->
ciphersuite
!= entry->
session
.
ciphersuite
||
86
session->
compression
!= entry->
session
.
compression
||
87
session->
length
!= entry->
session
.
length
)
88
continue
;
89
90
if
( memcmp( session->
id
, entry->
session
.
id
,
91
entry->
session
.
length
) != 0 )
92
continue
;
93
94
memcpy( session->
master
, entry->
session
.
master
, 48 );
95
96
session->
verify_result
= entry->
session
.
verify_result
;
97
98
#if defined(POLARSSL_X509_CRT_PARSE_C)
99
/*
100
* Restore peer certificate (without rest of the original chain)
101
*/
102
if
( entry->
peer_cert
.
p
!= NULL )
103
{
104
session->
peer_cert
= (
x509_crt
*)
polarssl_malloc
(
sizeof
(
x509_crt
) );
105
if
( session->
peer_cert
== NULL )
106
{
107
ret = 1;
108
goto
exit;
109
}
110
111
x509_crt_init
( session->
peer_cert
);
112
if
(
x509_crt_parse
( session->
peer_cert
, entry->
peer_cert
.
p
,
113
entry->
peer_cert
.
len
) != 0 )
114
{
115
polarssl_free
( session->
peer_cert
);
116
session->
peer_cert
= NULL;
117
ret = 1;
118
goto
exit;
119
}
120
}
121
#endif
/* POLARSSL_X509_CRT_PARSE_C */
122
123
ret = 0;
124
goto
exit;
125
}
126
127
exit:
128
#if defined(POLARSSL_THREADING_C)
129
if
(
polarssl_mutex_unlock
( &cache->mutex ) != 0 )
130
ret = 1;
131
#endif
132
133
return
( ret );
134
}
135
136
int
ssl_cache_set
(
void
*data,
const
ssl_session
*session )
137
{
138
int
ret = 1;
139
#if defined(POLARSSL_HAVE_TIME)
140
time_t t = time( NULL ), oldest = 0;
141
ssl_cache_entry
*old = NULL;
142
#endif
143
ssl_cache_context
*cache = (
ssl_cache_context
*) data;
144
ssl_cache_entry
*cur, *prv;
145
int
count = 0;
146
147
#if defined(POLARSSL_THREADING_C)
148
if
( ( ret =
polarssl_mutex_lock
( &cache->mutex ) ) != 0 )
149
return
( ret );
150
#endif
151
152
cur = cache->
chain
;
153
prv = NULL;
154
155
while
( cur != NULL )
156
{
157
count++;
158
159
#if defined(POLARSSL_HAVE_TIME)
160
if
( cache->
timeout
!= 0 &&
161
(
int
) ( t - cur->
timestamp
) > cache->
timeout
)
162
{
163
cur->
timestamp
= t;
164
break
;
/* expired, reuse this slot, update timestamp */
165
}
166
#endif
167
168
if
( memcmp( session->
id
, cur->
session
.
id
, cur->
session
.
length
) == 0 )
169
break
;
/* client reconnected, keep timestamp for session id */
170
171
#if defined(POLARSSL_HAVE_TIME)
172
if
( oldest == 0 || cur->
timestamp
< oldest )
173
{
174
oldest = cur->
timestamp
;
175
old = cur;
176
}
177
#endif
178
179
prv = cur;
180
cur = cur->
next
;
181
}
182
183
if
( cur == NULL )
184
{
185
#if defined(POLARSSL_HAVE_TIME)
186
/*
187
* Reuse oldest entry if max_entries reached
188
*/
189
if
( old != NULL && count >= cache->
max_entries
)
190
{
191
cur = old;
192
memset( &cur->
session
, 0,
sizeof
(
ssl_session
) );
193
#if defined(POLARSSL_X509_CRT_PARSE_C)
194
if
( cur->
peer_cert
.
p
!= NULL )
195
{
196
polarssl_free
( cur->
peer_cert
.
p
);
197
memset( &cur->
peer_cert
, 0,
sizeof
(
x509_buf
) );
198
}
199
#endif
/* POLARSSL_X509_CRT_PARSE_C */
200
}
201
#else
/* POLARSSL_HAVE_TIME */
202
/*
203
* Reuse first entry in chain if max_entries reached,
204
* but move to last place
205
*/
206
if
( count >= cache->
max_entries
)
207
{
208
if
( cache->
chain
== NULL )
209
{
210
ret = 1;
211
goto
exit;
212
}
213
214
cur = cache->
chain
;
215
cache->
chain
= cur->
next
;
216
217
#if defined(POLARSSL_X509_CRT_PARSE_C)
218
if
( cur->
peer_cert
.
p
!= NULL )
219
{
220
polarssl_free
( cur->
peer_cert
.
p
);
221
memset( &cur->
peer_cert
, 0,
sizeof
(
x509_buf
) );
222
}
223
#endif
/* POLARSSL_X509_CRT_PARSE_C */
224
225
memset( cur, 0,
sizeof
(
ssl_cache_entry
) );
226
prv->
next
= cur;
227
}
228
#endif
/* POLARSSL_HAVE_TIME */
229
else
230
{
231
cur = (
ssl_cache_entry
*)
polarssl_malloc
(
sizeof
(
ssl_cache_entry
) );
232
if
( cur == NULL )
233
{
234
ret = 1;
235
goto
exit;
236
}
237
238
memset( cur, 0,
sizeof
(
ssl_cache_entry
) );
239
240
if
( prv == NULL )
241
cache->
chain
= cur;
242
else
243
prv->
next
= cur;
244
}
245
246
#if defined(POLARSSL_HAVE_TIME)
247
cur->
timestamp
= t;
248
#endif
249
}
250
251
memcpy( &cur->
session
, session,
sizeof
(
ssl_session
) );
252
253
#if defined(POLARSSL_X509_CRT_PARSE_C)
254
/*
255
* Store peer certificate
256
*/
257
if
( session->
peer_cert
!= NULL )
258
{
259
cur->
peer_cert
.
p
= (
unsigned
char
*)
polarssl_malloc
( session->
peer_cert
->
raw
.
len
);
260
if
( cur->
peer_cert
.
p
== NULL )
261
{
262
ret = 1;
263
goto
exit;
264
}
265
266
memcpy( cur->
peer_cert
.
p
, session->
peer_cert
->
raw
.
p
,
267
session->
peer_cert
->
raw
.
len
);
268
cur->
peer_cert
.
len
= session->
peer_cert
->
raw
.
len
;
269
270
cur->
session
.
peer_cert
= NULL;
271
}
272
#endif
/* POLARSSL_X509_CRT_PARSE_C */
273
274
ret = 0;
275
276
exit:
277
#if defined(POLARSSL_THREADING_C)
278
if
(
polarssl_mutex_unlock
( &cache->mutex ) != 0 )
279
ret = 1;
280
#endif
281
282
return
( ret );
283
}
284
285
#if defined(POLARSSL_HAVE_TIME)
286
void
ssl_cache_set_timeout
(
ssl_cache_context
*cache,
int
timeout )
287
{
288
if
( timeout < 0 ) timeout = 0;
289
290
cache->
timeout
= timeout;
291
}
292
#endif
/* POLARSSL_HAVE_TIME */
293
294
void
ssl_cache_set_max_entries
(
ssl_cache_context
*cache,
int
max )
295
{
296
if
( max < 0 ) max = 0;
297
298
cache->
max_entries
= max;
299
}
300
301
void
ssl_cache_free
(
ssl_cache_context
*cache )
302
{
303
ssl_cache_entry
*cur, *prv;
304
305
cur = cache->
chain
;
306
307
while
( cur != NULL )
308
{
309
prv = cur;
310
cur = cur->
next
;
311
312
ssl_session_free
( &prv->
session
);
313
314
#if defined(POLARSSL_X509_CRT_PARSE_C)
315
if
( prv->
peer_cert
.
p
!= NULL )
316
polarssl_free
( prv->
peer_cert
.
p
);
317
#endif
/* POLARSSL_X509_CRT_PARSE_C */
318
319
polarssl_free
( prv );
320
}
321
322
#if defined(POLARSSL_THREADING_C)
323
polarssl_mutex_free
( &cache->mutex );
324
#endif
325
}
326
327
#endif
/* POLARSSL_SSL_CACHE_C */
Generated on Fri Nov 22 2013 08:28:27 for PolarSSL v1.3.1 by
1.8.3