Make maximum certifcate chain size accepted from the peer application
[openssl.git] / ssl / s3_srvr.c
index bcf8c875cc7cd71a85faba2ecd9aa041d4a013de..de840808447d6c663238beb242290887021d776b 100644 (file)
 #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);
 static int ssl3_get_client_hello(SSL *s);
@@ -270,6 +270,10 @@ int ssl3_accept(SSL *s)
                                && !(l & SSL_KRB5)
 #endif /* OPENSSL_NO_KRB5 */
                                )
+                               /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
+                                * even when forbidden by protocol specs
+                                * (handshake may fail as clients are not required to
+                                * be able to handle this) */
                                s->s3->tmp.use_rsa_tmp=1;
                        else
                                s->s3->tmp.use_rsa_tmp=0;
@@ -311,7 +315,9 @@ int ssl3_accept(SSL *s)
                                ((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) &&
                                 /* ... except when the application insists on verification
                                  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
-                                !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)))
+                                !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
+                                 /* never request cert in Kerberos ciphersuites */
+                                (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5))
                                {
                                /* no cert request */
                                skip=1;
@@ -544,7 +550,7 @@ static int ssl3_check_client_hello(SSL *s)
                SSL3_ST_SR_CERT_A,
                SSL3_ST_SR_CERT_B,
                -1,
-               SSL3_RT_MAX_PLAIN_LENGTH,
+               s->max_cert_list,
                &ok);
        if (!ok) return((int)n);
        s->s3->tmp.reuse_message = 1;
@@ -947,6 +953,7 @@ static int ssl3_send_server_key_exchange(SSL *s)
        BUF_MEM *buf;
        EVP_MD_CTX md_ctx;
 
+       EVP_MD_CTX_init(&md_ctx);
        if (s->state == SSL3_ST_SW_KEY_EXCH_A)
                {
                type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
@@ -971,7 +978,7 @@ static int ssl3_send_server_key_exchange(SSL *s)
                                        SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
                                        goto f_err;
                                }
-                               CRYPTO_add(&rsa->references,1,CRYPTO_LOCK_RSA);
+                               RSA_up_ref(rsa);
                                cert->rsa_tmp=rsa;
                                }
                        if (rsa == NULL)
@@ -1155,10 +1162,12 @@ static int ssl3_send_server_key_exchange(SSL *s)
                }
 
        s->state = SSL3_ST_SW_KEY_EXCH_B;
+       EVP_MD_CTX_cleanup(&md_ctx);
        return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
 f_err:
        ssl3_send_alert(s,SSL3_AL_FATAL,al);
 err:
+       EVP_MD_CTX_cleanup(&md_ctx);
        return(-1);
        }
 
@@ -1461,7 +1470,8 @@ static int ssl3_get_client_key_exchange(SSL *s)
                EVP_CIPHER_CTX          ciph_ctx;
                EVP_CIPHER              *enc = NULL;
                unsigned char           iv[EVP_MAX_IV_LENGTH];
-               unsigned char           pms[SSL_MAX_MASTER_KEY_LENGTH];
+               unsigned char           pms[SSL_MAX_MASTER_KEY_LENGTH
+                                               + EVP_MAX_IV_LENGTH + 1];
                int                     padl, outl = sizeof(pms);
                krb5_timestamp          authtime = 0;
                krb5_ticket_times       ttimes;
@@ -1483,7 +1493,7 @@ static int ssl3_get_client_key_exchange(SSL *s)
                enc_pms.data = p;
                p+=enc_pms.length;
 
-               if (n != enc_ticket.length + authenticator.length +
+               if ((unsigned long)n != enc_ticket.length + authenticator.length +
                                                enc_pms.length + 6)
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
@@ -1533,18 +1543,36 @@ static int ssl3_get_client_key_exchange(SSL *s)
 #endif /* KSSL_DEBUG */
 
                enc = kssl_map_enc(kssl_ctx->enctype);
+                if (enc == NULL)
+                    goto err;
+
                memset(iv, 0, EVP_MAX_IV_LENGTH);       /* per RFC 1510 */
 
-               EVP_DecryptInit(&ciph_ctx,enc,kssl_ctx->key,iv);
-               EVP_DecryptUpdate(&ciph_ctx, pms,&outl,
-                                       enc_pms.data, enc_pms.length);
+               if (!EVP_DecryptInit(&ciph_ctx,enc,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))
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                               SSL_R_DECRYPTION_FAILED);
+                       goto err;
+                       }
                if (outl > SSL_MAX_MASTER_KEY_LENGTH)
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                SSL_R_DATA_LENGTH_TOO_LONG);
                        goto err;
                        }
-               EVP_DecryptFinal(&ciph_ctx,&(pms[outl]),&padl);
+               if (!EVP_DecryptFinal(&ciph_ctx,&(pms[outl]),&padl))
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                               SSL_R_DECRYPTION_FAILED);
+                       goto err;
+                       }
                outl += padl;
                if (outl > SSL_MAX_MASTER_KEY_LENGTH)
                        {
@@ -1558,6 +1586,17 @@ static int ssl3_get_client_key_exchange(SSL *s)
                         s->method->ssl3_enc->generate_master_secret(s,
                                 s->session->master_key, pms, outl);
 
+                if (kssl_ctx->client_princ)
+                        {
+                        int len = strlen(kssl_ctx->client_princ);
+                        if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) 
+                                {
+                                s->session->krb5_client_princ_len = len;
+                                memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
+                                }
+                        }
+
+
                 /*  Was doing kssl_ctx_free() here,
                **  but it caused problems for apache.
                 **  kssl_ctx = kssl_ctx_free(kssl_ctx);
@@ -1732,11 +1771,7 @@ static int ssl3_get_client_certificate(SSL *s)
                SSL3_ST_SR_CERT_A,
                SSL3_ST_SR_CERT_B,
                -1,
-#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
-               1024*30, /* 30k max cert list :-) */
-#else
-               1024*100, /* 100k max cert list :-) */
-#endif
+               s->max_cert_list,
                &ok);
 
        if (!ok) return((int)n);