Fix an oversight - when checking a potential session ID for conflicts with
[openssl.git] / ssl / ssl_lib.c
index c757ea874e638d885ff59f5e8985d69c0b88525a..75816e70da7cd1a65622123063d5576cd3d10dad 100644 (file)
@@ -191,9 +191,9 @@ SSL *SSL_new(SSL_CTX *ctx)
        if (s == NULL) goto err;
        memset(s,0,sizeof(SSL));
 
-#ifndef        NO_KRB5
+#ifndef        OPENSSL_NO_KRB5
        s->kssl_ctx = kssl_ctx_new();
-#endif /* NO_KRB5 */
+#endif /* OPENSSL_NO_KRB5 */
 
        if (ctx->cert != NULL)
                {
@@ -218,6 +218,7 @@ SSL *SSL_new(SSL_CTX *ctx)
        s->verify_mode=ctx->verify_mode;
        s->verify_depth=ctx->verify_depth;
        s->verify_callback=ctx->default_verify_callback;
+       s->generate_session_id=ctx->generate_session_id;
        s->purpose = ctx->purpose;
        s->trust = ctx->trust;
        CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
@@ -282,6 +283,52 @@ int SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
     return 1;
     }
 
+int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
+       {
+       CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+       ctx->generate_session_id = cb;
+       CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+       return 1;
+       }
+
+int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
+       {
+       CRYPTO_w_lock(CRYPTO_LOCK_SSL);
+       ssl->generate_session_id = cb;
+       CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
+       return 1;
+       }
+
+int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+                               unsigned int id_len)
+       {
+       /* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
+        * we can "construct" a session to give us the desired check - ie. to
+        * find if there's a session in the hash table that would conflict with
+        * any new session built out of this id/id_len and the ssl_version in
+        * use by this SSL. */
+       SSL_SESSION r, *p;
+       r.ssl_version = ssl->version;
+       r.session_id_length = id_len;
+       memcpy(r.session_id, id, id_len);
+       /* NB: SSLv2 always uses a fixed 16-byte session ID, so even if a
+        * callback is calling us to check the uniqueness of a shorter ID, it
+        * must be compared as a padded-out ID because that is what it will be
+        * converted to when the callback has finished choosing it. */
+       if((r.ssl_version == SSL2_VERSION) &&
+                       (id_len < SSL2_SSL_SESSION_ID_LENGTH))
+               {
+               memset(r.session_id + id_len, 0,
+                       SSL2_SSL_SESSION_ID_LENGTH - id_len);
+               r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH;
+               }
+
+       CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
+       p = (SSL_SESSION *)lh_retrieve(ssl->ctx->sessions, &r);
+       CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+       return (p != NULL);
+       }
+
 int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
 {
        if(X509_PURPOSE_get_by_id(purpose) == -1) {
@@ -425,7 +472,7 @@ int SSL_get_fd(SSL *s)
        return(ret);
        }
 
-#ifndef NO_SOCK
+#ifndef OPENSSL_NO_SOCK
 int SSL_set_fd(SSL *s,int fd)
        {
        int ret=0;
@@ -1092,6 +1139,11 @@ unsigned long SSL_SESSION_hash(SSL_SESSION *a)
        return(l);
        }
 
+/* NB: If this function (or indeed the hash function which uses a sort of
+ * coarser function than this one) is changed, ensure
+ * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
+ * able to construct an SSL_SESSION that will collide with any existing session
+ * with a matching session ID. */
 int SSL_SESSION_cmp(SSL_SESSION *a,SSL_SESSION *b)
        {
        if (a->ssl_version != b->ssl_version)
@@ -1143,6 +1195,7 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
        ret->new_session_cb=NULL;
        ret->remove_session_cb=NULL;
        ret->get_session_cb=NULL;
+       ret->generate_session_id=NULL;
 
        memset((char *)&ret->stats,0,sizeof(ret->stats));
 
@@ -1316,14 +1369,14 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
 
        kl=SSL_C_EXPORT_PKEYLENGTH(cipher);
 
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
        rsa_tmp=(c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
        rsa_tmp_export=(c->rsa_tmp_cb != NULL ||
                (rsa_tmp && RSA_size(c->rsa_tmp)*8 <= kl));
 #else
        rsa_tmp=rsa_tmp_export=0;
 #endif
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
        dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
        dh_tmp_export=(c->dh_tmp_cb != NULL ||
                (dh_tmp && DH_size(c->dh_tmp)*8 <= kl));
@@ -1397,7 +1450,7 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
        mask|=SSL_aNULL;
        emask|=SSL_aNULL;
 
-#ifndef NO_KRB5
+#ifndef OPENSSL_NO_KRB5
        mask|=SSL_kKRB5|SSL_aKRB5;
        emask|=SSL_kKRB5|SSL_aKRB5;
 #endif
@@ -1718,6 +1771,10 @@ SSL *SSL_dup(SSL *s)
 
                if (s->cert != NULL)
                        {
+                       if (ret->cert != NULL)
+                               {
+                               ssl_cert_free(ret->cert);
+                               }
                        ret->cert = ssl_cert_dup(s->cert);
                        if (ret->cert == NULL)
                                goto err;
@@ -1942,7 +1999,7 @@ SSL_CTX *SSL_get_SSL_CTX(SSL *ssl)
        return(ssl->ctx);
        }
 
-#ifndef NO_STDIO
+#ifndef OPENSSL_NO_STDIO
 int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
        {
        return(X509_STORE_set_default_paths(ctx->cert_store));
@@ -2044,7 +2101,7 @@ int SSL_want(SSL *s)
  * \param cb the callback
  */
 
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
 void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
                                                          int is_export,
                                                          int keylength))
@@ -2081,7 +2138,7 @@ RSA *cb(SSL *ssl,int is_export,int keylength)
  * \param dh the callback
  */
 
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
                                                        int keylength))
     {
@@ -2095,7 +2152,7 @@ void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
     }
 #endif
 
-#if defined(_WINDLL) && defined(WIN16)
+#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
 #include "../crypto/bio/bss_file.c"
 #endif