Reorder inclusion of header files:
[openssl.git] / ssl / s3_srvr.c
index 94da180d08be65b0798f6f6efc3cb358001302b2..270afb8166657611aeffdac7461bec0e8c3f2dce 100644 (file)
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 
 #include <stdio.h>
+#include "ssl_locl.h"
+#include "kssl_lcl.h"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 #include <openssl/krb5_asn.h>
-#include "ssl_locl.h"
-#ifndef OPENSSL_NO_KRB5
-#include "kssl_lcl.h"
-#endif /* OPENSSL_NO_KRB5 */
 #include <openssl/md5.h>
 
 static SSL_METHOD *ssl3_get_server_method(int ver);
@@ -166,7 +164,7 @@ int ssl3_accept(SSL *s)
        {
        BUF_MEM *buf;
        unsigned long l,Time=time(NULL);
-       void (*cb)()=NULL;
+       void (*cb)(const SSL *ssl,int type,int val)=NULL;
        long num1;
        int ret= -1;
        int new_state,state,skip=0;
@@ -181,8 +179,8 @@ int ssl3_accept(SSL *s)
                cb=s->ctx->info_callback;
 
        /* init things to blank */
-       if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
        s->in_handshake++;
+       if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
 
        if (s->cert == NULL)
                {
@@ -273,9 +271,7 @@ int ssl3_accept(SSL *s)
 
                case SSL3_ST_SW_HELLO_REQ_C:
                        s->state=SSL_ST_OK;
-                       ret=1;
-                       goto end;
-                       /* break; */
+                       break;
 
                case SSL3_ST_SR_CLNT_HELLO_A:
                case SSL3_ST_SR_CLNT_HELLO_B:
@@ -284,6 +280,7 @@ int ssl3_accept(SSL *s)
                        s->shutdown=0;
                        ret=ssl3_get_client_hello(s);
                        if (ret <= 0) goto end;
+                       s->new_session = 2;
                        s->state=SSL3_ST_SW_SRVR_HELLO_A;
                        s->init_num=0;
                        break;
@@ -524,20 +521,25 @@ int ssl3_accept(SSL *s)
                        /* remove buffering on output */
                        ssl_free_wbio_buffer(s);
 
-                       if (s->new_session == 2)
-                               s->new_session=0;
-                       /* if s->new_session is still 1, we have only sent a HelloRequest */
                        s->init_num=0;
 
-                       ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
-
-                       s->ctx->stats.sess_accept_good++;
-                       /* s->server=1; */
-                       s->handshake_func=ssl3_accept;
-                       ret=1;
-
-                       if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+                       if (s->new_session == 2) /* skipped if we just sent a HelloRequest */
+                               {
+                               /* actually not necessarily a 'new' session unless
+                                * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
+                               
+                               s->new_session=0;
+                               
+                               ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
+                               
+                               s->ctx->stats.sess_accept_good++;
+                               /* s->server=1; */
+                               s->handshake_func=ssl3_accept;
 
+                               if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+                               }
+                       
+                       ret = 1;
                        goto end;
                        /* break; */
 
@@ -570,9 +572,9 @@ int ssl3_accept(SSL *s)
 end:
        /* BIO_flush(s->wbio); */
 
+       s->in_handshake--;
        if (cb != NULL)
                cb(s,SSL_CB_ACCEPT_EXIT,ret);
-       s->in_handshake--;
        return(ret);
        }
 
@@ -660,13 +662,25 @@ static int ssl3_get_client_hello(SSL *s)
                &ok);
 
        if (!ok) return((int)n);
-       d=p=(unsigned char *)s->init_buf->data;
+       d=p=(unsigned char *)s->init_msg;
 
        /* use version from inside client hello, not from record header
         * (may differ: see RFC 2246, Appendix E, second paragraph) */
        s->client_version=(((int)p[0])<<8)|(int)p[1];
        p+=2;
 
+       if (s->client_version < s->version)
+               {
+               SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
+               if ((s->client_version>>8) == SSL3_VERSION_MAJOR) 
+                       {
+                       /* similar to ssl3_get_record, send alert using remote version number */
+                       s->version = s->client_version;
+                       }
+               al = SSL_AD_PROTOCOL_VERSION;
+               goto f_err;
+               }
+
        /* load the client random */
        memcpy(s->s3->client_random,p,SSL3_RANDOM_SIZE);
        p+=SSL3_RANDOM_SIZE;
@@ -704,11 +718,6 @@ static int ssl3_get_client_hello(SSL *s)
                        }
                }
 
-       if (s->new_session)
-               /* actually not necessarily a 'new' section unless
-                * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
-               s->new_session = 2;
-
        p+=j;
        n2s(p,i);
        if ((i == 0) && (j != 0))
@@ -718,7 +727,7 @@ static int ssl3_get_client_hello(SSL *s)
                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_SPECIFIED);
                goto f_err;
                }
-       if ((i+p) > (d+n))
+       if ((p+i) >= (d+n))
                {
                /* not enough data */
                al=SSL_AD_DECODE_ERROR;
@@ -775,6 +784,13 @@ static int ssl3_get_client_hello(SSL *s)
 
        /* compression */
        i= *(p++);
+       if ((p+i) > (d+n))
+               {
+               /* not enough data */
+               al=SSL_AD_DECODE_ERROR;
+               SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
+               goto f_err;
+               }
        q=p;
        for (j=0; j<i; j++)
                {
@@ -822,7 +838,7 @@ static int ssl3_get_client_hello(SSL *s)
        /* TLS does not mind if there is extra stuff */
        if (s->version == SSL3_VERSION)
                {
-               if (p > (d+n))
+               if (p < (d+n))
                        {
                        /* wrong number of bytes,
                         * there could be more to follow */
@@ -1176,12 +1192,12 @@ static int ssl3_send_server_key_exchange(SSL *s)
                                j=0;
                                for (num=2; num > 0; num--)
                                        {
-                                       EVP_DigestInit(&md_ctx,(num == 2)
-                                               ?s->ctx->md5:s->ctx->sha1);
+                                       EVP_DigestInit_ex(&md_ctx,(num == 2)
+                                               ?s->ctx->md5:s->ctx->sha1, NULL);
                                        EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
                                        EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
                                        EVP_DigestUpdate(&md_ctx,&(d[4]),n);
-                                       EVP_DigestFinal(&md_ctx,q,
+                                       EVP_DigestFinal_ex(&md_ctx,q,
                                                (unsigned int *)&i);
                                        q+=i;
                                        j+=i;
@@ -1201,7 +1217,7 @@ static int ssl3_send_server_key_exchange(SSL *s)
                                if (pkey->type == EVP_PKEY_DSA)
                                {
                                /* lets do DSS */
-                               EVP_SignInit(&md_ctx,EVP_dss1());
+                               EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL);
                                EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
                                EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
                                EVP_SignUpdate(&md_ctx,&(d[4]),n);
@@ -1357,7 +1373,7 @@ static int ssl3_get_client_key_exchange(SSL *s)
                &ok);
 
        if (!ok) return((int)n);
-       p=(unsigned char *)s->init_buf->data;
+       p=(unsigned char *)s->init_msg;
 
        l=s->s3->tmp.new_cipher->algorithms;
 
@@ -1548,24 +1564,26 @@ static int ssl3_get_client_key_exchange(SSL *s)
                krb5_timestamp          authtime = 0;
                krb5_ticket_times       ttimes;
 
+               EVP_CIPHER_CTX_init(&ciph_ctx);
+
                 if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
 
                n2s(p,i);
                enc_ticket.length = i;
-               enc_ticket.data = p;
+               enc_ticket.data = (char *)p;
                p+=enc_ticket.length;
 
                n2s(p,i);
                authenticator.length = i;
-               authenticator.data = p;
+               authenticator.data = (char *)p;
                p+=authenticator.length;
 
                n2s(p,i);
                enc_pms.length = i;
-               enc_pms.data = p;
+               enc_pms.data = (char *)p;
                p+=enc_pms.length;
 
-               if ((unsigned long)n != enc_ticket.length + authenticator.length +
+               if (n != enc_ticket.length + authenticator.length +
                                                enc_pms.length + 6)
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
@@ -1620,14 +1638,14 @@ static int ssl3_get_client_key_exchange(SSL *s)
 
                memset(iv, 0, EVP_MAX_IV_LENGTH);       /* per RFC 1510 */
 
-               if (!EVP_DecryptInit(&ciph_ctx,enc,kssl_ctx->key,iv))
+               if (!EVP_DecryptInit_ex(&ciph_ctx,enc,NULL,kssl_ctx->key,iv))
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                SSL_R_DECRYPTION_FAILED);
                        goto err;
                        }
                if (!EVP_DecryptUpdate(&ciph_ctx, pms,&outl,
-                                       enc_pms.data, enc_pms.length))
+                                       (unsigned char *)enc_pms.data, enc_pms.length))
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                SSL_R_DECRYPTION_FAILED);
@@ -1639,7 +1657,7 @@ static int ssl3_get_client_key_exchange(SSL *s)
                                SSL_R_DATA_LENGTH_TOO_LONG);
                        goto err;
                        }
-               if (!EVP_DecryptFinal(&ciph_ctx,&(pms[outl]),&padl))
+               if (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl))
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                SSL_R_DECRYPTION_FAILED);
@@ -1758,7 +1776,7 @@ static int ssl3_get_cert_verify(SSL *s)
                }
 
        /* we now have a signature that we need to verify */
-       p=(unsigned char *)s->init_buf->data;
+       p=(unsigned char *)s->init_msg;
        n2s(p,i);
        n-=2;
        if (i > n)
@@ -1874,7 +1892,7 @@ static int ssl3_get_client_certificate(SSL *s)
                SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_WRONG_MESSAGE_TYPE);
                goto f_err;
                }
-       d=p=(unsigned char *)s->init_buf->data;
+       d=p=(unsigned char *)s->init_msg;
 
        if ((sk=sk_X509_new_null()) == NULL)
                {