summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>2000-01-24 17:57:56 +0000
committerBodo Möller <bodo@openssl.org>2000-01-24 17:57:56 +0000
commit2557eaeac81c93f9e12534ac64a7634ab2bdb0fc (patch)
tree67437b74650aa7624c49facf60d29f71a7879f9a
parenta46faa2bfdd998f09a0a562c71c653ae0a3a0e81 (diff)
Avoid a race condition.
-rw-r--r--CHANGES5
-rw-r--r--ssl/s2_clnt.c38
2 files changed, 25 insertions, 18 deletions
diff --git a/CHANGES b/CHANGES
index f5803d75bc..2389e2eb4d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
Changes between 0.9.4 and 0.9.5 [xx XXX 1999]
+ *) Avoid a race condition in s2_clnt.c (function get_server_hello) that
+ made it impossible to use the same SSL_SESSION data structure in
+ SSL2 clients in multiple threads.
+ [Bodo Moeller]
+
*) The return value of RAND_load_file() no longer counts bytes obtained
by stat(). RAND_load_file(..., -1) is new and uses the complete file
to seed the PRNG (previously an explicit byte count was required).
diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c
index c7ec4c07d1..e4e9660cb4 100644
--- a/ssl/s2_clnt.c
+++ b/ssl/s2_clnt.c
@@ -435,26 +435,28 @@ static int get_server_hello(SSL *s)
return(-1);
}
s->session->cipher=sk_SSL_CIPHER_value(cl,i);
- }
- if (s->session->peer != NULL)
- X509_free(s->session->peer);
-
-#if 0 /* What is all this meant to accomplish?? */
- /* hmmm, can we have the problem of the other session with this
- * cert, Free's it before we increment the reference count. */
- CRYPTO_w_lock(CRYPTO_LOCK_X509);
- s->session->peer=s->session->sess_cert->key->x509;
- /* Shouldn't do this: already locked */
- /*CRYPTO_add(&s->session->peer->references,1,CRYPTO_LOCK_X509);*/
- s->session->peer->references++;
- CRYPTO_w_unlock(CRYPTO_LOCK_X509);
-#else
- s->session->peer = s->session->sess_cert->peer_key->x509;
- /* peer_key->x509 has been set by ssl2_set_certificate. */
- CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
-#endif
+ if (s->session->peer != NULL) /* can't happen*/
+ {
+ ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_INTERNAL_ERROR);
+ return(-1);
+ }
+
+ s->session->peer = s->session->sess_cert->peer_key->x509;
+ /* peer_key->x509 has been set by ssl2_set_certificate. */
+ CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
+ }
+
+ if (s->session->peer != s->session->sess_cert->peer_key->x509)
+ /* can't happen */
+ {
+ ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_INTERNAL_ERROR);
+ return(-1);
+ }
+
s->s2->conn_id_length=s->s2->tmp.conn_id_length;
memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length);
return(1);