On Tue, Jan 30, 2007 at 10:24:21AM -0500, Victor Duchovni wrote:

> Is this the right forum? I want to make that Postfix 2.4 is still correct
> when OpenSSL 0.9.9 is released, and I am reluctant to augment the AES-256
> work-around with a Camellia-256 work-around, ... I am looking for a more
> systematic solution, ideally in the OpenSSL library.
> 
> Can ssl_cipher_get_disabled() be enhanced to distinguish between AES-128
> and AES-256 or Camellia-128 and Camellia-256?

Very simple patch below, when filtering actual ciphers test 256 bit
ciphers against a 256bit variant of the disabled cipher mask, and all
other ciphers against the regular mask. When filtering cipher aliases,
only disable aliases that fail both masks. Fullly binary compatible, no
externally visible changes, no consumption of algorithm bitmask slots, ...

I am hoping this can be adopted for 0.9.9 and any future 0.9.8e or 0.9.7m
release. I am also hoping for some feedback. :-)

Tested by explicitly setting:

        ssl_cipher_methods[SSL_ENC_AES128_IDX]=
#ifndef TEST_MASK256
          EVP_get_cipherbyname(SN_aes_128_cbc);
#else
          0;
#fi
        ssl_cipher_methods[SSL_ENC_AES256_IDX]=
          EVP_get_cipherbyname(SN_aes_256_cbc);
        ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX]=
          EVP_get_cipherbyname(SN_camellia_128_cbc);
        ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX]=
#ifndef TEST_MASK256
          EVP_get_cipherbyname(SN_camellia_256_cbc);
#else
          0;
#fi

Compiling with "-DTEST_MASK256" yields the expected results, with all
cipherlists the normally include AES always missing the AES-128 ciphers
only, and all cipherlists that normally include CAMELLIA always missing
the CAMELLIA-256 ciphers only.

*** openssl-SNAP-20070125/ssl/ssl_ciph.c        Wed Jan  3 15:01:16 2007
--- openssl-SNAP-20070125-new/ssl/ssl_ciph.c    Wed Jan 31 01:05:06 2007
***************
*** 478,486 ****
        *tail=curr;
        }
  
! static unsigned long ssl_cipher_get_disabled(void)
        {
        unsigned long mask = 0;
  
  #ifdef OPENSSL_NO_RSA
        mask |= SSL_aRSA|SSL_kRSA;
--- 478,488 ----
        *tail=curr;
        }
  
! static unsigned long ssl_cipher_get_disabled(long *m256Ptr)
        {
        unsigned long mask = 0;
+       unsigned long m256;
+ 
  
  #ifdef OPENSSL_NO_RSA
        mask |= SSL_aRSA|SSL_kRSA;
***************
*** 512,529 ****
        mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
        mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
        mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
-       mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0;
-       mask |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? 
SSL_CAMELLIA:0;
  
        mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
        mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
  
        return(mask);
        }
  
  static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
!               int num_of_ciphers, unsigned long mask, CIPHER_ORDER *co_list,
!               CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
        {
        int i, co_list_num;
        SSL_CIPHER *c;
--- 514,541 ----
        mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
        mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
        mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
  
        mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
        mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
  
+       /*
+        * So far so good, but for some ciphers mask and m256 differ
+        */
+       m256 = mask;
+ 
+       mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0;
+       m256 |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES:0;
+       mask |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? 
SSL_CAMELLIA:0;
+       m256 |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? 
SSL_CAMELLIA:0;
+ 
+       *m256Ptr = m256;
        return(mask);
        }
  
  static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
!               int num_of_ciphers, unsigned long mask, unsigned long m256,
!               CIPHER_ORDER *co_list, CIPHER_ORDER **head_p,
!               CIPHER_ORDER **tail_p)
        {
        int i, co_list_num;
        SSL_CIPHER *c;
***************
*** 541,547 ****
                {
                c = ssl_method->get_cipher(i);
                /* drop those that use any of that is not available */
!               if ((c != NULL) && c->valid && !(c->algorithms & mask))
                        {
                        co_list[co_list_num].cipher = c;
                        co_list[co_list_num].next = NULL;
--- 553,560 ----
                {
                c = ssl_method->get_cipher(i);
                /* drop those that use any of that is not available */
!               if ((c != NULL) && c->valid
!                   && !(c->algorithms & ((c->alg_bits == 256) ? m256 : mask)))
                        {
                        co_list[co_list_num].cipher = c;
                        co_list[co_list_num].next = NULL;
***************
*** 982,987 ****
--- 995,1001 ----
        {
        int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
        unsigned long disabled_mask;
+       unsigned long disabled_m256;
        STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
        const char *rule_p;
        CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
***************
*** 997,1003 ****
         * To reduce the work to do we only want to process the compiled
         * in algorithms, so we first get the mask of disabled ciphers.
         */
!       disabled_mask = ssl_cipher_get_disabled();
  
        /*
         * Now we have to collect the available ciphers from the compiled
--- 1011,1017 ----
         * To reduce the work to do we only want to process the compiled
         * in algorithms, so we first get the mask of disabled ciphers.
         */
!       disabled_mask = ssl_cipher_get_disabled(&disabled_m256);
  
        /*
         * Now we have to collect the available ciphers from the compiled
***************
*** 1016,1022 ****
                }
  
        ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask,
!                                  co_list, &head, &tail);
  
        /*
         * We also need cipher aliases for selecting based on the rule_str.
--- 1030,1036 ----
                }
  
        ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask,
!                                  disabled_m256, co_list, &head, &tail);
  
        /*
         * We also need cipher aliases for selecting based on the rule_str.
***************
*** 1036,1043 ****
                SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
                return(NULL);   /* Failure */
                }
!       ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mask,
!                                  head);
  
        /*
         * If the rule_string begins with DEFAULT, apply the default rule
--- 1050,1057 ----
                SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
                return(NULL);   /* Failure */
                }
!       ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
!                                  (disabled_mask & disabled_m256), head);
  
        /*
         * If the rule_string begins with DEFAULT, apply the default rule

-- 
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to