Don't send zero length session ID if stateless session resupmtion is
[openssl.git] / ssl / ssl_sess.c
index 3401d0062b40130e2070630b77c94e78a89da307..2e44a7aebde917bc44320b3c5c6b419f2813cbf6 100644 (file)
@@ -308,6 +308,14 @@ int ssl_get_new_session(SSL *s, int session)
                        SSL_SESSION_free(ss);
                        return(0);
                        }
+#ifndef OPENSSL_NO_TLSEXT
+               /* If RFC4507 ticket use empty session ID */
+               if (s->tlsext_ticket_expected)
+                       {
+                       ss->session_id_length = 0;
+                       goto sess_id_done;
+                       }
+#endif
                /* Choose which callback will set the session ID */
                CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
                if(s->generate_session_id)
@@ -350,6 +358,7 @@ int ssl_get_new_session(SSL *s, int session)
                        return(0);
                        }
 #ifndef OPENSSL_NO_TLSEXT
+               sess_id_done:
                if (s->tlsext_hostname) {
                        ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
                        if (ss->tlsext_hostname == NULL) {
@@ -406,21 +415,41 @@ int ssl_get_new_session(SSL *s, int session)
        return(1);
        }
 
-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,
+                       const unsigned char *limit)
        {
        /* This is used only by servers. */
 
-       SSL_SESSION *ret=NULL,data;
+       SSL_SESSION *ret=NULL;
        int fatal = 0;
+#ifndef OPENSSL_NO_TLSEXT
+       int r;
+#endif
 
-       data.ssl_version=s->version;
-       data.session_id_length=len;
        if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
                goto err;
-       memcpy(data.session_id,session_id,len);
-
+#ifndef OPENSSL_NO_TLSEXT
+       r = tls1_process_ticket(s, session_id, len, limit, &ret);
+       if (r == -1)
+               {
+               fatal = 1;
+               goto err;
+               }
+       else if (r == 0 || (!ret || !len))
+               goto err;
+       else if (!ret && !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
+#else
+       if (len == 0)
+               goto err;
        if (!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
+#endif
                {
+               SSL_SESSION data;
+               data.ssl_version=s->version;
+               data.session_id_length=len;
+               if (len == 0)
+                       return 0;
+               memcpy(data.session_id,session_id,len);
                CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
                ret=(SSL_SESSION *)lh_retrieve(s->session_ctx->sessions,&data);
                if (ret != NULL)
@@ -678,6 +707,7 @@ void SSL_SESSION_free(SSL_SESSION *ss)
        if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
 #ifndef OPENSSL_NO_TLSEXT
        if (ss->tlsext_hostname != NULL) OPENSSL_free(ss->tlsext_hostname);
+       if (ss->tlsext_tick != NULL) OPENSSL_free(ss->tlsext_tick);
 #ifndef OPENSSL_NO_EC
        ss->tlsext_ecpointformatlist_length = 0;
        if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist);