Branch data Line data Source code
1 : : /* ssl/ssl_sess.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
7 : : * The implementation was written so as to conform with Netscapes SSL.
8 : : *
9 : : * This library is free for commercial and non-commercial use as long as
10 : : * the following conditions are aheared to. The following conditions
11 : : * apply to all code found in this distribution, be it the RC4, RSA,
12 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : : * included with this distribution is covered by the same copyright terms
14 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : : *
16 : : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : : * the code are not to be removed.
18 : : * If this package is used in a product, Eric Young should be given attribution
19 : : * as the author of the parts of the library used.
20 : : * This can be in the form of a textual message at program startup or
21 : : * in documentation (online or textual) provided with the package.
22 : : *
23 : : * Redistribution and use in source and binary forms, with or without
24 : : * modification, are permitted provided that the following conditions
25 : : * are met:
26 : : * 1. Redistributions of source code must retain the copyright
27 : : * notice, this list of conditions and the following disclaimer.
28 : : * 2. Redistributions in binary form must reproduce the above copyright
29 : : * notice, this list of conditions and the following disclaimer in the
30 : : * documentation and/or other materials provided with the distribution.
31 : : * 3. All advertising materials mentioning features or use of this software
32 : : * must display the following acknowledgement:
33 : : * "This product includes cryptographic software written by
34 : : * Eric Young (eay@cryptsoft.com)"
35 : : * The word 'cryptographic' can be left out if the rouines from the library
36 : : * being used are not cryptographic related :-).
37 : : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : : * the apps directory (application code) you must include an acknowledgement:
39 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : : *
41 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : : * SUCH DAMAGE.
52 : : *
53 : : * The licence and distribution terms for any publically available version or
54 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : : * copied and put under another distribution licence
56 : : * [including the GNU Public Licence.]
57 : : */
58 : : /* ====================================================================
59 : : * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 : : *
61 : : * Redistribution and use in source and binary forms, with or without
62 : : * modification, are permitted provided that the following conditions
63 : : * are met:
64 : : *
65 : : * 1. Redistributions of source code must retain the above copyright
66 : : * notice, this list of conditions and the following disclaimer.
67 : : *
68 : : * 2. Redistributions in binary form must reproduce the above copyright
69 : : * notice, this list of conditions and the following disclaimer in
70 : : * the documentation and/or other materials provided with the
71 : : * distribution.
72 : : *
73 : : * 3. All advertising materials mentioning features or use of this
74 : : * software must display the following acknowledgment:
75 : : * "This product includes software developed by the OpenSSL Project
76 : : * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 : : *
78 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 : : * endorse or promote products derived from this software without
80 : : * prior written permission. For written permission, please contact
81 : : * openssl-core@openssl.org.
82 : : *
83 : : * 5. Products derived from this software may not be called "OpenSSL"
84 : : * nor may "OpenSSL" appear in their names without prior written
85 : : * permission of the OpenSSL Project.
86 : : *
87 : : * 6. Redistributions of any form whatsoever must retain the following
88 : : * acknowledgment:
89 : : * "This product includes software developed by the OpenSSL Project
90 : : * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 : : *
92 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
104 : : * ====================================================================
105 : : *
106 : : * This product includes cryptographic software written by Eric Young
107 : : * (eay@cryptsoft.com). This product includes software written by Tim
108 : : * Hudson (tjh@cryptsoft.com).
109 : : *
110 : : */
111 : : /* ====================================================================
112 : : * Copyright 2005 Nokia. All rights reserved.
113 : : *
114 : : * The portions of the attached software ("Contribution") is developed by
115 : : * Nokia Corporation and is licensed pursuant to the OpenSSL open source
116 : : * license.
117 : : *
118 : : * The Contribution, originally written by Mika Kousa and Pasi Eronen of
119 : : * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
120 : : * support (see RFC 4279) to OpenSSL.
121 : : *
122 : : * No patent licenses or other rights except those expressly stated in
123 : : * the OpenSSL open source license shall be deemed granted or received
124 : : * expressly, by implication, estoppel, or otherwise.
125 : : *
126 : : * No assurances are provided by Nokia that the Contribution does not
127 : : * infringe the patent or other intellectual property rights of any third
128 : : * party or that the license provides you with all the necessary rights
129 : : * to make use of the Contribution.
130 : : *
131 : : * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
132 : : * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
133 : : * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
134 : : * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
135 : : * OTHERWISE.
136 : : */
137 : :
138 : : #include <stdio.h>
139 : : #include <openssl/lhash.h>
140 : : #include <openssl/rand.h>
141 : : #ifndef OPENSSL_NO_ENGINE
142 : : #include <openssl/engine.h>
143 : : #endif
144 : : #include "ssl_locl.h"
145 : :
146 : : static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
147 : : static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
148 : : static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
149 : :
150 : 0 : SSL_SESSION *SSL_get_session(const SSL *ssl)
151 : : /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
152 : : {
153 : 0 : return(ssl->session);
154 : : }
155 : :
156 : 0 : SSL_SESSION *SSL_get1_session(SSL *ssl)
157 : : /* variant of SSL_get_session: caller really gets something */
158 : : {
159 : : SSL_SESSION *sess;
160 : : /* Need to lock this all up rather than just use CRYPTO_add so that
161 : : * somebody doesn't free ssl->session between when we check it's
162 : : * non-null and when we up the reference count. */
163 : 0 : CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION);
164 : 0 : sess = ssl->session;
165 [ # # ]: 0 : if(sess)
166 : 0 : sess->references++;
167 : 0 : CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION);
168 : 0 : return(sess);
169 : : }
170 : :
171 : 0 : int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
172 : : CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
173 : : {
174 : 0 : return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
175 : : new_func, dup_func, free_func);
176 : : }
177 : :
178 : 0 : int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
179 : : {
180 : 0 : return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
181 : : }
182 : :
183 : 0 : void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)
184 : : {
185 : 0 : return(CRYPTO_get_ex_data(&s->ex_data,idx));
186 : : }
187 : :
188 : 3235 : SSL_SESSION *SSL_SESSION_new(void)
189 : : {
190 : : SSL_SESSION *ss;
191 : :
192 : 3235 : ss=(SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
193 [ - + ]: 3235 : if (ss == NULL)
194 : : {
195 : 0 : SSLerr(SSL_F_SSL_SESSION_NEW,ERR_R_MALLOC_FAILURE);
196 : 0 : return(0);
197 : : }
198 : : memset(ss,0,sizeof(SSL_SESSION));
199 : :
200 : 3235 : ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
201 : 3235 : ss->references=1;
202 : 3235 : ss->timeout=60*5+4; /* 5 minute timeout by default */
203 : 3235 : ss->time=(unsigned long)time(NULL);
204 : 3235 : ss->prev=NULL;
205 : 3235 : ss->next=NULL;
206 : 3235 : ss->compress_meth=0;
207 : : #ifndef OPENSSL_NO_TLSEXT
208 : 3235 : ss->tlsext_hostname = NULL;
209 : : #ifndef OPENSSL_NO_EC
210 : 3235 : ss->tlsext_ecpointformatlist_length = 0;
211 : 3235 : ss->tlsext_ecpointformatlist = NULL;
212 : 3235 : ss->tlsext_ellipticcurvelist_length = 0;
213 : 3235 : ss->tlsext_ellipticcurvelist = NULL;
214 : : #endif
215 : : #endif
216 : 3235 : CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
217 : : #ifndef OPENSSL_NO_PSK
218 : 3235 : ss->psk_identity_hint=NULL;
219 : 3235 : ss->psk_identity=NULL;
220 : : #endif
221 : : #ifndef OPENSSL_NO_SRP
222 : 3235 : ss->srp_username=NULL;
223 : : #endif
224 : 3235 : return(ss);
225 : : }
226 : :
227 : 0 : const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
228 : : {
229 [ # # ]: 0 : if(len)
230 : 0 : *len = s->session_id_length;
231 : 0 : return s->session_id;
232 : : }
233 : :
234 : 0 : unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s)
235 : : {
236 : 0 : return s->compress_meth;
237 : : }
238 : :
239 : : /* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1
240 : : * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly
241 : : * until we have no conflict is going to complete in one iteration pretty much
242 : : * "most" of the time (btw: understatement). So, if it takes us 10 iterations
243 : : * and we still can't avoid a conflict - well that's a reasonable point to call
244 : : * it quits. Either the RAND code is broken or someone is trying to open roughly
245 : : * very close to 2^128 (or 2^256) SSL sessions to our server. How you might
246 : : * store that many sessions is perhaps a more interesting question ... */
247 : :
248 : : #define MAX_SESS_ID_ATTEMPTS 10
249 : 385 : static int def_generate_session_id(const SSL *ssl, unsigned char *id,
250 : : unsigned int *id_len)
251 : : {
252 : 385 : unsigned int retry = 0;
253 : : do
254 [ + - ]: 385 : if (RAND_pseudo_bytes(id, *id_len) <= 0)
255 : : return 0;
256 [ # # ]: 385 : while(SSL_has_matching_session_id(ssl, id, *id_len) &&
257 [ - + ]: 385 : (++retry < MAX_SESS_ID_ATTEMPTS));
258 [ - + ]: 385 : if(retry < MAX_SESS_ID_ATTEMPTS)
259 : : return 1;
260 : : /* else - woops a session_id match */
261 : : /* XXX We should also check the external cache --
262 : : * but the probability of a collision is negligible, and
263 : : * we could not prevent the concurrent creation of sessions
264 : : * with identical IDs since we currently don't have means
265 : : * to atomically check whether a session ID already exists
266 : : * and make a reservation for it if it does not
267 : : * (this problem applies to the internal cache as well).
268 : : */
269 : 0 : return 0;
270 : : }
271 : :
272 : 2402 : int ssl_get_new_session(SSL *s, int session)
273 : : {
274 : : /* This gets used by clients and servers. */
275 : :
276 : : unsigned int tmp;
277 : 2402 : SSL_SESSION *ss=NULL;
278 : 2402 : GEN_SESSION_CB cb = def_generate_session_id;
279 : :
280 [ + - ]: 2402 : if ((ss=SSL_SESSION_new()) == NULL) return(0);
281 : :
282 : : /* If the context has a default timeout, use it */
283 [ - + ]: 2402 : if (s->session_ctx->session_timeout == 0)
284 : 0 : ss->timeout=SSL_get_default_timeout(s);
285 : : else
286 : 2402 : ss->timeout=s->session_ctx->session_timeout;
287 : :
288 [ + + ]: 2402 : if (s->session != NULL)
289 : : {
290 : 308 : SSL_SESSION_free(s->session);
291 : 308 : s->session=NULL;
292 : : }
293 : :
294 [ + + ]: 2402 : if (session)
295 : : {
296 [ + + ]: 1201 : if (s->version == SSL2_VERSION)
297 : : {
298 : 132 : ss->ssl_version=SSL2_VERSION;
299 : 132 : ss->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
300 : : }
301 [ + + ]: 1069 : else if (s->version == SSL3_VERSION)
302 : : {
303 : 253 : ss->ssl_version=SSL3_VERSION;
304 : 253 : ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
305 : : }
306 [ + + ]: 816 : else if (s->version == TLS1_VERSION)
307 : : {
308 : 616 : ss->ssl_version=TLS1_VERSION;
309 : 616 : ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
310 : : }
311 [ - + ]: 200 : else if (s->version == TLS1_1_VERSION)
312 : : {
313 : 0 : ss->ssl_version=TLS1_1_VERSION;
314 : 0 : ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
315 : : }
316 [ + - ]: 200 : else if (s->version == TLS1_2_VERSION)
317 : : {
318 : 200 : ss->ssl_version=TLS1_2_VERSION;
319 : 200 : ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
320 : : }
321 [ # # ]: 0 : else if (s->version == DTLS1_BAD_VER)
322 : : {
323 : 0 : ss->ssl_version=DTLS1_BAD_VER;
324 : 0 : ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
325 : : }
326 [ # # ]: 0 : else if (s->version == DTLS1_VERSION)
327 : : {
328 : 0 : ss->ssl_version=DTLS1_VERSION;
329 : 0 : ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
330 : : }
331 [ # # ]: 0 : else if (s->version == DTLS1_2_VERSION)
332 : : {
333 : 0 : ss->ssl_version=DTLS1_2_VERSION;
334 : 0 : ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
335 : : }
336 : : else
337 : : {
338 : 0 : SSLerr(SSL_F_SSL_GET_NEW_SESSION,SSL_R_UNSUPPORTED_SSL_VERSION);
339 : 0 : SSL_SESSION_free(ss);
340 : 0 : return(0);
341 : : }
342 : : #ifndef OPENSSL_NO_TLSEXT
343 : : /* If RFC4507 ticket use empty session ID */
344 [ + + ]: 1201 : if (s->tlsext_ticket_expected)
345 : : {
346 : 816 : ss->session_id_length = 0;
347 : 816 : goto sess_id_done;
348 : : }
349 : : #endif
350 : : /* Choose which callback will set the session ID */
351 : 385 : CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
352 [ + - ]: 385 : if(s->generate_session_id)
353 : : cb = s->generate_session_id;
354 [ - + ]: 385 : else if(s->session_ctx->generate_session_id)
355 : 0 : cb = s->session_ctx->generate_session_id;
356 : 385 : CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
357 : : /* Choose a session ID */
358 : 385 : tmp = ss->session_id_length;
359 [ - + ]: 385 : if(!cb(s, ss->session_id, &tmp))
360 : : {
361 : : /* The callback failed */
362 : 0 : SSLerr(SSL_F_SSL_GET_NEW_SESSION,
363 : : SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
364 : 0 : SSL_SESSION_free(ss);
365 : 0 : return(0);
366 : : }
367 : : /* Don't allow the callback to set the session length to zero.
368 : : * nor set it higher than it was. */
369 [ + - ][ - + ]: 385 : if(!tmp || (tmp > ss->session_id_length))
370 : : {
371 : : /* The callback set an illegal length */
372 : 0 : SSLerr(SSL_F_SSL_GET_NEW_SESSION,
373 : : SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
374 : 0 : SSL_SESSION_free(ss);
375 : 0 : return(0);
376 : : }
377 : : /* If the session length was shrunk and we're SSLv2, pad it */
378 [ - + ][ # # ]: 385 : if((tmp < ss->session_id_length) && (s->version == SSL2_VERSION))
379 : 0 : memset(ss->session_id + tmp, 0, ss->session_id_length - tmp);
380 : : else
381 : 385 : ss->session_id_length = tmp;
382 : : /* Finally, check for a conflict */
383 [ - + ]: 385 : if(SSL_has_matching_session_id(s, ss->session_id,
384 : : ss->session_id_length))
385 : : {
386 : 0 : SSLerr(SSL_F_SSL_GET_NEW_SESSION,
387 : : SSL_R_SSL_SESSION_ID_CONFLICT);
388 : 0 : SSL_SESSION_free(ss);
389 : 0 : return(0);
390 : : }
391 : : #ifndef OPENSSL_NO_TLSEXT
392 : : sess_id_done:
393 [ - + ]: 1201 : if (s->tlsext_hostname) {
394 : 0 : ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
395 [ # # ]: 0 : if (ss->tlsext_hostname == NULL) {
396 : 0 : SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
397 : 0 : SSL_SESSION_free(ss);
398 : 0 : return 0;
399 : : }
400 : : }
401 : : #endif
402 : : }
403 : : else
404 : : {
405 : 1201 : ss->session_id_length=0;
406 : : }
407 : :
408 [ - + ]: 2402 : if (s->sid_ctx_length > sizeof ss->sid_ctx)
409 : : {
410 : 0 : SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
411 : 0 : SSL_SESSION_free(ss);
412 : 0 : return 0;
413 : : }
414 : 2402 : memcpy(ss->sid_ctx,s->sid_ctx,s->sid_ctx_length);
415 : 2402 : ss->sid_ctx_length=s->sid_ctx_length;
416 : 2402 : s->session=ss;
417 : 2402 : ss->ssl_version=s->version;
418 : 2402 : ss->verify_result = X509_V_OK;
419 : :
420 : 2402 : return(1);
421 : : }
422 : :
423 : : /* ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
424 : : * connection. It is only called by servers.
425 : : *
426 : : * session_id: points at the session ID in the ClientHello. This code will
427 : : * read past the end of this in order to parse out the session ticket
428 : : * extension, if any.
429 : : * len: the length of the session ID.
430 : : * limit: a pointer to the first byte after the ClientHello.
431 : : *
432 : : * Returns:
433 : : * -1: error
434 : : * 0: a session may have been found.
435 : : *
436 : : * Side effects:
437 : : * - If a session is found then s->session is pointed at it (after freeing an
438 : : * existing session if need be) and s->verify_result is set from the session.
439 : : * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
440 : : * if the server should issue a new session ticket (to 0 otherwise).
441 : : */
442 : 1080 : int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
443 : : const unsigned char *limit)
444 : : {
445 : : /* This is used only by servers. */
446 : :
447 : 1080 : SSL_SESSION *ret=NULL;
448 : 1080 : int fatal = 0;
449 : 1080 : int try_session_cache = 1;
450 : : #ifndef OPENSSL_NO_TLSEXT
451 : : int r;
452 : : #endif
453 : :
454 [ + - ]: 1080 : if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
455 : : goto err;
456 : :
457 [ + + ]: 1080 : if (len == 0)
458 : 1069 : try_session_cache = 0;
459 : :
460 : : #ifndef OPENSSL_NO_TLSEXT
461 : 1080 : r = tls1_process_ticket(s, session_id, len, limit, &ret); /* sets s->tlsext_ticket_expected */
462 [ + - + - ]: 1080 : switch (r)
463 : : {
464 : : case -1: /* Error during processing */
465 : : fatal = 1;
466 : : goto err;
467 : : case 0: /* No ticket found */
468 : : case 1: /* Zero length ticket found */
469 : : break; /* Ok to carry on processing session id. */
470 : : case 2: /* Ticket found but not decrypted. */
471 : : case 3: /* Ticket decrypted, *ret has been set. */
472 : 11 : try_session_cache = 0;
473 : 11 : break;
474 : : default:
475 : 0 : abort();
476 : : }
477 : : #endif
478 : :
479 [ - + ][ # # ]: 1080 : if (try_session_cache &&
480 [ # # ]: 0 : ret == NULL &&
481 : 0 : !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
482 : : {
483 : : SSL_SESSION data;
484 : 0 : data.ssl_version=s->version;
485 : 0 : data.session_id_length=len;
486 [ # # ]: 0 : if (len == 0)
487 : 0 : return 0;
488 : 0 : memcpy(data.session_id,session_id,len);
489 : 0 : CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
490 : 0 : ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data);
491 [ # # ]: 0 : if (ret != NULL)
492 : : {
493 : : /* don't allow other threads to steal it: */
494 : 0 : CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
495 : : }
496 : 0 : CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
497 [ # # ]: 0 : if (ret == NULL)
498 : 0 : s->session_ctx->stats.sess_miss++;
499 : : }
500 : :
501 [ - + ][ # # ]: 1080 : if (try_session_cache &&
502 [ # # ]: 0 : ret == NULL &&
503 : 0 : s->session_ctx->get_session_cb != NULL)
504 : : {
505 : 0 : int copy=1;
506 : :
507 [ # # ]: 0 : if ((ret=s->session_ctx->get_session_cb(s,session_id,len,©)))
508 : : {
509 : 0 : s->session_ctx->stats.sess_cb_hit++;
510 : :
511 : : /* Increment reference count now if the session callback
512 : : * asks us to do so (note that if the session structures
513 : : * returned by the callback are shared between threads,
514 : : * it must handle the reference count itself [i.e. copy == 0],
515 : : * or things won't be thread-safe). */
516 [ # # ]: 0 : if (copy)
517 : 0 : CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
518 : :
519 : : /* Add the externally cached session to the internal
520 : : * cache as well if and only if we are supposed to. */
521 [ # # ]: 0 : if(!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
522 : : /* The following should not return 1, otherwise,
523 : : * things are very strange */
524 : 0 : SSL_CTX_add_session(s->session_ctx,ret);
525 : : }
526 : : }
527 : :
528 [ + + ]: 1080 : if (ret == NULL)
529 : : goto err;
530 : :
531 : : /* Now ret is non-NULL and we own one of its reference counts. */
532 : :
533 [ + - ]: 11 : if (ret->sid_ctx_length != s->sid_ctx_length
534 [ + - ]: 11 : || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
535 : : {
536 : : /* We have the session requested by the client, but we don't
537 : : * want to use it in this context. */
538 : : goto err; /* treat like cache miss */
539 : : }
540 : :
541 [ - + ][ # # ]: 11 : if((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0)
542 : : {
543 : : /* We can't be sure if this session is being used out of
544 : : * context, which is especially important for SSL_VERIFY_PEER.
545 : : * The application should have used SSL[_CTX]_set_session_id_context.
546 : : *
547 : : * For this error case, we generate an error instead of treating
548 : : * the event like a cache miss (otherwise it would be easy for
549 : : * applications to effectively disable the session cache by
550 : : * accident without anyone noticing).
551 : : */
552 : :
553 : 0 : SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
554 : 0 : fatal = 1;
555 : 0 : goto err;
556 : : }
557 : :
558 [ + - ]: 11 : if (ret->cipher == NULL)
559 : : {
560 : : unsigned char buf[5],*p;
561 : : unsigned long l;
562 : :
563 : 11 : p=buf;
564 : 11 : l=ret->cipher_id;
565 : 11 : l2n(l,p);
566 [ + - ]: 11 : if ((ret->ssl_version>>8) >= SSL3_VERSION_MAJOR)
567 : 11 : ret->cipher=ssl_get_cipher_by_char(s,&(buf[2]));
568 : : else
569 : 0 : ret->cipher=ssl_get_cipher_by_char(s,&(buf[1]));
570 [ + - ]: 11 : if (ret->cipher == NULL)
571 : : goto err;
572 : : }
573 : :
574 [ - + ]: 11 : if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
575 : : {
576 : 0 : s->session_ctx->stats.sess_timeout++;
577 [ # # ]: 0 : if (try_session_cache)
578 : : {
579 : : /* session was from the cache, so remove it */
580 : 0 : SSL_CTX_remove_session(s->session_ctx,ret);
581 : : }
582 : : goto err;
583 : : }
584 : :
585 : 11 : s->session_ctx->stats.sess_hit++;
586 : :
587 [ + - ]: 11 : if (s->session != NULL)
588 : 11 : SSL_SESSION_free(s->session);
589 : 11 : s->session=ret;
590 : 11 : s->verify_result = s->session->verify_result;
591 : 11 : return 1;
592 : :
593 : : err:
594 [ - + ]: 1069 : if (ret != NULL)
595 : : {
596 : 0 : SSL_SESSION_free(ret);
597 : : #ifndef OPENSSL_NO_TLSEXT
598 [ # # ]: 0 : if (!try_session_cache)
599 : : {
600 : : /* The session was from a ticket, so we should
601 : : * issue a ticket for the new session */
602 : 0 : s->tlsext_ticket_expected = 1;
603 : : }
604 : : #endif
605 : : }
606 [ + - ]: 1069 : if (fatal)
607 : : return -1;
608 : : else
609 : 1069 : return 0;
610 : : }
611 : :
612 : 363 : int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
613 : : {
614 : 363 : int ret=0;
615 : : SSL_SESSION *s;
616 : :
617 : : /* add just 1 reference count for the SSL_CTX's session cache
618 : : * even though it has two ways of access: each session is in a
619 : : * doubly linked list and an lhash */
620 : 363 : CRYPTO_add(&c->references,1,CRYPTO_LOCK_SSL_SESSION);
621 : : /* if session c is in already in cache, we take back the increment later */
622 : :
623 : 363 : CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
624 : 363 : s=lh_SSL_SESSION_insert(ctx->sessions,c);
625 : :
626 : : /* s != NULL iff we already had a session with the given PID.
627 : : * In this case, s == c should hold (then we did not really modify
628 : : * ctx->sessions), or we're in trouble. */
629 [ - + ]: 363 : if (s != NULL && s != c)
630 : : {
631 : : /* We *are* in trouble ... */
632 : 0 : SSL_SESSION_list_remove(ctx,s);
633 : 0 : SSL_SESSION_free(s);
634 : : /* ... so pretend the other session did not exist in cache
635 : : * (we cannot handle two SSL_SESSION structures with identical
636 : : * session ID in the same cache, which could happen e.g. when
637 : : * two threads concurrently obtain the same session from an external
638 : : * cache) */
639 : 0 : s = NULL;
640 : : }
641 : :
642 : : /* Put at the head of the queue unless it is already in the cache */
643 [ + - ]: 363 : if (s == NULL)
644 : 363 : SSL_SESSION_list_add(ctx,c);
645 : :
646 [ - + ]: 363 : if (s != NULL)
647 : : {
648 : : /* existing cache entry -- decrement previously incremented reference
649 : : * count because it already takes into account the cache */
650 : :
651 : 0 : SSL_SESSION_free(s); /* s == c */
652 : 0 : ret=0;
653 : : }
654 : : else
655 : : {
656 : : /* new cache entry -- remove old ones if cache has become too large */
657 : :
658 : 363 : ret=1;
659 : :
660 [ + - ]: 363 : if (SSL_CTX_sess_get_cache_size(ctx) > 0)
661 : : {
662 [ - + ]: 726 : while (SSL_CTX_sess_number(ctx) >
663 : 363 : SSL_CTX_sess_get_cache_size(ctx))
664 : : {
665 [ # # ]: 0 : if (!remove_session_lock(ctx,
666 : 0 : ctx->session_cache_tail, 0))
667 : : break;
668 : : else
669 : 0 : ctx->stats.sess_cache_full++;
670 : : }
671 : : }
672 : : }
673 : 363 : CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
674 : 363 : return(ret);
675 : : }
676 : :
677 : 0 : int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
678 : : {
679 : 0 : return remove_session_lock(ctx, c, 1);
680 : : }
681 : :
682 : 0 : static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
683 : : {
684 : : SSL_SESSION *r;
685 : 0 : int ret=0;
686 : :
687 [ # # ][ # # ]: 0 : if ((c != NULL) && (c->session_id_length != 0))
688 : : {
689 [ # # ]: 0 : if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
690 [ # # ]: 0 : if ((r = lh_SSL_SESSION_retrieve(ctx->sessions,c)) == c)
691 : : {
692 : 0 : ret=1;
693 : 0 : r=lh_SSL_SESSION_delete(ctx->sessions,c);
694 : 0 : SSL_SESSION_list_remove(ctx,c);
695 : : }
696 : :
697 [ # # ]: 0 : if(lck) CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
698 : :
699 [ # # ]: 0 : if (ret)
700 : : {
701 : 0 : r->not_resumable=1;
702 [ # # ]: 0 : if (ctx->remove_session_cb != NULL)
703 : 0 : ctx->remove_session_cb(ctx,r);
704 : 0 : SSL_SESSION_free(r);
705 : : }
706 : : }
707 : : else
708 : : ret=0;
709 : 0 : return(ret);
710 : : }
711 : :
712 : 3598 : void SSL_SESSION_free(SSL_SESSION *ss)
713 : : {
714 : : int i;
715 : :
716 [ + - ]: 3598 : if(ss == NULL)
717 : : return;
718 : :
719 : 3598 : i=CRYPTO_add(&ss->references,-1,CRYPTO_LOCK_SSL_SESSION);
720 : : #ifdef REF_PRINT
721 : : REF_PRINT("SSL_SESSION",ss);
722 : : #endif
723 [ + + ]: 3598 : if (i > 0) return;
724 : : #ifdef REF_CHECK
725 : : if (i < 0)
726 : : {
727 : : fprintf(stderr,"SSL_SESSION_free, bad reference count\n");
728 : : abort(); /* ok */
729 : : }
730 : : #endif
731 : :
732 : 3235 : CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
733 : :
734 : 3235 : OPENSSL_cleanse(ss->key_arg,sizeof ss->key_arg);
735 : 3235 : OPENSSL_cleanse(ss->master_key,sizeof ss->master_key);
736 : 3235 : OPENSSL_cleanse(ss->session_id,sizeof ss->session_id);
737 [ + + ]: 3235 : if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert);
738 [ + + ]: 3235 : if (ss->peer != NULL) X509_free(ss->peer);
739 [ + + ]: 3235 : if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
740 : : #ifndef OPENSSL_NO_TLSEXT
741 [ - + ]: 3235 : if (ss->tlsext_hostname != NULL) OPENSSL_free(ss->tlsext_hostname);
742 [ + + ]: 3235 : if (ss->tlsext_tick != NULL) OPENSSL_free(ss->tlsext_tick);
743 : : #ifndef OPENSSL_NO_EC
744 : 3235 : ss->tlsext_ecpointformatlist_length = 0;
745 [ + + ]: 3235 : if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist);
746 : 3235 : ss->tlsext_ellipticcurvelist_length = 0;
747 [ + + ]: 3235 : if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
748 : : #endif /* OPENSSL_NO_EC */
749 : : #endif
750 : : #ifndef OPENSSL_NO_PSK
751 [ + + ]: 3235 : if (ss->psk_identity_hint != NULL)
752 : 66 : OPENSSL_free(ss->psk_identity_hint);
753 [ + + ]: 3235 : if (ss->psk_identity != NULL)
754 : 66 : OPENSSL_free(ss->psk_identity);
755 : : #endif
756 : : #ifndef OPENSSL_NO_SRP
757 [ + + ]: 3235 : if (ss->srp_username != NULL)
758 : 66 : OPENSSL_free(ss->srp_username);
759 : : #endif
760 : 3235 : OPENSSL_cleanse(ss,sizeof(*ss));
761 : 3235 : OPENSSL_free(ss);
762 : : }
763 : :
764 : 1190 : int SSL_set_session(SSL *s, SSL_SESSION *session)
765 : : {
766 : 1190 : int ret=0;
767 : : const SSL_METHOD *meth;
768 : :
769 [ - + ]: 1190 : if (session != NULL)
770 : : {
771 : 0 : meth=s->ctx->method->get_ssl_method(session->ssl_version);
772 [ # # ]: 0 : if (meth == NULL)
773 : 0 : meth=s->method->get_ssl_method(session->ssl_version);
774 [ # # ]: 0 : if (meth == NULL)
775 : : {
776 : 0 : SSLerr(SSL_F_SSL_SET_SESSION,SSL_R_UNABLE_TO_FIND_SSL_METHOD);
777 : 0 : return(0);
778 : : }
779 : :
780 [ # # ]: 0 : if (meth != s->method)
781 : : {
782 [ # # ]: 0 : if (!SSL_set_ssl_method(s,meth))
783 : : return(0);
784 : : }
785 : :
786 : : #ifndef OPENSSL_NO_KRB5
787 : : if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
788 : : session->krb5_client_princ_len > 0)
789 : : {
790 : : s->kssl_ctx->client_princ = (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1);
791 : : memcpy(s->kssl_ctx->client_princ,session->krb5_client_princ,
792 : : session->krb5_client_princ_len);
793 : : s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0';
794 : : }
795 : : #endif /* OPENSSL_NO_KRB5 */
796 : :
797 : : /* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/
798 : 0 : CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);
799 [ # # ]: 0 : if (s->session != NULL)
800 : 0 : SSL_SESSION_free(s->session);
801 : 0 : s->session=session;
802 : 0 : s->verify_result = s->session->verify_result;
803 : : /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/
804 : 0 : ret=1;
805 : : }
806 : : else
807 : : {
808 [ + + ]: 1190 : if (s->session != NULL)
809 : : {
810 : 308 : SSL_SESSION_free(s->session);
811 : 308 : s->session=NULL;
812 : : }
813 : :
814 : 1190 : meth=s->ctx->method;
815 [ - + ]: 1190 : if (meth != s->method)
816 : : {
817 [ # # ]: 0 : if (!SSL_set_ssl_method(s,meth))
818 : : return(0);
819 : : }
820 : : ret=1;
821 : : }
822 : : return(ret);
823 : : }
824 : :
825 : 0 : long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)
826 : : {
827 [ # # ]: 0 : if (s == NULL) return(0);
828 : 0 : s->timeout=t;
829 : 0 : return(1);
830 : : }
831 : :
832 : 0 : long SSL_SESSION_get_timeout(const SSL_SESSION *s)
833 : : {
834 [ # # ]: 0 : if (s == NULL) return(0);
835 : 0 : return(s->timeout);
836 : : }
837 : :
838 : 0 : long SSL_SESSION_get_time(const SSL_SESSION *s)
839 : : {
840 [ # # ]: 0 : if (s == NULL) return(0);
841 : 0 : return(s->time);
842 : : }
843 : :
844 : 0 : long SSL_SESSION_set_time(SSL_SESSION *s, long t)
845 : : {
846 [ # # ]: 0 : if (s == NULL) return(0);
847 : 0 : s->time=t;
848 : 0 : return(t);
849 : : }
850 : :
851 : 6 : X509 *SSL_SESSION_get0_peer(SSL_SESSION *s)
852 : : {
853 : 6 : return s->peer;
854 : : }
855 : :
856 : 0 : int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
857 : : unsigned int sid_ctx_len)
858 : : {
859 [ # # ]: 0 : if(sid_ctx_len > SSL_MAX_SID_CTX_LENGTH)
860 : : {
861 : 0 : SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
862 : 0 : return 0;
863 : : }
864 : 0 : s->sid_ctx_length=sid_ctx_len;
865 : 0 : memcpy(s->sid_ctx,sid_ctx,sid_ctx_len);
866 : :
867 : 0 : return 1;
868 : : }
869 : :
870 : 0 : long SSL_CTX_set_timeout(SSL_CTX *s, long t)
871 : : {
872 : : long l;
873 [ # # ]: 0 : if (s == NULL) return(0);
874 : 0 : l=s->session_timeout;
875 : 0 : s->session_timeout=t;
876 : 0 : return(l);
877 : : }
878 : :
879 : 0 : long SSL_CTX_get_timeout(const SSL_CTX *s)
880 : : {
881 [ # # ]: 0 : if (s == NULL) return(0);
882 : 0 : return(s->session_timeout);
883 : : }
884 : :
885 : : #ifndef OPENSSL_NO_TLSEXT
886 : 0 : int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
887 : : STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
888 : : {
889 [ # # ]: 0 : if (s == NULL) return(0);
890 : 0 : s->tls_session_secret_cb = tls_session_secret_cb;
891 : 0 : s->tls_session_secret_cb_arg = arg;
892 : 0 : return(1);
893 : : }
894 : :
895 : 0 : int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
896 : : void *arg)
897 : : {
898 [ # # ]: 0 : if (s == NULL) return(0);
899 : 0 : s->tls_session_ticket_ext_cb = cb;
900 : 0 : s->tls_session_ticket_ext_cb_arg = arg;
901 : 0 : return(1);
902 : : }
903 : :
904 : 0 : int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
905 : : {
906 [ # # ]: 0 : if (s->version >= TLS1_VERSION)
907 : : {
908 [ # # ]: 0 : if (s->tlsext_session_ticket)
909 : : {
910 : 0 : OPENSSL_free(s->tlsext_session_ticket);
911 : 0 : s->tlsext_session_ticket = NULL;
912 : : }
913 : :
914 : 0 : s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
915 [ # # ]: 0 : if (!s->tlsext_session_ticket)
916 : : {
917 : 0 : SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE);
918 : 0 : return 0;
919 : : }
920 : :
921 [ # # ]: 0 : if (ext_data)
922 : : {
923 : 0 : s->tlsext_session_ticket->length = ext_len;
924 : 0 : s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1;
925 : 0 : memcpy(s->tlsext_session_ticket->data, ext_data, ext_len);
926 : : }
927 : : else
928 : : {
929 : 0 : s->tlsext_session_ticket->length = 0;
930 : 0 : s->tlsext_session_ticket->data = NULL;
931 : : }
932 : :
933 : : return 1;
934 : : }
935 : :
936 : : return 0;
937 : : }
938 : : #endif /* OPENSSL_NO_TLSEXT */
939 : :
940 : : typedef struct timeout_param_st
941 : : {
942 : : SSL_CTX *ctx;
943 : : long time;
944 : : LHASH_OF(SSL_SESSION) *cache;
945 : : } TIMEOUT_PARAM;
946 : :
947 : 363 : static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p)
948 : : {
949 [ - + ][ # # ]: 363 : if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */
950 : : {
951 : : /* The reason we don't call SSL_CTX_remove_session() is to
952 : : * save on locking overhead */
953 : 363 : (void)lh_SSL_SESSION_delete(p->cache,s);
954 : 363 : SSL_SESSION_list_remove(p->ctx,s);
955 : 363 : s->not_resumable=1;
956 [ - + ]: 363 : if (p->ctx->remove_session_cb != NULL)
957 : 0 : p->ctx->remove_session_cb(p->ctx,s);
958 : 363 : SSL_SESSION_free(s);
959 : : }
960 : 363 : }
961 : :
962 : 726 : static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM)
963 : :
964 : 1808 : void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
965 : : {
966 : : unsigned long i;
967 : : TIMEOUT_PARAM tp;
968 : :
969 : 1808 : tp.ctx=s;
970 : 1808 : tp.cache=s->sessions;
971 [ + - ]: 1808 : if (tp.cache == NULL) return;
972 : 1808 : tp.time=t;
973 : 1808 : CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
974 : 1808 : i=CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load;
975 : 1808 : CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=0;
976 : 1808 : lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout),
977 : : TIMEOUT_PARAM, &tp);
978 : 1808 : CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=i;
979 : 1808 : CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
980 : : }
981 : :
982 : 6018 : int ssl_clear_bad_session(SSL *s)
983 : : {
984 [ + + ][ + + ]: 6018 : if ( (s->session != NULL) &&
985 [ - + ]: 374 : !(s->shutdown & SSL_SENT_SHUTDOWN) &&
986 [ # # ]: 374 : !(SSL_in_init(s) || SSL_in_before(s)))
987 : : {
988 : 0 : SSL_CTX_remove_session(s->ctx,s->session);
989 : 0 : return(1);
990 : : }
991 : : else
992 : : return(0);
993 : : }
994 : :
995 : : /* locked by SSL_CTX in the calling function */
996 : 726 : static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)
997 : : {
998 [ + - ][ + - ]: 363 : if ((s->next == NULL) || (s->prev == NULL)) return;
999 : :
1000 [ + - ]: 363 : if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail))
1001 : : { /* last element in list */
1002 [ + - ]: 363 : if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
1003 : : { /* only one element in list */
1004 : 363 : ctx->session_cache_head=NULL;
1005 : 363 : ctx->session_cache_tail=NULL;
1006 : : }
1007 : : else
1008 : : {
1009 : 0 : ctx->session_cache_tail=s->prev;
1010 : 0 : s->prev->next=(SSL_SESSION *)&(ctx->session_cache_tail);
1011 : : }
1012 : : }
1013 : : else
1014 : : {
1015 [ # # ]: 0 : if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
1016 : : { /* first element in list */
1017 : 0 : ctx->session_cache_head=s->next;
1018 : 0 : s->next->prev=(SSL_SESSION *)&(ctx->session_cache_head);
1019 : : }
1020 : : else
1021 : : { /* middle of list */
1022 : 0 : s->next->prev=s->prev;
1023 : 0 : s->prev->next=s->next;
1024 : : }
1025 : : }
1026 : 363 : s->prev=s->next=NULL;
1027 : : }
1028 : :
1029 : 363 : static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)
1030 : : {
1031 [ - + ][ # # ]: 363 : if ((s->next != NULL) && (s->prev != NULL))
1032 : 0 : SSL_SESSION_list_remove(ctx,s);
1033 : :
1034 [ + - ]: 363 : if (ctx->session_cache_head == NULL)
1035 : : {
1036 : 363 : ctx->session_cache_head=s;
1037 : 363 : ctx->session_cache_tail=s;
1038 : 363 : s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
1039 : 363 : s->next=(SSL_SESSION *)&(ctx->session_cache_tail);
1040 : : }
1041 : : else
1042 : : {
1043 : 0 : s->next=ctx->session_cache_head;
1044 : 0 : s->next->prev=s;
1045 : 0 : s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
1046 : 0 : ctx->session_cache_head=s;
1047 : : }
1048 : 363 : }
1049 : :
1050 : 0 : void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
1051 : : int (*cb)(struct ssl_st *ssl,SSL_SESSION *sess))
1052 : : {
1053 : 0 : ctx->new_session_cb=cb;
1054 : 0 : }
1055 : :
1056 : 0 : int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess)
1057 : : {
1058 : 0 : return ctx->new_session_cb;
1059 : : }
1060 : :
1061 : 0 : void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
1062 : : void (*cb)(SSL_CTX *ctx,SSL_SESSION *sess))
1063 : : {
1064 : 0 : ctx->remove_session_cb=cb;
1065 : 0 : }
1066 : :
1067 : 0 : void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX * ctx,SSL_SESSION *sess)
1068 : : {
1069 : 0 : return ctx->remove_session_cb;
1070 : : }
1071 : :
1072 : 0 : void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
1073 : : SSL_SESSION *(*cb)(struct ssl_st *ssl,
1074 : : unsigned char *data,int len,int *copy))
1075 : : {
1076 : 0 : ctx->get_session_cb=cb;
1077 : 0 : }
1078 : :
1079 : 0 : SSL_SESSION * (*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl,
1080 : : unsigned char *data,int len,int *copy)
1081 : : {
1082 : 0 : return ctx->get_session_cb;
1083 : : }
1084 : :
1085 : 0 : void SSL_CTX_set_info_callback(SSL_CTX *ctx,
1086 : : void (*cb)(const SSL *ssl,int type,int val))
1087 : : {
1088 : 0 : ctx->info_callback=cb;
1089 : 0 : }
1090 : :
1091 : 0 : void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val)
1092 : : {
1093 : 0 : return ctx->info_callback;
1094 : : }
1095 : :
1096 : 0 : void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
1097 : : int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey))
1098 : : {
1099 : 0 : ctx->client_cert_cb=cb;
1100 : 0 : }
1101 : :
1102 : 0 : int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509 , EVP_PKEY **pkey)
1103 : : {
1104 : 0 : return ctx->client_cert_cb;
1105 : : }
1106 : :
1107 : : #ifndef OPENSSL_NO_ENGINE
1108 : 0 : int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
1109 : : {
1110 [ # # ]: 0 : if (!ENGINE_init(e))
1111 : : {
1112 : 0 : SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
1113 : 0 : return 0;
1114 : : }
1115 [ # # ]: 0 : if(!ENGINE_get_ssl_client_cert_function(e))
1116 : : {
1117 : 0 : SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, SSL_R_NO_CLIENT_CERT_METHOD);
1118 : 0 : ENGINE_finish(e);
1119 : 0 : return 0;
1120 : : }
1121 : 0 : ctx->client_cert_engine = e;
1122 : 0 : return 1;
1123 : : }
1124 : : #endif
1125 : :
1126 : 0 : void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
1127 : : int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len))
1128 : : {
1129 : 0 : ctx->app_gen_cookie_cb=cb;
1130 : 0 : }
1131 : :
1132 : 0 : void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
1133 : : int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len))
1134 : : {
1135 : 0 : ctx->app_verify_cookie_cb=cb;
1136 : 0 : }
1137 : :
1138 : 14 : IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
|