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