Remainder of SSL purpose and trust code: trust and purpose setting in
[oweals/openssl.git] / ssl / ssl_sess.c
index e918d9854f19a82a2265de1c088c89f23cdb3cc8..74ec2178a936a0cadcf62cb6e7ddbc6aababd022 100644 (file)
@@ -67,19 +67,41 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
 static int ssl_session_num=0;
 static STACK *ssl_session_meth=NULL;
 
+#if 1 /* traditional SSLeay behaviour */
 SSL_SESSION *SSL_get_session(SSL *ssl)
        {
        return(ssl->session);
        }
+#else /* suggested change: increase reference counter so that a session
+       * can later be set in a new SSL object.
+       * Objections:
+       *   -- the modified function should have a new name (or old
+       *      applications, including s_client, leak memory);
+       *   -- the locking seems unnecessary given that SSL structures
+       *      usually cannot be safely shared between threads anyway. */
+SSL_SESSION *SSL_get_session(SSL *ssl)
+       {
+       SSL_SESSION *sess;
+       /* Need to lock this all up rather than just use CRYPTO_add so that
+        * somebody doesn't free ssl->session between when we check it's
+        * non-null and when we up the reference count. */
+       CRYPTO_r_lock(CRYPTO_LOCK_SSL_SESSION);
+       sess = ssl->session;
+       if(sess)
+               sess->references++;
+       CRYPTO_r_unlock(CRYPTO_LOCK_SSL_SESSION);
+       return(sess);
+       }
+#endif
 
 int SSL_SESSION_get_ex_new_index(long argl, char *argp, int (*new_func)(),
             int (*dup_func)(), void (*free_func)())
-        {
-        ssl_session_num++;
-        return(CRYPTO_get_ex_new_index(ssl_session_num-1,
+       {
+       ssl_session_num++;
+       return(CRYPTO_get_ex_new_index(ssl_session_num-1,
                &ssl_session_meth,
-                argl,argp,new_func,dup_func,free_func));
-        }
+               argl,argp,new_func,dup_func,free_func));
+       }
 
 int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
        {
@@ -103,6 +125,7 @@ SSL_SESSION *SSL_SESSION_new(void)
                }
        memset(ss,0,sizeof(SSL_SESSION));
 
+       ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
        ss->references=1;
        ss->timeout=60*5+4; /* 5 minute timeout by default */
        ss->time=time(NULL);
@@ -181,6 +204,7 @@ int ssl_get_new_session(SSL *s, int session)
        ss->sid_ctx_length=s->sid_ctx_length;
        s->session=ss;
        ss->ssl_version=s->version;
+       ss->verify_result = X509_V_OK;
 
        return(1);
        }
@@ -203,8 +227,9 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
                {
                CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
                ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,(char *)&data);
-               /* don't allow other threads to steal it: */
-               CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
+               if (ret != NULL)
+                   /* don't allow other threads to steal it: */
+                   CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
                CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
                }
 
@@ -310,6 +335,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
        if (s->session != NULL)
                SSL_SESSION_free(s->session);
        s->session=ret;
+       s->verify_result = s->session->verify_result;
        return(1);
 
  err: