PolarSSL v1.2.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-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 */
Generated on Wed Oct 2 2013 22:02:11 for PolarSSL v1.2.9 by
1.8.3.1