reject zero length point format list or supported curves extensions
[openssl.git] / ssl / ssl_ciph.c
index c03f02974859aa696921c31843b108dcc36359e4..fbd0c212075c486b850606436b62ecdcda62df54 100644 (file)
@@ -238,9 +238,9 @@ static const SSL_CIPHER cipher_aliases[]={
         * e.g. kEDH combines DHE_DSS and DHE_RSA) */
        {0,SSL_TXT_kRSA,0,    SSL_kRSA,  0,0,0,0,0,0,0,0},
 
-       {0,SSL_TXT_kDHr,0,    SSL_kDHr,  0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
-       {0,SSL_TXT_kDHd,0,    SSL_kDHd,  0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
-       {0,SSL_TXT_kDH,0,     SSL_kDHr|SSL_kDHd,0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
+       {0,SSL_TXT_kDHr,0,    SSL_kDHr,  0,0,0,0,0,0,0,0},
+       {0,SSL_TXT_kDHd,0,    SSL_kDHd,  0,0,0,0,0,0,0,0},
+       {0,SSL_TXT_kDH,0,     SSL_kDHr|SSL_kDHd,0,0,0,0,0,0,0,0},
        {0,SSL_TXT_kEDH,0,    SSL_kEDH,  0,0,0,0,0,0,0,0},
        {0,SSL_TXT_DH,0,      SSL_kDHr|SSL_kDHd|SSL_kEDH,0,0,0,0,0,0,0,0},
 
@@ -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},
@@ -470,6 +471,7 @@ static void load_builtin_compressions(void)
                                                sk_SSL_COMP_push(ssl_comp_methods,comp);
                                                }
                                        }
+                                       sk_SSL_COMP_sort(ssl_comp_methods);
                                }
                        MemCheck_on();
                        }
@@ -615,18 +617,24 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
                {
                const EVP_CIPHER *evp;
 
-               if      (s->ssl_version >= TLS1_VERSION &&
-                        c->algorithm_enc == SSL_RC4 &&
+               if (s->ssl_version>>8 != TLS1_VERSION_MAJOR ||
+                   s->ssl_version < TLS1_VERSION)
+                       return 1;
+
+#ifdef OPENSSL_FIPS
+               if (FIPS_mode())
+                       return 1;
+#endif
+
+               if      (c->algorithm_enc == SSL_RC4 &&
                         c->algorithm_mac == SSL_MD5 &&
                         (evp=EVP_get_cipherbyname("RC4-HMAC-MD5")))
                        *enc = evp, *md = NULL;
-               else if (s->ssl_version >= TLS1_VERSION &&
-                        c->algorithm_enc == SSL_AES128 &&
+               else if (c->algorithm_enc == SSL_AES128 &&
                         c->algorithm_mac == SSL_SHA1 &&
                         (evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
                        *enc = evp, *md = NULL;
-               else if (s->ssl_version >= TLS1_VERSION &&
-                        c->algorithm_enc == SSL_AES256 &&
+               else if (c->algorithm_enc == SSL_AES256 &&
                         c->algorithm_mac == SSL_SHA1 &&
                         (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
                        *enc = evp, *md = NULL;
@@ -700,8 +708,6 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un
 #ifdef OPENSSL_NO_DSA
        *auth |= SSL_aDSS;
 #endif
-       *mkey |= SSL_kDHr|SSL_kDHd; /* no such ciphersuites supported! */
-       *auth |= SSL_aDH;
 #ifdef OPENSSL_NO_DH
        *mkey |= SSL_kDHr|SSL_kDHd|SSL_kEDH;
        *auth |= SSL_aDH;
@@ -966,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))
@@ -1143,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);
@@ -1342,10 +1351,49 @@ 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;
+       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, "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:
+               *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;
@@ -1360,6 +1408,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.
@@ -1841,5 +1893,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);
+       }