Additional, more descriptive error message for rejection of a session ID
[openssl.git] / ssl / ssl_sess.c
index 26a80d66639133f4540461625e1c0d362ae4e96e..cac408c38e805689c102f6a7c71accfc2d409fec 100644 (file)
 #include <openssl/rand.h>
 #include "ssl_locl.h"
 
 #include <openssl/rand.h>
 #include "ssl_locl.h"
 
-#ifndef NOPROTO
 static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
 static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
 static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
 static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
-#else
-static void SSL_SESSION_list_remove();
-static void SSL_SESSION_list_add();
-#endif
-
+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;
 
 static int ssl_session_num=0;
 static STACK *ssl_session_meth=NULL;
 
@@ -120,6 +115,8 @@ SSL_SESSION *SSL_SESSION_new(void)
 
 int ssl_get_new_session(SSL *s, int session)
        {
 
 int ssl_get_new_session(SSL *s, int session)
        {
+       /* This gets used by clients and servers. */
+
        SSL_SESSION *ss=NULL;
 
        if ((ss=SSL_SESSION_new()) == NULL) return(0);
        SSL_SESSION *ss=NULL;
 
        if ((ss=SSL_SESSION_new()) == NULL) return(0);
@@ -188,6 +185,8 @@ int ssl_get_new_session(SSL *s, int session)
 
 int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
        {
 
 int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
        {
+       /* This is used only by servers. */
+
        SSL_SESSION *ret=NULL,data;
        int copy=1;
 
        SSL_SESSION *ret=NULL,data;
        int copy=1;
 
@@ -226,7 +225,11 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
           && (!s->sid_ctx_length || ret->sid_ctx_length != s->sid_ctx_length
               || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length)))
            {
           && (!s->sid_ctx_length || ret->sid_ctx_length != s->sid_ctx_length
               || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length)))
            {
-           SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
+               if (s->sid_ctx_length)
+                       SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
+               else
+                       /* application should have used SSL[_CTX]_set_session_id_context */
+                       SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
            return 0;
            }
 
            return 0;
            }
 
@@ -310,8 +313,8 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
                        while (SSL_CTX_sess_number(ctx) >
                                SSL_CTX_sess_get_cache_size(ctx))
                                {
                        while (SSL_CTX_sess_number(ctx) >
                                SSL_CTX_sess_get_cache_size(ctx))
                                {
-                               if (!SSL_CTX_remove_session(ctx,
-                                       ctx->session_cache_tail))
+                               if (!remove_session_lock(ctx,
+                                       ctx->session_cache_tail, 0))
                                        break;
                                else
                                        ctx->stats.sess_cache_full++;
                                        break;
                                else
                                        ctx->stats.sess_cache_full++;
@@ -323,13 +326,18 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
        }
 
 int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
        }
 
 int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
+{
+       return remove_session_lock(ctx, c, 1);
+}
+
+static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
        {
        SSL_SESSION *r;
        int ret=0;
 
        if ((c != NULL) && (c->session_id_length != 0))
                {
        {
        SSL_SESSION *r;
        int ret=0;
 
        if ((c != NULL) && (c->session_id_length != 0))
                {
-               CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+               if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
                r=(SSL_SESSION *)lh_delete(ctx->sessions,(char *)c);
                if (r != NULL)
                        {
                r=(SSL_SESSION *)lh_delete(ctx->sessions,(char *)c);
                if (r != NULL)
                        {
@@ -337,7 +345,7 @@ int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
                        SSL_SESSION_list_remove(ctx,c);
                        }
 
                        SSL_SESSION_list_remove(ctx,c);
                        }
 
-               CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+               if(lck) CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
 
                if (ret)
                        {
 
                if (ret)
                        {
@@ -377,7 +385,7 @@ void SSL_SESSION_free(SSL_SESSION *ss)
        memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH);
        memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH);
        memset(ss->session_id,0,SSL_MAX_SSL_SESSION_ID_LENGTH);
        memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH);
        memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH);
        memset(ss->session_id,0,SSL_MAX_SSL_SESSION_ID_LENGTH);
-       if (ss->cert != NULL) ssl_cert_free(ss->cert);
+       if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert);
        if (ss->peer != NULL) X509_free(ss->peer);
        if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
        memset(ss,0,sizeof(*ss));
        if (ss->peer != NULL) X509_free(ss->peer);
        if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
        memset(ss,0,sizeof(*ss));