Fix Bleichenbacher PKCS #1 1.5 countermeasure.
[oweals/openssl.git] / ssl / s2_srvr.c
index 974d6e6de742df31064595026bd89a1a56498023..2fa2f310a8eded974e762d1d00222a10b96df485 100644 (file)
@@ -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,7 +451,6 @@ 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
@@ -556,37 +556,21 @@ static int get_client_hello(SSL *s)
                        &s->session->ciphers);
                if (cs == NULL) goto mem_err;
 
-               cl=SSL_get_ciphers(s);
+               cl=ssl_get_ciphers_by_id(s);
 
-               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++)
+               for (z=0; z<sk_SSL_CIPHER_num(cs); z++)
                        {
-                       if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
+                       if (sk_SSL_CIPHER_find(cl,sk_SSL_CIPHER_value(cs,z)) < 0)
                                {
-                               sk_SSL_CIPHER_delete(prio,z);
+                               sk_SSL_CIPHER_delete(cs,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 or in the order of the server's preference
-                * if SSL_OP_CIPHER_SERVER_PREFERENCE was set.
+                * the ciphers.
                 */
                }
        p+=s->s2->tmp.cipher_spec_length;