Various Win32 fixes. Change args in do_ms.bat to put platform last. Fix
[openssl.git] / ssl / ssl_lib.c
index cbc89b888de0b16625338da41700d4560877fc70..bf1c900129247b5b7114d04ce7c353449817148a 100644 (file)
@@ -70,7 +70,7 @@ static STACK *ssl_ctx_meth=NULL;
 static int ssl_meth_num=0;
 static int ssl_ctx_meth_num=0;
 
-SSL3_ENC_METHOD ssl3_undef_enc_method={
+OPENSSL_GLOBAL SSL3_ENC_METHOD ssl3_undef_enc_method={
        ssl_undefined_function,
        ssl_undefined_function,
        ssl_undefined_function,
@@ -510,10 +510,10 @@ STACK_OF(X509) *SSL_get_peer_cert_chain(SSL *s)
        {
        STACK_OF(X509) *r;
        
-       if ((s == NULL) || (s->session == NULL) || (s->session->cert == NULL))
+       if ((s == NULL) || (s->session == NULL) || (s->session->sess_cert == NULL))
                r=NULL;
        else
-               r=s->session->cert->cert_chain;
+               r=s->session->sess_cert->cert_chain;
 
        return(r);
        }
@@ -592,11 +592,19 @@ int SSL_check_private_key(SSL *ssl)
 
 int SSL_accept(SSL *s)
        {
+       if (s->handshake_func == 0)
+               /* Not properly initialized yet */
+               SSL_set_accept_state(s);
+
        return(s->method->ssl_accept(s));
        }
 
 int SSL_connect(SSL *s)
        {
+       if (s->handshake_func == 0)
+               /* Not properly initialized yet */
+               SSL_set_connect_state(s);
+
        return(s->method->ssl_connect(s));
        }
 
@@ -607,6 +615,12 @@ long SSL_get_default_timeout(SSL *s)
 
 int SSL_read(SSL *s,char *buf,int num)
        {
+       if (s->handshake_func == 0)
+               {
+               SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
+               return -1;
+               }
+
        if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
                {
                s->rwstate=SSL_NOTHING;
@@ -626,6 +640,12 @@ int SSL_peek(SSL *s,char *buf,int num)
 
 int SSL_write(SSL *s,const char *buf,int num)
        {
+       if (s->handshake_func == 0)
+               {
+               SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
+               return -1;
+               }
+
        if (s->shutdown & SSL_SENT_SHUTDOWN)
                {
                s->rwstate=SSL_NOTHING;
@@ -637,6 +657,18 @@ int SSL_write(SSL *s,const char *buf,int num)
 
 int SSL_shutdown(SSL *s)
        {
+       /* Note that this function behaves differently from what one might
+        * expect.  Return values are 0 for no success (yet),
+        * 1 for success; but calling it once is usually not enough,
+        * even if blocking I/O is used (see ssl3_shutdown).
+        */
+
+       if (s->handshake_func == 0)
+               {
+               SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED);
+               return -1;
+               }
+
        if ((s != NULL) && !SSL_in_init(s))
                return(s->method->ssl_shutdown(s));
        else
@@ -1089,12 +1121,12 @@ void SSL_CTX_free(SSL_CTX *a)
        Free((char *)a);
        }
 
-void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx,int (*cb)())
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
        {
        ctx->default_passwd_callback=cb;
        }
 
-void SSL_CTX_set_cert_verify_cb(SSL_CTX *ctx,int (*cb)(),char *arg)
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,int (*cb)(),char *arg)
        {
        ctx->app_verify_callback=cb;
        ctx->app_verify_arg=arg;
@@ -1479,7 +1511,7 @@ char *SSL_get_version(SSL *s)
        }
 
 SSL *SSL_dup(SSL *s)
-        {
+       {
        STACK_OF(X509_NAME) *sk;
        X509_NAME *xn;
         SSL *ret;
@@ -1488,8 +1520,31 @@ SSL *SSL_dup(SSL *s)
        if ((ret=SSL_new(SSL_get_SSL_CTX(s))) == NULL)
            return(NULL);
                          
-       /* This copies version, session-id, SSL_METHOD and 'cert' */
-       SSL_copy_session_id(ret,s);
+       if (s->session != NULL)
+               {
+               /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */
+               SSL_copy_session_id(ret,s);
+               }
+       else
+               {
+               /* No session has been established yet, so we have to expect
+                * that s->cert or ret->cert will be changed later --
+                * they should not both point to the same object,
+                * and thus we can't use SSL_copy_session_id. */
+
+               ret->method = s->method;
+               ret->method->ssl_new(ret);
+
+               if (s->cert != NULL)
+                       {
+                       ret->cert = ssl_cert_dup(s->cert);
+                       if (ret->cert == NULL)
+                               goto err;
+                       }
+                               
+               SSL_set_session_id_context(ret,
+                       s->sid_ctx, s->sid_ctx_length);
+               }
 
        SSL_set_read_ahead(ret,SSL_get_read_ahead(s));
        SSL_set_verify(ret,SSL_get_verify_mode(s),
@@ -1565,18 +1620,18 @@ err:
 
 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);
-                s->enc_read_ctx=NULL;
-                }
-        if (s->enc_write_ctx != NULL)
-                {
-                EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
-                Free(s->enc_write_ctx);
-                s->enc_write_ctx=NULL;
-                }
+       if (s->enc_read_ctx != NULL)
+               {
+               EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
+               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);
+               s->enc_write_ctx=NULL;
+               }
        if (s->expand != NULL)
                {
                COMP_CTX_free(s->expand);