add Suite B 128 bit mode offering only combination 2
[openssl.git] / ssl / ssl_ciph.c
index 6db2aa945d0cfe8ad8cffdd54ca934766a58e644..084e8bbb1b204c5d9080b3c1e7b70fa5955fccfb 100644 (file)
@@ -312,6 +312,7 @@ static const SSL_CIPHER cipher_aliases[]={
        {0,SSL_TXT_SSLV2,0,   0,0,0,0,SSL_SSLV2, 0,0,0,0},
        {0,SSL_TXT_SSLV3,0,   0,0,0,0,SSL_SSLV3, 0,0,0,0},
        {0,SSL_TXT_TLSV1,0,   0,0,0,0,SSL_TLSV1, 0,0,0,0},
+       {0,SSL_TXT_TLSV1_2,0, 0,0,0,0,SSL_TLSV1_2, 0,0,0,0},
 
        /* export flag */
        {0,SSL_TXT_EXP,0,     0,0,0,0,0,SSL_EXPORT,0,0,0},
@@ -971,7 +972,10 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
 #ifdef CIPHER_DEBUG
                        printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
 #endif
-
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+                       if (cipher_id && cipher_id != cp->id)
+                               continue;
+#endif
                        if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
                                continue;
                        if (alg_auth && !(alg_auth & cp->algorithm_auth))
@@ -1148,9 +1152,9 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
                        while ( ((ch >= 'A') && (ch <= 'Z')) ||
                                ((ch >= '0') && (ch <= '9')) ||
                                ((ch >= 'a') && (ch <= 'z')) ||
-                                (ch == '-'))
+                                (ch == '-') || (ch == '.'))
 #else
-                       while ( isalnum(ch) || (ch == '-'))
+                       while ( isalnum(ch) || (ch == '-') || (ch == '.'))
 #endif
                                 {
                                 ch = *(++l);
@@ -1347,10 +1351,57 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
        return(retval);
        }
 
+static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,
+                                       const char **prule_str)
+       {
+       unsigned int suiteb_flags = 0, suiteb_comb2 = 0;
+       if (!strcmp(*prule_str, "SUITEB128"))
+               suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
+       else if (!strcmp(*prule_str, "SUITEB128ONLY"))
+               suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY;
+       else if (!strcmp(*prule_str, "SUITEB128C2"))
+               {
+               suiteb_comb2 = 1;
+               suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
+               }
+       else if (!strcmp(*prule_str, "SUITEB192"))
+               suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS;
+
+       if (suiteb_flags)
+               {
+               c->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS;
+               c->cert_flags |= suiteb_flags;
+               }
+       else
+               suiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS;
+
+       if (!suiteb_flags)
+               return 1;
+       /* Check version */
+
+       switch(suiteb_flags)
+               {
+       case SSL_CERT_FLAG_SUITEB_128_LOS:
+               if (suiteb_comb2)
+                       *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";
+               else
+                       *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384";
+               break;
+       case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
+               *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256";
+               break;
+       case SSL_CERT_FLAG_SUITEB_192_LOS:
+               *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";
+               break;
+               }
+       return 1;
+       }
+
+
 STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
                STACK_OF(SSL_CIPHER) **cipher_list,
                STACK_OF(SSL_CIPHER) **cipher_list_by_id,
-               const char *rule_str)
+               const char *rule_str, CERT *c)
        {
        int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
        unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl;
@@ -1365,6 +1416,10 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
        if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
                return NULL;
 
+       if (!check_suiteb_cipher_list(ssl_method, c, &rule_str))
+               return NULL;
+
+
        /*
         * To reduce the work to do we only want to process the compiled
         * in algorithms, so we first get the mask of disabled ciphers.
@@ -1846,5 +1901,60 @@ const char *SSL_COMP_get_name(const COMP_METHOD *comp)
                return comp->name;
        return NULL;
        }
-
 #endif
+/* For a cipher return the index corresponding to the certificate type */
+int ssl_cipher_get_cert_index(const SSL_CIPHER *c)
+       {
+       unsigned long alg_k, alg_a;
+
+       alg_k = c->algorithm_mkey;
+       alg_a = c->algorithm_auth;
+
+       if (alg_k & (SSL_kECDHr|SSL_kECDHe))
+               {
+               /* we don't need to look at SSL_kEECDH
+                * since no certificate is needed for
+                * anon ECDH and for authenticated
+                * EECDH, the check for the auth
+                * algorithm will set i correctly
+                * NOTE: For ECDH-RSA, we need an ECC
+                * not an RSA cert but for EECDH-RSA
+                * we need an RSA cert. Placing the
+                * checks for SSL_kECDH before RSA
+                * checks ensures the correct cert is chosen.
+                */
+               return SSL_PKEY_ECC;
+               }
+       else if (alg_a & SSL_aECDSA)
+               return SSL_PKEY_ECC;
+       else if (alg_k & SSL_kDHr)
+               return SSL_PKEY_DH_RSA;
+       else if (alg_k & SSL_kDHd)
+               return SSL_PKEY_DH_DSA;
+       else if (alg_a & SSL_aDSS)
+               return SSL_PKEY_DSA_SIGN;
+       else if (alg_a & SSL_aRSA)
+               return SSL_PKEY_RSA_ENC;
+       else if (alg_a & SSL_aKRB5)
+               /* VRS something else here? */
+               return -1;
+       else if (alg_a & SSL_aGOST94) 
+               return SSL_PKEY_GOST94;
+       else if (alg_a & SSL_aGOST01)
+               return SSL_PKEY_GOST01;
+       return -1;
+       }
+
+const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr)
+       {
+       const SSL_CIPHER *c;
+       c = ssl->method->get_cipher_by_char(ptr);
+       if (c == NULL || c->valid == 0)
+               return NULL;
+       return c;
+       }
+
+const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
+       {
+       return ssl->method->get_cipher_by_char(ptr);
+       }