summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_sess.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/ssl_sess.c')
-rw-r--r--src/lib/libssl/ssl_sess.c89
1 files changed, 66 insertions, 23 deletions
diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c
index 681499f08a..9e01f72753 100644
--- a/src/lib/libssl/ssl_sess.c
+++ b/src/lib/libssl/ssl_sess.c
@@ -65,15 +65,31 @@ static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
65static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s); 65static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
66static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); 66static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
67static int ssl_session_num=0; 67static int ssl_session_num=0;
68static STACK *ssl_session_meth=NULL; 68static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_session_meth=NULL;
69 69
70SSL_SESSION *SSL_get_session(SSL *ssl) 70SSL_SESSION *SSL_get_session(SSL *ssl)
71/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
71 { 72 {
72 return(ssl->session); 73 return(ssl->session);
73 } 74 }
74 75
75int SSL_SESSION_get_ex_new_index(long argl, char *argp, int (*new_func)(), 76SSL_SESSION *SSL_get1_session(SSL *ssl)
76 int (*dup_func)(), void (*free_func)()) 77/* variant of SSL_get_session: caller really gets something */
78 {
79 SSL_SESSION *sess;
80 /* Need to lock this all up rather than just use CRYPTO_add so that
81 * somebody doesn't free ssl->session between when we check it's
82 * non-null and when we up the reference count. */
83 CRYPTO_r_lock(CRYPTO_LOCK_SSL_SESSION);
84 sess = ssl->session;
85 if(sess)
86 sess->references++;
87 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_SESSION);
88 return(sess);
89 }
90
91int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
92 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
77 { 93 {
78 ssl_session_num++; 94 ssl_session_num++;
79 return(CRYPTO_get_ex_new_index(ssl_session_num-1, 95 return(CRYPTO_get_ex_new_index(ssl_session_num-1,
@@ -103,13 +119,14 @@ SSL_SESSION *SSL_SESSION_new(void)
103 } 119 }
104 memset(ss,0,sizeof(SSL_SESSION)); 120 memset(ss,0,sizeof(SSL_SESSION));
105 121
122 ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
106 ss->references=1; 123 ss->references=1;
107 ss->timeout=60*5+4; /* 5 minute timeout by default */ 124 ss->timeout=60*5+4; /* 5 minute timeout by default */
108 ss->time=time(NULL); 125 ss->time=time(NULL);
109 ss->prev=NULL; 126 ss->prev=NULL;
110 ss->next=NULL; 127 ss->next=NULL;
111 ss->compress_meth=0; 128 ss->compress_meth=0;
112 CRYPTO_new_ex_data(ssl_session_meth,(char *)ss,&ss->ex_data); 129 CRYPTO_new_ex_data(ssl_session_meth,ss,&ss->ex_data);
113 return(ss); 130 return(ss);
114 } 131 }
115 132
@@ -161,15 +178,20 @@ int ssl_get_new_session(SSL *s, int session)
161 { 178 {
162 SSL_SESSION *r; 179 SSL_SESSION *r;
163 180
164 RAND_bytes(ss->session_id,ss->session_id_length); 181 RAND_pseudo_bytes(ss->session_id,ss->session_id_length);
165 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 182 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
166 r=(SSL_SESSION *)lh_retrieve(s->ctx->sessions, 183 r=(SSL_SESSION *)lh_retrieve(s->ctx->sessions, ss);
167 (char *)ss);
168 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 184 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
169 if (r == NULL) break; 185 if (r == NULL) break;
170 /* else - woops a session_id match */ 186 /* else - woops a session_id match */
171 /* XXX should also check external cache! 187 /* XXX We should also check the external cache --
172 * (But the probability of a collision is negligible, anyway...) */ 188 * but the probability of a collision is negligible, and
189 * we could not prevent the concurrent creation of sessions
190 * with identical IDs since we currently don't have means
191 * to atomically check whether a session ID already exists
192 * and make a reservation for it if it does not
193 * (this problem applies to the internal cache as well).
194 */
173 } 195 }
174 } 196 }
175 else 197 else
@@ -181,6 +203,7 @@ int ssl_get_new_session(SSL *s, int session)
181 ss->sid_ctx_length=s->sid_ctx_length; 203 ss->sid_ctx_length=s->sid_ctx_length;
182 s->session=ss; 204 s->session=ss;
183 ss->ssl_version=s->version; 205 ss->ssl_version=s->version;
206 ss->verify_result = X509_V_OK;
184 207
185 return(1); 208 return(1);
186 } 209 }
@@ -192,7 +215,6 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
192 SSL_SESSION *ret=NULL,data; 215 SSL_SESSION *ret=NULL,data;
193 int fatal = 0; 216 int fatal = 0;
194 217
195 /* conn_init();*/
196 data.ssl_version=s->version; 218 data.ssl_version=s->version;
197 data.session_id_length=len; 219 data.session_id_length=len;
198 if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) 220 if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
@@ -202,7 +224,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
202 if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) 224 if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
203 { 225 {
204 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 226 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
205 ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,(char *)&data); 227 ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,&data);
206 if (ret != NULL) 228 if (ret != NULL)
207 /* don't allow other threads to steal it: */ 229 /* don't allow other threads to steal it: */
208 CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION); 230 CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
@@ -311,6 +333,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
311 if (s->session != NULL) 333 if (s->session != NULL)
312 SSL_SESSION_free(s->session); 334 SSL_SESSION_free(s->session);
313 s->session=ret; 335 s->session=ret;
336 s->verify_result = s->session->verify_result;
314 return(1); 337 return(1);
315 338
316 err: 339 err:
@@ -327,27 +350,47 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
327 int ret=0; 350 int ret=0;
328 SSL_SESSION *s; 351 SSL_SESSION *s;
329 352
330 /* conn_init(); */ 353 /* add just 1 reference count for the SSL_CTX's session cache
354 * even though it has two ways of access: each session is in a
355 * doubly linked list and an lhash */
331 CRYPTO_add(&c->references,1,CRYPTO_LOCK_SSL_SESSION); 356 CRYPTO_add(&c->references,1,CRYPTO_LOCK_SSL_SESSION);
357 /* if session c is in already in cache, we take back the increment later */
332 358
333 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 359 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
334 s=(SSL_SESSION *)lh_insert(ctx->sessions,(char *)c); 360 s=(SSL_SESSION *)lh_insert(ctx->sessions,c);
335 361
336 /* Put on the end of the queue unless it is already in the cache */ 362 /* s != NULL iff we already had a session with the given PID.
363 * In this case, s == c should hold (then we did not really modify
364 * ctx->sessions), or we're in trouble. */
365 if (s != NULL && s != c)
366 {
367 /* We *are* in trouble ... */
368 SSL_SESSION_list_remove(ctx,s);
369 SSL_SESSION_free(s);
370 /* ... so pretend the other session did not exist in cache
371 * (we cannot handle two SSL_SESSION structures with identical
372 * session ID in the same cache, which could happen e.g. when
373 * two threads concurrently obtain the same session from an external
374 * cache) */
375 s = NULL;
376 }
377
378 /* Put at the head of the queue unless it is already in the cache */
337 if (s == NULL) 379 if (s == NULL)
338 SSL_SESSION_list_add(ctx,c); 380 SSL_SESSION_list_add(ctx,c);
339 381
340 /* If the same session if is being 're-added', Free the old
341 * one when the last person stops using it.
342 * This will also work if it is alread in the cache.
343 * The references will go up and then down :-) */
344 if (s != NULL) 382 if (s != NULL)
345 { 383 {
346 SSL_SESSION_free(s); 384 /* existing cache entry -- decrement previously incremented reference
385 * count because it already takes into account the cache */
386
387 SSL_SESSION_free(s); /* s == c */
347 ret=0; 388 ret=0;
348 } 389 }
349 else 390 else
350 { 391 {
392 /* new cache entry -- remove old ones if cache has become too large */
393
351 ret=1; 394 ret=1;
352 395
353 if (SSL_CTX_sess_get_cache_size(ctx) > 0) 396 if (SSL_CTX_sess_get_cache_size(ctx) > 0)
@@ -380,7 +423,7 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
380 if ((c != NULL) && (c->session_id_length != 0)) 423 if ((c != NULL) && (c->session_id_length != 0))
381 { 424 {
382 if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 425 if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
383 r=(SSL_SESSION *)lh_delete(ctx->sessions,(char *)c); 426 r=(SSL_SESSION *)lh_delete(ctx->sessions,c);
384 if (r != NULL) 427 if (r != NULL)
385 { 428 {
386 ret=1; 429 ret=1;
@@ -422,7 +465,7 @@ void SSL_SESSION_free(SSL_SESSION *ss)
422 } 465 }
423#endif 466#endif
424 467
425 CRYPTO_free_ex_data(ssl_session_meth,(char *)ss,&ss->ex_data); 468 CRYPTO_free_ex_data(ssl_session_meth,ss,&ss->ex_data);
426 469
427 memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH); 470 memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH);
428 memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH); 471 memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH);
@@ -541,7 +584,7 @@ static void timeout(SSL_SESSION *s, TIMEOUT_PARAM *p)
541 { 584 {
542 /* The reason we don't call SSL_CTX_remove_session() is to 585 /* The reason we don't call SSL_CTX_remove_session() is to
543 * save on locking overhead */ 586 * save on locking overhead */
544 lh_delete(p->cache,(char *)s); 587 lh_delete(p->cache,s);
545 SSL_SESSION_list_remove(p->ctx,s); 588 SSL_SESSION_list_remove(p->ctx,s);
546 s->not_resumable=1; 589 s->not_resumable=1;
547 if (p->ctx->remove_session_cb != NULL) 590 if (p->ctx->remove_session_cb != NULL)
@@ -562,7 +605,7 @@ void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
562 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 605 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
563 i=tp.cache->down_load; 606 i=tp.cache->down_load;
564 tp.cache->down_load=0; 607 tp.cache->down_load=0;
565 lh_doall_arg(tp.cache,(void (*)())timeout,(char *)&tp); 608 lh_doall_arg(tp.cache,(void (*)())timeout,&tp);
566 tp.cache->down_load=i; 609 tp.cache->down_load=i;
567 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 610 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
568 } 611 }