summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_sess.c
diff options
context:
space:
mode:
authorbeck <>2002-05-15 02:29:21 +0000
committerbeck <>2002-05-15 02:29:21 +0000
commitb64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9 (patch)
treefa27cf82a1250b64ed3bf5f4a18c7354d470bbcc /src/lib/libssl/ssl_sess.c
parente471e1ea98d673597b182ea85f29e30c97cd08b5 (diff)
downloadopenbsd-b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9.tar.gz
openbsd-b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9.tar.bz2
openbsd-b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9.zip
OpenSSL 0.9.7 stable 2002 05 08 merge
Diffstat (limited to 'src/lib/libssl/ssl_sess.c')
-rw-r--r--src/lib/libssl/ssl_sess.c122
1 files changed, 93 insertions, 29 deletions
diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c
index 7064262def..6424f775e2 100644
--- a/src/lib/libssl/ssl_sess.c
+++ b/src/lib/libssl/ssl_sess.c
@@ -64,8 +64,6 @@
64static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); 64static 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;
68static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_session_meth=NULL;
69 67
70SSL_SESSION *SSL_get_session(SSL *ssl) 68SSL_SESSION *SSL_get_session(SSL *ssl)
71/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ 69/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
@@ -91,10 +89,8 @@ SSL_SESSION *SSL_get1_session(SSL *ssl)
91int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 89int 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) 90 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
93 { 91 {
94 ssl_session_num++; 92 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
95 return(CRYPTO_get_ex_new_index(ssl_session_num-1, 93 new_func, dup_func, free_func);
96 &ssl_session_meth,
97 argl,argp,new_func,dup_func,free_func));
98 } 94 }
99 95
100int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) 96int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
@@ -126,15 +122,49 @@ SSL_SESSION *SSL_SESSION_new(void)
126 ss->prev=NULL; 122 ss->prev=NULL;
127 ss->next=NULL; 123 ss->next=NULL;
128 ss->compress_meth=0; 124 ss->compress_meth=0;
129 CRYPTO_new_ex_data(ssl_session_meth,ss,&ss->ex_data); 125 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
130 return(ss); 126 return(ss);
131 } 127 }
132 128
129/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1
130 * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly
131 * until we have no conflict is going to complete in one iteration pretty much
132 * "most" of the time (btw: understatement). So, if it takes us 10 iterations
133 * and we still can't avoid a conflict - well that's a reasonable point to call
134 * it quits. Either the RAND code is broken or someone is trying to open roughly
135 * very close to 2^128 (or 2^256) SSL sessions to our server. How you might
136 * store that many sessions is perhaps a more interesting question ... */
137
138#define MAX_SESS_ID_ATTEMPTS 10
139static int def_generate_session_id(const SSL *ssl, unsigned char *id,
140 unsigned int *id_len)
141{
142 unsigned int retry = 0;
143 do
144 RAND_pseudo_bytes(id, *id_len);
145 while(SSL_has_matching_session_id(ssl, id, *id_len) &&
146 (++retry < MAX_SESS_ID_ATTEMPTS));
147 if(retry < MAX_SESS_ID_ATTEMPTS)
148 return 1;
149 /* else - woops a session_id match */
150 /* XXX We should also check the external cache --
151 * but the probability of a collision is negligible, and
152 * we could not prevent the concurrent creation of sessions
153 * with identical IDs since we currently don't have means
154 * to atomically check whether a session ID already exists
155 * and make a reservation for it if it does not
156 * (this problem applies to the internal cache as well).
157 */
158 return 0;
159}
160
133int ssl_get_new_session(SSL *s, int session) 161int ssl_get_new_session(SSL *s, int session)
134 { 162 {
135 /* This gets used by clients and servers. */ 163 /* This gets used by clients and servers. */
136 164
165 unsigned int tmp;
137 SSL_SESSION *ss=NULL; 166 SSL_SESSION *ss=NULL;
167 GEN_SESSION_CB cb = def_generate_session_id;
138 168
139 if ((ss=SSL_SESSION_new()) == NULL) return(0); 169 if ((ss=SSL_SESSION_new()) == NULL) return(0);
140 170
@@ -173,25 +203,46 @@ int ssl_get_new_session(SSL *s, int session)
173 SSL_SESSION_free(ss); 203 SSL_SESSION_free(ss);
174 return(0); 204 return(0);
175 } 205 }
176 206 /* Choose which callback will set the session ID */
177 for (;;) 207 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
208 if(s->generate_session_id)
209 cb = s->generate_session_id;
210 else if(s->ctx->generate_session_id)
211 cb = s->ctx->generate_session_id;
212 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
213 /* Choose a session ID */
214 tmp = ss->session_id_length;
215 if(!cb(s, ss->session_id, &tmp))
178 { 216 {
179 SSL_SESSION *r; 217 /* The callback failed */
180 218 SSLerr(SSL_F_SSL_GET_NEW_SESSION,
181 RAND_pseudo_bytes(ss->session_id,ss->session_id_length); 219 SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
182 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 220 SSL_SESSION_free(ss);
183 r=(SSL_SESSION *)lh_retrieve(s->ctx->sessions, ss); 221 return(0);
184 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 222 }
185 if (r == NULL) break; 223 /* Don't allow the callback to set the session length to zero.
186 /* else - woops a session_id match */ 224 * nor set it higher than it was. */
187 /* XXX We should also check the external cache -- 225 if(!tmp || (tmp > ss->session_id_length))
188 * but the probability of a collision is negligible, and 226 {
189 * we could not prevent the concurrent creation of sessions 227 /* The callback set an illegal length */
190 * with identical IDs since we currently don't have means 228 SSLerr(SSL_F_SSL_GET_NEW_SESSION,
191 * to atomically check whether a session ID already exists 229 SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
192 * and make a reservation for it if it does not 230 SSL_SESSION_free(ss);
193 * (this problem applies to the internal cache as well). 231 return(0);
194 */ 232 }
233 /* If the session length was shrunk and we're SSLv2, pad it */
234 if((tmp < ss->session_id_length) && (s->version == SSL2_VERSION))
235 memset(ss->session_id + tmp, 0, ss->session_id_length - tmp);
236 else
237 ss->session_id_length = tmp;
238 /* Finally, check for a conflict */
239 if(SSL_has_matching_session_id(s, ss->session_id,
240 ss->session_id_length))
241 {
242 SSLerr(SSL_F_SSL_GET_NEW_SESSION,
243 SSL_R_SSL_SESSION_ID_CONFLICT);
244 SSL_SESSION_free(ss);
245 return(0);
195 } 246 }
196 } 247 }
197 else 248 else
@@ -423,10 +474,10 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
423 if ((c != NULL) && (c->session_id_length != 0)) 474 if ((c != NULL) && (c->session_id_length != 0))
424 { 475 {
425 if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 476 if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
426 r=(SSL_SESSION *)lh_delete(ctx->sessions,c); 477 if ((r = (SSL_SESSION *)lh_retrieve(ctx->sessions,c)) == c)
427 if (r != NULL)
428 { 478 {
429 ret=1; 479 ret=1;
480 r=(SSL_SESSION *)lh_delete(ctx->sessions,c);
430 SSL_SESSION_list_remove(ctx,c); 481 SSL_SESSION_list_remove(ctx,c);
431 } 482 }
432 483
@@ -465,7 +516,7 @@ void SSL_SESSION_free(SSL_SESSION *ss)
465 } 516 }
466#endif 517#endif
467 518
468 CRYPTO_free_ex_data(ssl_session_meth,ss,&ss->ex_data); 519 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
469 520
470 memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH); 521 memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH);
471 memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH); 522 memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH);
@@ -503,6 +554,17 @@ int SSL_set_session(SSL *s, SSL_SESSION *session)
503 session->timeout=s->ctx->session_timeout; 554 session->timeout=s->ctx->session_timeout;
504 } 555 }
505 556
557#ifndef OPENSSL_NO_KRB5
558 if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
559 session->krb5_client_princ_len > 0)
560 {
561 s->kssl_ctx->client_princ = (char *)malloc(session->krb5_client_princ_len + 1);
562 memcpy(s->kssl_ctx->client_princ,session->krb5_client_princ,
563 session->krb5_client_princ_len);
564 s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0';
565 }
566#endif /* OPENSSL_NO_KRB5 */
567
506 /* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/ 568 /* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/
507 CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION); 569 CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);
508 if (s->session != NULL) 570 if (s->session != NULL)
@@ -594,6 +656,8 @@ static void timeout(SSL_SESSION *s, TIMEOUT_PARAM *p)
594 } 656 }
595 } 657 }
596 658
659static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION *, TIMEOUT_PARAM *)
660
597void SSL_CTX_flush_sessions(SSL_CTX *s, long t) 661void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
598 { 662 {
599 unsigned long i; 663 unsigned long i;
@@ -606,7 +670,7 @@ void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
606 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 670 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
607 i=tp.cache->down_load; 671 i=tp.cache->down_load;
608 tp.cache->down_load=0; 672 tp.cache->down_load=0;
609 lh_doall_arg(tp.cache,(void (*)())timeout,&tp); 673 lh_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), &tp);
610 tp.cache->down_load=i; 674 tp.cache->down_load=i;
611 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 675 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
612 } 676 }