'make update'
[openssl.git] / ssl / s2_srvr.c
index 4eb453b5f689ae38a307e0edf167b53bc2035506..cc9f59142756609f7c2faab9eb03dd7cadbea628 100644 (file)
@@ -57,7 +57,7 @@
  */
 
 #include "ssl_locl.h"
-#ifndef NO_SSL2
+#ifndef OPENSSL_NO_SSL2
 #include <stdio.h>
 #include <openssl/bio.h>
 #include <openssl/rand.h>
@@ -405,12 +405,13 @@ static int get_client_master_key(SSL *s)
        /* bad decrypt */
 #if 1
        /* If a bad decrypt, continue with protocol but with a
-        * dud master secret */
+        * random master secret (Bleichenbacher attack) */
        if ((i < 0) ||
                ((!is_export && (i != EVP_CIPHER_key_length(c)))
                || (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
                        EVP_CIPHER_key_length(c))))))
                {
+               ERR_clear_error();
                if (is_export)
                        i=ek;
                else
@@ -450,6 +451,7 @@ static int get_client_hello(SSL *s)
        unsigned char *p;
        STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */
        STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */
+       STACK_OF(SSL_CIPHER) *prio, *allow;
        int z;
 
        /* This is a bit of a hack to check for the correct packet
@@ -555,21 +557,37 @@ static int get_client_hello(SSL *s)
                        &s->session->ciphers);
                if (cs == NULL) goto mem_err;
 
-               cl=ssl_get_ciphers_by_id(s);
+               cl=SSL_get_ciphers(s);
 
-               for (z=0; z<sk_SSL_CIPHER_num(cs); z++)
+               if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
+                   {
+                   prio=sk_SSL_CIPHER_dup(cl);
+                   if (prio == NULL) goto mem_err;
+                   allow = cs;
+                   }
+               else
+                   {
+                   prio = cs;
+                   allow = cl;
+                   }
+               for (z=0; z<sk_SSL_CIPHER_num(prio); z++)
                        {
-                       if (sk_SSL_CIPHER_find(cl,sk_SSL_CIPHER_value(cs,z)) < 0)
+                       if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
                                {
-                               sk_SSL_CIPHER_delete(cs,z);
+                               sk_SSL_CIPHER_delete(prio,z);
                                z--;
                                }
                        }
-
+               if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
+                   {
+                   sk_SSL_CIPHER_free(s->session->ciphers);
+                   s->session->ciphers = prio;
+                   }
                /* s->session->ciphers should now have a list of
                 * ciphers that are on both the client and server.
                 * This list is ordered by the order the client sent
-                * the ciphers.
+                * the ciphers or in the order of the server's preference
+                * if SSL_OP_CIPHER_SERVER_PREFERENCE was set.
                 */
                }
        p+=s->s2->tmp.cipher_spec_length;
@@ -898,7 +916,7 @@ static int request_certificate(SSL *s)
                EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
 
                i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
-               buf2=(unsigned char *)Malloc((unsigned int)i);
+               buf2=OPENSSL_malloc((unsigned int)i);
                if (buf2 == NULL)
                        {
                        SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
@@ -907,7 +925,7 @@ static int request_certificate(SSL *s)
                p2=buf2;
                i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
                EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
-               Free(buf2);
+               OPENSSL_free(buf2);
 
                pkey=X509_get_pubkey(x509);
                if (pkey == NULL) goto end;
@@ -966,7 +984,7 @@ static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
                SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB);
        return(i);
        }
-#else /* !NO_SSL2 */
+#else /* !OPENSSL_NO_SSL2 */
 
 # if PEDANTIC
 static void *dummy=&dummy;