ssl_sess.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  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. #include <stdio.h>
  59. #include <openssl/lhash.h>
  60. #include <openssl/rand.h>
  61. #include "ssl_locl.h"
  62. #include "cryptlib.h"
  63. static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
  64. static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
  65. static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
  66. SSL_SESSION *SSL_get_session(SSL *ssl)
  67. /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
  68. {
  69. return(ssl->session);
  70. }
  71. SSL_SESSION *SSL_get1_session(SSL *ssl)
  72. /* variant of SSL_get_session: caller really gets something */
  73. {
  74. SSL_SESSION *sess;
  75. /* Need to lock this all up rather than just use CRYPTO_add so that
  76. * somebody doesn't free ssl->session between when we check it's
  77. * non-null and when we up the reference count. */
  78. CRYPTO_r_lock(CRYPTO_LOCK_SSL_SESSION);
  79. sess = ssl->session;
  80. if(sess)
  81. sess->references++;
  82. CRYPTO_r_unlock(CRYPTO_LOCK_SSL_SESSION);
  83. return(sess);
  84. }
  85. int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
  86. CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
  87. {
  88. return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
  89. new_func, dup_func, free_func);
  90. }
  91. int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
  92. {
  93. return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
  94. }
  95. void *SSL_SESSION_get_ex_data(SSL_SESSION *s, int idx)
  96. {
  97. return(CRYPTO_get_ex_data(&s->ex_data,idx));
  98. }
  99. SSL_SESSION *SSL_SESSION_new(void)
  100. {
  101. SSL_SESSION *ss;
  102. ss=(SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
  103. if (ss == NULL)
  104. {
  105. SSLerr(SSL_F_SSL_SESSION_NEW,ERR_R_MALLOC_FAILURE);
  106. return(0);
  107. }
  108. memset(ss,0,sizeof(SSL_SESSION));
  109. ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
  110. ss->references=1;
  111. ss->timeout=60*5+4; /* 5 minute timeout by default */
  112. ss->time=time(NULL);
  113. ss->prev=NULL;
  114. ss->next=NULL;
  115. ss->compress_meth=0;
  116. CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
  117. return(ss);
  118. }
  119. /* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1
  120. * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly
  121. * until we have no conflict is going to complete in one iteration pretty much
  122. * "most" of the time (btw: understatement). So, if it takes us 10 iterations
  123. * and we still can't avoid a conflict - well that's a reasonable point to call
  124. * it quits. Either the RAND code is broken or someone is trying to open roughly
  125. * very close to 2^128 (or 2^256) SSL sessions to our server. How you might
  126. * store that many sessions is perhaps a more interesting question ... */
  127. #define MAX_SESS_ID_ATTEMPTS 10
  128. static int def_generate_session_id(const SSL *ssl, unsigned char *id,
  129. unsigned int *id_len)
  130. {
  131. unsigned int retry = 0;
  132. do
  133. RAND_pseudo_bytes(id, *id_len);
  134. while(SSL_has_matching_session_id(ssl, id, *id_len) &&
  135. (++retry < MAX_SESS_ID_ATTEMPTS));
  136. if(retry < MAX_SESS_ID_ATTEMPTS)
  137. return 1;
  138. /* else - woops a session_id match */
  139. /* XXX We should also check the external cache --
  140. * but the probability of a collision is negligible, and
  141. * we could not prevent the concurrent creation of sessions
  142. * with identical IDs since we currently don't have means
  143. * to atomically check whether a session ID already exists
  144. * and make a reservation for it if it does not
  145. * (this problem applies to the internal cache as well).
  146. */
  147. return 0;
  148. }
  149. int ssl_get_new_session(SSL *s, int session)
  150. {
  151. /* This gets used by clients and servers. */
  152. unsigned int tmp;
  153. SSL_SESSION *ss=NULL;
  154. GEN_SESSION_CB cb = def_generate_session_id;
  155. if ((ss=SSL_SESSION_new()) == NULL) return(0);
  156. /* If the context has a default timeout, use it */
  157. if (s->ctx->session_timeout == 0)
  158. ss->timeout=SSL_get_default_timeout(s);
  159. else
  160. ss->timeout=s->ctx->session_timeout;
  161. if (s->session != NULL)
  162. {
  163. SSL_SESSION_free(s->session);
  164. s->session=NULL;
  165. }
  166. if (session)
  167. {
  168. if (s->version == SSL2_VERSION)
  169. {
  170. ss->ssl_version=SSL2_VERSION;
  171. ss->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
  172. }
  173. else if (s->version == SSL3_VERSION)
  174. {
  175. ss->ssl_version=SSL3_VERSION;
  176. ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
  177. }
  178. else if (s->version == TLS1_VERSION)
  179. {
  180. ss->ssl_version=TLS1_VERSION;
  181. ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
  182. }
  183. else
  184. {
  185. SSLerr(SSL_F_SSL_GET_NEW_SESSION,SSL_R_UNSUPPORTED_SSL_VERSION);
  186. SSL_SESSION_free(ss);
  187. return(0);
  188. }
  189. /* Choose which callback will set the session ID */
  190. CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
  191. if(s->generate_session_id)
  192. cb = s->generate_session_id;
  193. else if(s->ctx->generate_session_id)
  194. cb = s->ctx->generate_session_id;
  195. CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
  196. /* Choose a session ID */
  197. tmp = ss->session_id_length;
  198. if(!cb(s, ss->session_id, &tmp))
  199. {
  200. /* The callback failed */
  201. SSLerr(SSL_F_SSL_GET_NEW_SESSION,
  202. SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
  203. SSL_SESSION_free(ss);
  204. return(0);
  205. }
  206. /* Don't allow the callback to set the session length to zero.
  207. * nor set it higher than it was. */
  208. if(!tmp || (tmp > ss->session_id_length))
  209. {
  210. /* The callback set an illegal length */
  211. SSLerr(SSL_F_SSL_GET_NEW_SESSION,
  212. SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
  213. SSL_SESSION_free(ss);
  214. return(0);
  215. }
  216. /* If the session length was shrunk and we're SSLv2, pad it */
  217. if((tmp < ss->session_id_length) && (s->version == SSL2_VERSION))
  218. memset(ss->session_id + tmp, 0, ss->session_id_length - tmp);
  219. else
  220. ss->session_id_length = tmp;
  221. /* Finally, check for a conflict */
  222. if(SSL_has_matching_session_id(s, ss->session_id,
  223. ss->session_id_length))
  224. {
  225. SSLerr(SSL_F_SSL_GET_NEW_SESSION,
  226. SSL_R_SSL_SESSION_ID_CONFLICT);
  227. SSL_SESSION_free(ss);
  228. return(0);
  229. }
  230. }
  231. else
  232. {
  233. ss->session_id_length=0;
  234. }
  235. if (s->sid_ctx_length > sizeof ss->sid_ctx)
  236. {
  237. SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
  238. SSL_SESSION_free(ss);
  239. return 0;
  240. }
  241. memcpy(ss->sid_ctx,s->sid_ctx,s->sid_ctx_length);
  242. ss->sid_ctx_length=s->sid_ctx_length;
  243. s->session=ss;
  244. ss->ssl_version=s->version;
  245. ss->verify_result = X509_V_OK;
  246. return(1);
  247. }
  248. int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
  249. {
  250. /* This is used only by servers. */
  251. SSL_SESSION *ret=NULL,data;
  252. int fatal = 0;
  253. data.ssl_version=s->version;
  254. data.session_id_length=len;
  255. if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
  256. goto err;
  257. memcpy(data.session_id,session_id,len);
  258. if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
  259. {
  260. CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
  261. ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,&data);
  262. if (ret != NULL)
  263. /* don't allow other threads to steal it: */
  264. CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
  265. CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
  266. }
  267. if (ret == NULL)
  268. {
  269. int copy=1;
  270. s->ctx->stats.sess_miss++;
  271. ret=NULL;
  272. if (s->ctx->get_session_cb != NULL
  273. && (ret=s->ctx->get_session_cb(s,session_id,len,&copy))
  274. != NULL)
  275. {
  276. s->ctx->stats.sess_cb_hit++;
  277. /* Increment reference count now if the session callback
  278. * asks us to do so (note that if the session structures
  279. * returned by the callback are shared between threads,
  280. * it must handle the reference count itself [i.e. copy == 0],
  281. * or things won't be thread-safe). */
  282. if (copy)
  283. CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
  284. /* Add the externally cached session to the internal
  285. * cache as well if and only if we are supposed to. */
  286. if(!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
  287. /* The following should not return 1, otherwise,
  288. * things are very strange */
  289. SSL_CTX_add_session(s->ctx,ret);
  290. }
  291. if (ret == NULL)
  292. goto err;
  293. }
  294. /* Now ret is non-NULL, and we own one of its reference counts. */
  295. if((s->verify_mode&SSL_VERIFY_PEER)
  296. && (!s->sid_ctx_length || ret->sid_ctx_length != s->sid_ctx_length
  297. || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length)))
  298. {
  299. /* We've found the session named by the client, but we don't
  300. * want to use it in this context. */
  301. if (s->sid_ctx_length == 0)
  302. {
  303. /* application should have used SSL[_CTX]_set_session_id_context
  304. * -- we could tolerate this and just pretend we never heard
  305. * of this session, but then applications could effectively
  306. * disable the session cache by accident without anyone noticing */
  307. SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
  308. fatal = 1;
  309. goto err;
  310. }
  311. else
  312. {
  313. #if 0 /* The client cannot always know when a session is not appropriate,
  314. * so we shouldn't generate an error message. */
  315. SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
  316. #endif
  317. goto err; /* treat like cache miss */
  318. }
  319. }
  320. if (ret->cipher == NULL)
  321. {
  322. unsigned char buf[5],*p;
  323. unsigned long l;
  324. p=buf;
  325. l=ret->cipher_id;
  326. l2n(l,p);
  327. if ((ret->ssl_version>>8) == SSL3_VERSION_MAJOR)
  328. ret->cipher=ssl_get_cipher_by_char(s,&(buf[2]));
  329. else
  330. ret->cipher=ssl_get_cipher_by_char(s,&(buf[1]));
  331. if (ret->cipher == NULL)
  332. goto err;
  333. }
  334. #if 0 /* This is way too late. */
  335. /* If a thread got the session, then 'swaped', and another got
  336. * it and then due to a time-out decided to 'OPENSSL_free' it we could
  337. * be in trouble. So I'll increment it now, then double decrement
  338. * later - am I speaking rubbish?. */
  339. CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
  340. #endif
  341. if ((long)(ret->time+ret->timeout) < (long)time(NULL)) /* timeout */
  342. {
  343. s->ctx->stats.sess_timeout++;
  344. /* remove it from the cache */
  345. SSL_CTX_remove_session(s->ctx,ret);
  346. goto err;
  347. }
  348. s->ctx->stats.sess_hit++;
  349. /* ret->time=time(NULL); */ /* rezero timeout? */
  350. /* again, just leave the session
  351. * if it is the same session, we have just incremented and
  352. * then decremented the reference count :-) */
  353. if (s->session != NULL)
  354. SSL_SESSION_free(s->session);
  355. s->session=ret;
  356. s->verify_result = s->session->verify_result;
  357. return(1);
  358. err:
  359. if (ret != NULL)
  360. SSL_SESSION_free(ret);
  361. if (fatal)
  362. return -1;
  363. else
  364. return 0;
  365. }
  366. int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
  367. {
  368. int ret=0;
  369. SSL_SESSION *s;
  370. /* add just 1 reference count for the SSL_CTX's session cache
  371. * even though it has two ways of access: each session is in a
  372. * doubly linked list and an lhash */
  373. CRYPTO_add(&c->references,1,CRYPTO_LOCK_SSL_SESSION);
  374. /* if session c is in already in cache, we take back the increment later */
  375. CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
  376. s=(SSL_SESSION *)lh_insert(ctx->sessions,c);
  377. /* s != NULL iff we already had a session with the given PID.
  378. * In this case, s == c should hold (then we did not really modify
  379. * ctx->sessions), or we're in trouble. */
  380. if (s != NULL && s != c)
  381. {
  382. /* We *are* in trouble ... */
  383. SSL_SESSION_list_remove(ctx,s);
  384. SSL_SESSION_free(s);
  385. /* ... so pretend the other session did not exist in cache
  386. * (we cannot handle two SSL_SESSION structures with identical
  387. * session ID in the same cache, which could happen e.g. when
  388. * two threads concurrently obtain the same session from an external
  389. * cache) */
  390. s = NULL;
  391. }
  392. /* Put at the head of the queue unless it is already in the cache */
  393. if (s == NULL)
  394. SSL_SESSION_list_add(ctx,c);
  395. if (s != NULL)
  396. {
  397. /* existing cache entry -- decrement previously incremented reference
  398. * count because it already takes into account the cache */
  399. SSL_SESSION_free(s); /* s == c */
  400. ret=0;
  401. }
  402. else
  403. {
  404. /* new cache entry -- remove old ones if cache has become too large */
  405. ret=1;
  406. if (SSL_CTX_sess_get_cache_size(ctx) > 0)
  407. {
  408. while (SSL_CTX_sess_number(ctx) >
  409. SSL_CTX_sess_get_cache_size(ctx))
  410. {
  411. if (!remove_session_lock(ctx,
  412. ctx->session_cache_tail, 0))
  413. break;
  414. else
  415. ctx->stats.sess_cache_full++;
  416. }
  417. }
  418. }
  419. CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
  420. return(ret);
  421. }
  422. int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
  423. {
  424. return remove_session_lock(ctx, c, 1);
  425. }
  426. static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
  427. {
  428. SSL_SESSION *r;
  429. int ret=0;
  430. if ((c != NULL) && (c->session_id_length != 0))
  431. {
  432. if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
  433. if ((r = (SSL_SESSION *)lh_retrieve(ctx->sessions,c)) == c)
  434. {
  435. ret=1;
  436. r=(SSL_SESSION *)lh_delete(ctx->sessions,c);
  437. SSL_SESSION_list_remove(ctx,c);
  438. }
  439. if(lck) CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
  440. if (ret)
  441. {
  442. r->not_resumable=1;
  443. if (ctx->remove_session_cb != NULL)
  444. ctx->remove_session_cb(ctx,r);
  445. SSL_SESSION_free(r);
  446. }
  447. }
  448. else
  449. ret=0;
  450. return(ret);
  451. }
  452. void SSL_SESSION_free(SSL_SESSION *ss)
  453. {
  454. int i;
  455. if(ss == NULL)
  456. return;
  457. i=CRYPTO_add(&ss->references,-1,CRYPTO_LOCK_SSL_SESSION);
  458. #ifdef REF_PRINT
  459. REF_PRINT("SSL_SESSION",ss);
  460. #endif
  461. if (i > 0) return;
  462. #ifdef REF_CHECK
  463. if (i < 0)
  464. {
  465. fprintf(stderr,"SSL_SESSION_free, bad reference count\n");
  466. abort(); /* ok */
  467. }
  468. #endif
  469. CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
  470. OPENSSL_cleanse(ss->key_arg,sizeof ss->key_arg);
  471. OPENSSL_cleanse(ss->master_key,sizeof ss->master_key);
  472. OPENSSL_cleanse(ss->session_id,sizeof ss->session_id);
  473. if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert);
  474. if (ss->peer != NULL) X509_free(ss->peer);
  475. if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
  476. OPENSSL_cleanse(ss,sizeof(*ss));
  477. OPENSSL_free(ss);
  478. }
  479. int SSL_set_session(SSL *s, SSL_SESSION *session)
  480. {
  481. int ret=0;
  482. SSL_METHOD *meth;
  483. if (session != NULL)
  484. {
  485. meth=s->ctx->method->get_ssl_method(session->ssl_version);
  486. if (meth == NULL)
  487. meth=s->method->get_ssl_method(session->ssl_version);
  488. if (meth == NULL)
  489. {
  490. SSLerr(SSL_F_SSL_SET_SESSION,SSL_R_UNABLE_TO_FIND_SSL_METHOD);
  491. return(0);
  492. }
  493. if (meth != s->method)
  494. {
  495. if (!SSL_set_ssl_method(s,meth))
  496. return(0);
  497. if (s->ctx->session_timeout == 0)
  498. session->timeout=SSL_get_default_timeout(s);
  499. else
  500. session->timeout=s->ctx->session_timeout;
  501. }
  502. #ifndef OPENSSL_NO_KRB5
  503. if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
  504. session->krb5_client_princ_len > 0)
  505. {
  506. s->kssl_ctx->client_princ = (char *)malloc(session->krb5_client_princ_len + 1);
  507. memcpy(s->kssl_ctx->client_princ,session->krb5_client_princ,
  508. session->krb5_client_princ_len);
  509. s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0';
  510. }
  511. #endif /* OPENSSL_NO_KRB5 */
  512. /* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/
  513. CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);
  514. if (s->session != NULL)
  515. SSL_SESSION_free(s->session);
  516. s->session=session;
  517. s->verify_result = s->session->verify_result;
  518. /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/
  519. ret=1;
  520. }
  521. else
  522. {
  523. if (s->session != NULL)
  524. {
  525. SSL_SESSION_free(s->session);
  526. s->session=NULL;
  527. }
  528. meth=s->ctx->method;
  529. if (meth != s->method)
  530. {
  531. if (!SSL_set_ssl_method(s,meth))
  532. return(0);
  533. }
  534. ret=1;
  535. }
  536. return(ret);
  537. }
  538. long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)
  539. {
  540. if (s == NULL) return(0);
  541. s->timeout=t;
  542. return(1);
  543. }
  544. long SSL_SESSION_get_timeout(SSL_SESSION *s)
  545. {
  546. if (s == NULL) return(0);
  547. return(s->timeout);
  548. }
  549. long SSL_SESSION_get_time(SSL_SESSION *s)
  550. {
  551. if (s == NULL) return(0);
  552. return(s->time);
  553. }
  554. long SSL_SESSION_set_time(SSL_SESSION *s, long t)
  555. {
  556. if (s == NULL) return(0);
  557. s->time=t;
  558. return(t);
  559. }
  560. long SSL_CTX_set_timeout(SSL_CTX *s, long t)
  561. {
  562. long l;
  563. if (s == NULL) return(0);
  564. l=s->session_timeout;
  565. s->session_timeout=t;
  566. return(l);
  567. }
  568. long SSL_CTX_get_timeout(SSL_CTX *s)
  569. {
  570. if (s == NULL) return(0);
  571. return(s->session_timeout);
  572. }
  573. typedef struct timeout_param_st
  574. {
  575. SSL_CTX *ctx;
  576. long time;
  577. LHASH *cache;
  578. } TIMEOUT_PARAM;
  579. static void timeout(SSL_SESSION *s, TIMEOUT_PARAM *p)
  580. {
  581. if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */
  582. {
  583. /* The reason we don't call SSL_CTX_remove_session() is to
  584. * save on locking overhead */
  585. lh_delete(p->cache,s);
  586. SSL_SESSION_list_remove(p->ctx,s);
  587. s->not_resumable=1;
  588. if (p->ctx->remove_session_cb != NULL)
  589. p->ctx->remove_session_cb(p->ctx,s);
  590. SSL_SESSION_free(s);
  591. }
  592. }
  593. static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION *, TIMEOUT_PARAM *)
  594. void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
  595. {
  596. unsigned long i;
  597. TIMEOUT_PARAM tp;
  598. tp.ctx=s;
  599. tp.cache=s->sessions;
  600. if (tp.cache == NULL) return;
  601. tp.time=t;
  602. CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
  603. i=tp.cache->down_load;
  604. tp.cache->down_load=0;
  605. lh_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), &tp);
  606. tp.cache->down_load=i;
  607. CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
  608. }
  609. int ssl_clear_bad_session(SSL *s)
  610. {
  611. if ( (s->session != NULL) &&
  612. !(s->shutdown & SSL_SENT_SHUTDOWN) &&
  613. !(SSL_in_init(s) || SSL_in_before(s)))
  614. {
  615. SSL_CTX_remove_session(s->ctx,s->session);
  616. return(1);
  617. }
  618. else
  619. return(0);
  620. }
  621. /* locked by SSL_CTX in the calling function */
  622. static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)
  623. {
  624. if ((s->next == NULL) || (s->prev == NULL)) return;
  625. if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail))
  626. { /* last element in list */
  627. if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
  628. { /* only one element in list */
  629. ctx->session_cache_head=NULL;
  630. ctx->session_cache_tail=NULL;
  631. }
  632. else
  633. {
  634. ctx->session_cache_tail=s->prev;
  635. s->prev->next=(SSL_SESSION *)&(ctx->session_cache_tail);
  636. }
  637. }
  638. else
  639. {
  640. if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
  641. { /* first element in list */
  642. ctx->session_cache_head=s->next;
  643. s->next->prev=(SSL_SESSION *)&(ctx->session_cache_head);
  644. }
  645. else
  646. { /* middle of list */
  647. s->next->prev=s->prev;
  648. s->prev->next=s->next;
  649. }
  650. }
  651. s->prev=s->next=NULL;
  652. }
  653. static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)
  654. {
  655. if ((s->next != NULL) && (s->prev != NULL))
  656. SSL_SESSION_list_remove(ctx,s);
  657. if (ctx->session_cache_head == NULL)
  658. {
  659. ctx->session_cache_head=s;
  660. ctx->session_cache_tail=s;
  661. s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
  662. s->next=(SSL_SESSION *)&(ctx->session_cache_tail);
  663. }
  664. else
  665. {
  666. s->next=ctx->session_cache_head;
  667. s->next->prev=s;
  668. s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
  669. ctx->session_cache_head=s;
  670. }
  671. }