Don't modify s->read_ahead in SSL_clear, which is called from
[openssl.git] / ssl / ssl_lib.c
index 10d080df8f640f36f48e09e40b3cbab91210aa39..d77d340388478a2c58ba503e73bf123fc9d7f15b 100644 (file)
  * [including the GNU Public Licence.]
  */
 
+
+#include <assert.h>
 #include <stdio.h>
 #include <openssl/objects.h>
 #include <openssl/lhash.h>
 #include <openssl/x509v3.h>
 #include "ssl_locl.h"
 
-char *SSL_version_str=OPENSSL_VERSION_TEXT;
+const char *SSL_version_str=OPENSSL_VERSION_TEXT;
 
-static STACK *ssl_meth=NULL;
-static STACK *ssl_ctx_meth=NULL;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_meth=NULL;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_ctx_meth=NULL;
 static int ssl_meth_num=0;
 static int ssl_ctx_meth_num=0;
 
 OPENSSL_GLOBAL SSL3_ENC_METHOD ssl3_undef_enc_method={
+       /* evil casts, but these functions are only called if there's a library bug */
+       (int (*)(SSL *,int))ssl_undefined_function,
+       (int (*)(SSL *, unsigned char *, int))ssl_undefined_function,
        ssl_undefined_function,
-       ssl_undefined_function,
-       ssl_undefined_function,
-       ssl_undefined_function,
-       ssl_undefined_function,
-       ssl_undefined_function,
+       (int (*)(SSL *, unsigned char *, unsigned char *, int))ssl_undefined_function,
+       (int (*)(SSL*, int))ssl_undefined_function,
+       (int (*)(SSL *, EVP_MD_CTX *, EVP_MD_CTX *, const char*, int, unsigned char *))ssl_undefined_function
        };
 
 int SSL_clear(SSL *s)
@@ -94,10 +97,17 @@ int SSL_clear(SSL *s)
        s->hit=0;
        s->shutdown=0;
 
-#if 0
+#if 0 /* Disabled since version 1.10 of this file (early return not
+       * needed because SSL_clear is not called when doing renegotiation) */
        /* This is set if we are doing dynamic renegotiation so keep
         * the old cipher.  It is sort of a SSL_clear_lite :-) */
        if (s->new_session) return(1);
+#else
+       if (s->new_session)
+               {
+               SSLerr(SSL_F_SSL_CLEAR,SSL_R_INTERNAL_ERROR);
+               return 0;
+               }
 #endif
 
        state=s->state; /* Keep to check if we throw away the session-id */
@@ -109,7 +119,9 @@ int SSL_clear(SSL *s)
        s->client_version=s->version;
        s->rwstate=SSL_NOTHING;
        s->rstate=SSL_ST_READ_HEADER;
+#if 0
        s->read_ahead=s->ctx->read_ahead;
+#endif
 
        if (s->init_buf != NULL)
                {
@@ -175,7 +187,7 @@ SSL *SSL_new(SSL_CTX *ctx)
                return(NULL);
                }
 
-       s=(SSL *)Malloc(sizeof(SSL));
+       s=(SSL *)OPENSSL_malloc(sizeof(SSL));
        if (s == NULL) goto err;
        memset(s,0,sizeof(SSL));
 
@@ -221,7 +233,7 @@ SSL *SSL_new(SSL_CTX *ctx)
        s->mode=ctx->mode;
        SSL_clear(s);
 
-       CRYPTO_new_ex_data(ssl_meth,(char *)s,&s->ex_data);
+       CRYPTO_new_ex_data(ssl_meth,s,&s->ex_data);
 
        return(s);
 err:
@@ -231,7 +243,7 @@ err:
                        ssl_cert_free(s->cert);
                if (s->ctx != NULL)
                        SSL_CTX_free(s->ctx); /* decrement reference count */
-               Free(s);
+               OPENSSL_free(s);
                }
        SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
        return(NULL);
@@ -367,7 +379,7 @@ void SSL_free(SSL *s)
 
        if (s->method != NULL) s->method->ssl_free(s);
 
-       Free((char *)s);
+       OPENSSL_free(s);
        }
 
 void SSL_set_bio(SSL *s,BIO *rbio,BIO *wbio)
@@ -476,6 +488,38 @@ err:
        }
 #endif
 
+
+/* return length of latest Finished message we sent, copy to 'buf' */
+size_t SSL_get_finished(SSL *s, void *buf, size_t count)
+       {
+       size_t ret = 0;
+       
+       if (s->s3 != NULL)
+               {
+               ret = s->s3->tmp.finish_md_len;
+               if (count > ret)
+                       count = ret;
+               memcpy(buf, s->s3->tmp.finish_md, count);
+               }
+       return ret;
+       }
+
+/* return length of latest Finished message we expected, copy to 'buf' */
+size_t SSL_get_peer_finished(SSL *s, void *buf, size_t count)
+       {
+       size_t ret = 0;
+       
+       if (s->s3 != NULL)
+               {
+               ret = s->s3->tmp.peer_finish_md_len;
+               if (count > ret)
+                       count = ret;
+               memcpy(buf, s->s3->tmp.peer_finish_md, count);
+               }
+       return ret;
+       }
+
+
 int SSL_get_verify_mode(SSL *s)
        {
        return(s->verify_mode);
@@ -559,6 +603,9 @@ STACK_OF(X509) *SSL_get_peer_cert_chain(SSL *s)
        else
                r=s->session->sess_cert->cert_chain;
 
+       /* If we are a client, cert_chain includes the peer's own
+        * certificate; if we are a server, it does not. */
+       
        return(r);
        }
 
@@ -749,6 +796,20 @@ long SSL_ctrl(SSL *s,int cmd,long larg,char *parg)
                }
        }
 
+long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)())
+       {
+       switch(cmd)
+               {
+       default:
+               return(s->method->ssl_callback_ctrl(s,cmd,fp));
+               }
+       }
+
+struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx)
+       {
+       return ctx->sessions;
+       }
+
 long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,char *parg)
        {
        long l;
@@ -808,7 +869,16 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,char *parg)
                }
        }
 
-int ssl_cipher_id_cmp(SSL_CIPHER *a,SSL_CIPHER *b)
+long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)())
+       {
+       switch(cmd)
+               {
+       default:
+               return(ctx->method->ssl_ctx_callback_ctrl(ctx,cmd,fp));
+               }
+       }
+
+int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b)
        {
        long l;
 
@@ -819,7 +889,8 @@ int ssl_cipher_id_cmp(SSL_CIPHER *a,SSL_CIPHER *b)
                return((l > 0)?1:-1);
        }
 
-int ssl_cipher_ptr_id_cmp(SSL_CIPHER **ap,SSL_CIPHER **bp)
+int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
+                       const SSL_CIPHER * const *bp)
        {
        long l;
 
@@ -877,8 +948,8 @@ const char *SSL_get_cipher_list(SSL *s,int n)
        return(c->name);
        }
 
-/** specify the ciphers to be used by defaut by the SSL_CTX */
-int SSL_CTX_set_cipher_list(SSL_CTX *ctx,char *str)
+/** specify the ciphers to be used by default by the SSL_CTX */
+int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
        {
        STACK_OF(SSL_CIPHER) *sk;
        
@@ -889,7 +960,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx,char *str)
        }
 
 /** specify the ciphers to be used by the SSL */
-int SSL_set_cipher_list(SSL *s,char *str)
+int SSL_set_cipher_list(SSL *s,const char *str)
        {
        STACK_OF(SSL_CIPHER) *sk;
        
@@ -967,7 +1038,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
                return(NULL);
                }
        if ((skp == NULL) || (*skp == NULL))
-               sk=sk_SSL_CIPHER_new(NULL); /* change perhaps later */
+               sk=sk_SSL_CIPHER_new_null(); /* change perhaps later */
        else
                {
                sk= *skp;
@@ -1033,7 +1104,7 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
                SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
                goto err;
                }
-       ret=(SSL_CTX *)Malloc(sizeof(SSL_CTX));
+       ret=(SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
        if (ret == NULL)
                goto err;
 
@@ -1129,7 +1200,7 @@ err2:
        }
 
 static void SSL_COMP_free(SSL_COMP *comp)
-    { Free(comp); }
+    { OPENSSL_free(comp); }
 
 void SSL_CTX_free(SSL_CTX *a)
        {
@@ -1170,7 +1241,7 @@ void SSL_CTX_free(SSL_CTX *a)
                sk_X509_pop_free(a->extra_certs,X509_free);
        if (a->comp_methods != NULL)
                sk_SSL_COMP_pop_free(a->comp_methods,SSL_COMP_free);
-       Free((char *)a);
+       OPENSSL_free(a);
        }
 
 void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
@@ -1297,10 +1368,8 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
                emask|=SSL_aDSS;
                }
 
-#ifdef SSL_ALLOW_ADH
        mask|=SSL_aNULL;
        emask|=SSL_aNULL;
-#endif
 
        c->mask=mask;
        c->export_mask=emask;
@@ -1317,7 +1386,7 @@ X509 *ssl_get_server_send_cert(SSL *s)
        c=s->cert;
        ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
        alg=s->s3->tmp.new_cipher->algorithms;
-       is_export=SSL_IS_EXPORT(alg);
+       is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
        mask=is_export?c->export_mask:c->mask;
        kalg=alg&(SSL_MKEY_MASK|SSL_AUTH_MASK);
 
@@ -1570,7 +1639,7 @@ SSL_METHOD *ssl_bad_method(int ver)
        return(NULL);
        }
 
-char *SSL_get_version(SSL *s)
+const char *SSL_get_version(SSL *s)
        {
        if (s->version == TLS1_VERSION)
                return("TLSv1");
@@ -1695,13 +1764,13 @@ void ssl_clear_cipher_ctx(SSL *s)
        if (s->enc_read_ctx != NULL)
                {
                EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
-               Free(s->enc_read_ctx);
+               OPENSSL_free(s->enc_read_ctx);
                s->enc_read_ctx=NULL;
                }
        if (s->enc_write_ctx != NULL)
                {
                EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
-               Free(s->enc_write_ctx);
+               OPENSSL_free(s->enc_write_ctx);
                s->enc_write_ctx=NULL;
                }
        if (s->expand != NULL)
@@ -1779,19 +1848,16 @@ int ssl_init_wbio_buffer(SSL *s,int push)
 
 void ssl_free_wbio_buffer(SSL *s)
        {
-       BIO *under;
-
        if (s->bbio == NULL) return;
 
        if (s->bbio == s->wbio)
                {
                /* remove buffering */
-               under=BIO_pop(s->wbio);
-               if (under != NULL)
-                       s->wbio=under;
-               else
-                       abort(); /* ok */
-               }
+               s->wbio=BIO_pop(s->wbio);
+#ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids adding one more preprocessor symbol */
+               assert(s->wbio != NULL);
+#endif 
+       }
        BIO_free(s->bbio);
        s->bbio=NULL;
        }
@@ -1874,8 +1940,8 @@ long SSL_get_verify_result(SSL *ssl)
        return(ssl->verify_result);
        }
 
-int SSL_get_ex_new_index(long argl,char *argp,int (*new_func)(),
-                        int (*dup_func)(),void (*free_func)())
+int SSL_get_ex_new_index(long argl,void *argp,CRYPTO_EX_new *new_func,
+                        CRYPTO_EX_dup *dup_func,CRYPTO_EX_free *free_func)
        {
        ssl_meth_num++;
        return(CRYPTO_get_ex_new_index(ssl_meth_num-1,
@@ -1892,8 +1958,8 @@ void *SSL_get_ex_data(SSL *s,int idx)
        return(CRYPTO_get_ex_data(&s->ex_data,idx));
        }
 
-int SSL_CTX_get_ex_new_index(long argl,char *argp,int (*new_func)(),
-                            int (*dup_func)(),void (*free_func)())
+int SSL_CTX_get_ex_new_index(long argl,void *argp,CRYPTO_EX_new *new_func,
+                            CRYPTO_EX_dup *dup_func,CRYPTO_EX_free *free_func)
        {
        ssl_ctx_meth_num++;
        return(CRYPTO_get_ex_new_index(ssl_ctx_meth_num-1,
@@ -1942,13 +2008,16 @@ int SSL_want(SSL *s)
 void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
                                                          int is_export,
                                                          int keylength))
-    { SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,0,(char *)cb); }
-#endif
+    {
+    SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,(void (*)())cb);
+    }
 
-#ifndef NO_RSA
-void SSL_set_tmp_rsa_callback(SSL *ssl,RSA *(*cb)(SSL *ssl,int is_export,
-                                                         int keylength))
-    { SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA_CB,0,(char *)cb); }
+void SSL_set_tmp_rsa_callback(SSL *ssl,RSA *(*cb)(SSL *ssl,
+                                                 int is_export,
+                                                 int keylength))
+    {
+    SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_RSA_CB,(void (*)())cb);
+    }
 #endif
 
 #ifdef DOXYGEN
@@ -1975,11 +2044,15 @@ RSA *cb(SSL *ssl,int is_export,int keylength)
 #ifndef NO_DH
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
                                                        int keylength))
-    { SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,0,(char *)dh); }
+    {
+    SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,(void (*)())dh);
+    }
 
 void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
-                                                       int keylength))
-    { SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,0,(char *)dh); }
+                                               int keylength))
+    {
+    SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)())dh);
+    }
 #endif
 
 #if defined(_WINDLL) && defined(WIN16)