Consistently use 'void *' for SSL read, peek and write functions.
[openssl.git] / ssl / ssl_lib.c
index 866cd182d4c6ceafa0ff532f45bde4327f954318..f8207fa4238b03bb90dae8154e1b7dd030ea0967 100644 (file)
@@ -105,7 +105,7 @@ int SSL_clear(SSL *s)
 #else
        if (s->new_session)
                {
 #else
        if (s->new_session)
                {
-               SSLerr(SSL_F_SSL_CLEAR,SSL_R_INTERNAL_ERROR);
+               SSLerr(SSL_F_SSL_CLEAR,ERR_R_INTERNAL_ERROR);
                return 0;
                }
 #endif
                return 0;
                }
 #endif
@@ -191,9 +191,9 @@ SSL *SSL_new(SSL_CTX *ctx)
        if (s == NULL) goto err;
        memset(s,0,sizeof(SSL));
 
        if (s == NULL) goto err;
        memset(s,0,sizeof(SSL));
 
-#ifndef        NO_KRB5
+#ifndef        OPENSSL_NO_KRB5
        s->kssl_ctx = kssl_ctx_new();
        s->kssl_ctx = kssl_ctx_new();
-#endif /* NO_KRB5 */
+#endif /* OPENSSL_NO_KRB5 */
 
        if (ctx->cert != NULL)
                {
 
        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->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);
        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;
     }
 
     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) {
 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);
        }
 
        return(ret);
        }
 
-#ifndef NO_SOCK
+#ifndef OPENSSL_NO_SOCK
 int SSL_set_fd(SSL *s,int fd)
        {
        int ret=0;
 int SSL_set_fd(SSL *s,int fd)
        {
        int ret=0;
@@ -719,7 +766,7 @@ long SSL_get_default_timeout(SSL *s)
        return(s->method->get_timeout());
        }
 
        return(s->method->get_timeout());
        }
 
-int SSL_read(SSL *s,char *buf,int num)
+int SSL_read(SSL *s,void *buf,int num)
        {
        if (s->handshake_func == 0)
                {
        {
        if (s->handshake_func == 0)
                {
@@ -735,8 +782,14 @@ int SSL_read(SSL *s,char *buf,int num)
        return(s->method->ssl_read(s,buf,num));
        }
 
        return(s->method->ssl_read(s,buf,num));
        }
 
-int SSL_peek(SSL *s,char *buf,int num)
+int SSL_peek(SSL *s,void *buf,int num)
        {
        {
+       if (s->handshake_func == 0)
+               {
+               SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
+               return -1;
+               }
+
        if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
                {
                return(0);
        if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
                {
                return(0);
@@ -744,7 +797,7 @@ int SSL_peek(SSL *s,char *buf,int num)
        return(s->method->ssl_peek(s,buf,num));
        }
 
        return(s->method->ssl_peek(s,buf,num));
        }
 
-int SSL_write(SSL *s,const char *buf,int num)
+int SSL_write(SSL *s,const void *buf,int num)
        {
        if (s->handshake_func == 0)
                {
        {
        if (s->handshake_func == 0)
                {
@@ -1092,6 +1145,11 @@ unsigned long SSL_SESSION_hash(SSL_SESSION *a)
        return(l);
        }
 
        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)
 int SSL_SESSION_cmp(SSL_SESSION *a,SSL_SESSION *b)
        {
        if (a->ssl_version != b->ssl_version)
@@ -1101,6 +1159,13 @@ int SSL_SESSION_cmp(SSL_SESSION *a,SSL_SESSION *b)
        return(memcmp(a->session_id,b->session_id,a->session_id_length));
        }
 
        return(memcmp(a->session_id,b->session_id,a->session_id_length));
        }
 
+/* These wrapper functions should remain rather than redeclaring
+ * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
+ * variable. The reason is that the functions aren't static, they're exposed via
+ * ssl.h. */
+static IMPLEMENT_LHASH_HASH_FN(SSL_SESSION_hash, SSL_SESSION *)
+static IMPLEMENT_LHASH_COMP_FN(SSL_SESSION_cmp, SSL_SESSION *)
+
 SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
        {
        SSL_CTX *ret=NULL;
 SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
        {
        SSL_CTX *ret=NULL;
@@ -1136,6 +1201,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->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));
 
 
        memset((char *)&ret->stats,0,sizeof(ret->stats));
 
@@ -1164,7 +1230,8 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
        ret->default_passwd_callback_userdata=NULL;
        ret->client_cert_cb=NULL;
 
        ret->default_passwd_callback_userdata=NULL;
        ret->client_cert_cb=NULL;
 
-       ret->sessions=lh_new(SSL_SESSION_hash,SSL_SESSION_cmp);
+       ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash),
+                       LHASH_COMP_FN(SSL_SESSION_cmp));
        if (ret->sessions == NULL) goto err;
        ret->cert_store=X509_STORE_new();
        if (ret->cert_store == NULL) goto err;
        if (ret->sessions == NULL) goto err;
        ret->cert_store=X509_STORE_new();
        if (ret->cert_store == NULL) goto err;
@@ -1211,8 +1278,10 @@ err2:
        return(NULL);
        }
 
        return(NULL);
        }
 
+#if 0
 static void SSL_COMP_free(SSL_COMP *comp)
     { OPENSSL_free(comp); }
 static void SSL_COMP_free(SSL_COMP *comp)
     { OPENSSL_free(comp); }
+#endif
 
 void SSL_CTX_free(SSL_CTX *a)
        {
 
 void SSL_CTX_free(SSL_CTX *a)
        {
@@ -1306,14 +1375,14 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
 
        kl=SSL_C_EXPORT_PKEYLENGTH(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
        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));
        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));
@@ -1387,7 +1456,7 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
        mask|=SSL_aNULL;
        emask|=SSL_aNULL;
 
        mask|=SSL_aNULL;
        emask|=SSL_aNULL;
 
-#ifndef NO_KRB5
+#ifndef OPENSSL_NO_KRB5
        mask|=SSL_kKRB5|SSL_aKRB5;
        emask|=SSL_kKRB5|SSL_aKRB5;
 #endif
        mask|=SSL_kKRB5|SSL_aKRB5;
        emask|=SSL_kKRB5|SSL_aKRB5;
 #endif
@@ -1431,7 +1500,7 @@ X509 *ssl_get_server_send_cert(SSL *s)
                }
        else /* if (kalg & SSL_aNULL) */
                {
                }
        else /* if (kalg & SSL_aNULL) */
                {
-               SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,SSL_R_INTERNAL_ERROR);
+               SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR);
                return(NULL);
                }
        if (c->pkeys[i].x509 == NULL) return(NULL);
                return(NULL);
                }
        if (c->pkeys[i].x509 == NULL) return(NULL);
@@ -1460,7 +1529,7 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher)
                }
        else /* if (alg & SSL_aNULL) */
                {
                }
        else /* if (alg & SSL_aNULL) */
                {
-               SSLerr(SSL_F_SSL_GET_SIGN_PKEY,SSL_R_INTERNAL_ERROR);
+               SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);
                return(NULL);
                }
        }
                return(NULL);
                }
        }
@@ -1708,6 +1777,10 @@ SSL *SSL_dup(SSL *s)
 
                if (s->cert != NULL)
                        {
 
                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;
                        ret->cert = ssl_cert_dup(s->cert);
                        if (ret->cert == NULL)
                                goto err;
@@ -1932,7 +2005,7 @@ SSL_CTX *SSL_get_SSL_CTX(SSL *ssl)
        return(ssl->ctx);
        }
 
        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));
 int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
        {
        return(X509_STORE_set_default_paths(ctx->cert_store));
@@ -2034,7 +2107,7 @@ int SSL_want(SSL *s)
  * \param cb the callback
  */
 
  * \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))
 void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
                                                          int is_export,
                                                          int keylength))
@@ -2071,7 +2144,7 @@ RSA *cb(SSL *ssl,int is_export,int keylength)
  * \param dh the callback
  */
 
  * \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))
     {
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
                                                        int keylength))
     {
@@ -2085,7 +2158,7 @@ void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
     }
 #endif
 
     }
 #endif
 
-#if defined(_WINDLL) && defined(WIN16)
+#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
 #include "../crypto/bio/bss_file.c"
 #endif
 
 #include "../crypto/bio/bss_file.c"
 #endif