This commit was manufactured by cvs2svn to create branch
[oweals/openssl.git] / ssl / ssl_ciph.c
index da231de213e4cfa1d9ef2af1e72ff93fd7f37bbd..b68ed81e5227626bffe6297c30bb51903571512e 100644 (file)
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * ECC cipher suite support in OpenSSL originally developed by 
- * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
- */
+
 #include <stdio.h>
 #include <openssl/objects.h>
 #include <openssl/comp.h>
+#include <openssl/fips.h>
 #include "ssl_locl.h"
 
 #define SSL_ENC_DES_IDX                0
@@ -80,10 +77,6 @@ static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
        NULL,NULL,NULL,NULL,NULL,NULL,
        };
 
-#define SSL_COMP_NULL_IDX      0
-#define SSL_COMP_ZLIB_IDX      1
-#define SSL_COMP_NUM_IDX       2
-
 static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
 
 #define SSL_MD_MD5_IDX 0
@@ -109,20 +102,18 @@ typedef struct cipher_order_st
 
 static const SSL_CIPHER cipher_aliases[]={
        /* Don't include eNULL unless specifically enabled. */
-       /* Don't include ECC in ALL because these ciphers are not yet official. */
-       {0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL & ~SSL_kECDH & ~SSL_kECDHE, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */
-       /* TODO: COMPLEMENT OF ALL and COMPLEMENT OF DEFAULT do not have ECC cipher suites handled properly. */
-       {0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},  /* COMPLEMENT OF ALL */
+       {0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */
+        {0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},  /* COMPLEMENT OF ALL */
        {0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0},
-       {0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0},  /* VRS Kerberos5 */
+        {0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0},  /* VRS Kerberos5 */
        {0,SSL_TXT_kRSA,0,SSL_kRSA,  0,0,0,0,SSL_MKEY_MASK,0},
        {0,SSL_TXT_kDHr,0,SSL_kDHr,  0,0,0,0,SSL_MKEY_MASK,0},
        {0,SSL_TXT_kDHd,0,SSL_kDHd,  0,0,0,0,SSL_MKEY_MASK,0},
        {0,SSL_TXT_kEDH,0,SSL_kEDH,  0,0,0,0,SSL_MKEY_MASK,0},
        {0,SSL_TXT_kFZA,0,SSL_kFZA,  0,0,0,0,SSL_MKEY_MASK,0},
        {0,SSL_TXT_DH,  0,SSL_DH,    0,0,0,0,SSL_MKEY_MASK,0},
-       {0,SSL_TXT_ECC, 0,(SSL_kECDH|SSL_kECDHE), 0,0,0,0,SSL_MKEY_MASK,0},
        {0,SSL_TXT_EDH, 0,SSL_EDH,   0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0},
+
        {0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0},  /* VRS Kerberos5 */
        {0,SSL_TXT_aRSA,0,SSL_aRSA,  0,0,0,0,SSL_AUTH_MASK,0},
        {0,SSL_TXT_aDSS,0,SSL_aDSS,  0,0,0,0,SSL_AUTH_MASK,0},
@@ -163,6 +154,7 @@ static const SSL_CIPHER cipher_aliases[]={
        {0,SSL_TXT_LOW,   0, 0,   SSL_LOW, 0,0,0,0,SSL_STRONG_MASK},
        {0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK},
        {0,SSL_TXT_HIGH,  0, 0,  SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK},
+       {0,SSL_TXT_FIPS,  0, 0,  SSL_FIPS, 0,0,0,0,SSL_FIPS|SSL_STRONG_NONE},
        };
 
 static int init_ciphers=1;
@@ -195,47 +187,7 @@ static void load_ciphers(void)
        init_ciphers=0;
        }
 
-static int sk_comp_cmp(const SSL_COMP * const *a,
-                       const SSL_COMP * const *b)
-       {
-       return((*a)->id-(*b)->id);
-       }
-
-static void load_builtin_compressions(void)
-       {
-       if (ssl_comp_methods != NULL)
-               return;
-
-       CRYPTO_w_lock(CRYPTO_LOCK_SSL);
-       if (ssl_comp_methods == NULL)
-               {
-               SSL_COMP *comp = NULL;
-
-               MemCheck_off();
-               ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp);
-               if (ssl_comp_methods != NULL)
-                       {
-                       comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
-                       if (comp != NULL)
-                               {
-                               comp->method=COMP_zlib();
-                               if (comp->method
-                                       && comp->method->type == NID_undef)
-                                       OPENSSL_free(comp);
-                               else
-                                       {
-                                       comp->id=SSL_COMP_ZLIB_IDX;
-                                       comp->name=comp->method->name;
-                                       sk_SSL_COMP_push(ssl_comp_methods,comp);
-                                       }
-                               }
-                       }
-               MemCheck_on();
-               }
-       CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
-       }
-
-int ssl_cipher_get_evp(SSL_SESSION *s, const EVP_CIPHER **enc,
+int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
             const EVP_MD **md, SSL_COMP **comp)
        {
        int i;
@@ -247,12 +199,17 @@ int ssl_cipher_get_evp(SSL_SESSION *s, const EVP_CIPHER **enc,
                {
                SSL_COMP ctmp;
 
-               load_builtin_compressions();
-
-               *comp=NULL;
-               ctmp.id=s->compress_meth;
-               if (ssl_comp_methods != NULL)
+               if (s->compress_meth == 0)
+                       *comp=NULL;
+               else if (ssl_comp_methods == NULL)
+                       {
+                       /* bad */
+                       *comp=NULL;
+                       }
+               else
                        {
+
+                       ctmp.id=s->compress_meth;
                        i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp);
                        if (i >= 0)
                                *comp=sk_SSL_COMP_value(ssl_comp_methods,i);
@@ -365,9 +322,7 @@ static unsigned long ssl_cipher_get_disabled(void)
 #ifdef OPENSSL_NO_KRB5
        mask |= SSL_kKRB5|SSL_aKRB5;
 #endif
-#ifdef OPENSSL_NO_ECDH
-       mask |= SSL_kECDH|SSL_kECDHE;
-#endif
+
 #ifdef SSL_FORBID_ENULL
        mask |= SSL_eNULL;
 #endif
@@ -406,7 +361,12 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
                {
                c = ssl_method->get_cipher(i);
                /* drop those that use any of that is not available */
+#ifdef OPENSSL_FIPS
+               if ((c != NULL) && c->valid && !(c->algorithms & mask)
+                       && (!FIPS_mode() || (c->algo_strength & SSL_FIPS)))
+#else
                if ((c != NULL) && c->valid && !(c->algorithms & mask))
+#endif
                        {
                        co_list[co_list_num].cipher = c;
                        co_list[co_list_num].next = NULL;
@@ -901,7 +861,11 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
         */
        for (curr = head; curr != NULL; curr = curr->next)
                {
+#ifdef OPENSSL_FIPS
+               if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS))
+#else
                if (curr->active)
+#endif
                        {
                        sk_SSL_CIPHER_push(cipherstack, curr->cipher);
 #ifdef CIPHER_DEBUG
@@ -976,7 +940,7 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len)
        pkl=SSL_C_EXPORT_PKEYLENGTH(cipher);
        kl=SSL_C_EXPORT_KEYLENGTH(cipher);
        exp_str=is_export?" export":"";
-       
+
        if (alg & SSL_SSLV2)
                ver="SSLv2";
        else if (alg & SSL_SSLV3)
@@ -1005,10 +969,6 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len)
        case SSL_kEDH:
                kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH";
                break;
-       case SSL_kECDH:
-       case SSL_kECDHE:
-               kx=is_export?"ECDH(<=163)":"ECDH";
-               break;
        default:
                kx="unknown";
                }
@@ -1032,9 +992,6 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len)
        case SSL_aNULL:
                au="None";
                break;
-       case SSL_aECDSA:
-               au="ECDSA";
-               break;
        default:
                au="unknown";
                break;
@@ -1108,7 +1065,7 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len)
        return(buf);
        }
 
-char *SSL_CIPHER_get_version(SSL_CIPHER *c)
+char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
        {
        int i;
 
@@ -1123,7 +1080,7 @@ char *SSL_CIPHER_get_version(SSL_CIPHER *c)
        }
 
 /* return the actual cipher being used */
-const char *SSL_CIPHER_get_name(SSL_CIPHER *c)
+const char *SSL_CIPHER_get_name(const SSL_CIPHER *c)
        {
        if (c != NULL)
                return(c->name);
@@ -1131,7 +1088,7 @@ const char *SSL_CIPHER_get_name(SSL_CIPHER *c)
        }
 
 /* number of bits for symmetric cipher */
-int SSL_CIPHER_get_bits(SSL_CIPHER *c, int *alg_bits)
+int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
        {
        int ret=0;
 
@@ -1159,48 +1116,35 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
        return(NULL);
        }
 
+static int sk_comp_cmp(const SSL_COMP * const *a,
+                       const SSL_COMP * const *b)
+       {
+       return((*a)->id-(*b)->id);
+       }
+
 STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
        {
-       load_builtin_compressions();
        return(ssl_comp_methods);
        }
 
 int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
        {
        SSL_COMP *comp;
+       STACK_OF(SSL_COMP) *sk;
 
         if (cm == NULL || cm->type == NID_undef)
                 return 1;
 
-       /* According to draft-ietf-tls-compression-04.txt, the
-          compression number ranges should be the following:
-
-          0 to 63:    methods defined by the IETF
-          64 to 192:  external party methods assigned by IANA
-          193 to 255: reserved for private use */
-       if (id < 193 || id > 255)
-               {
-               SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE);
-               return 0;
-               }
-
        MemCheck_off();
        comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
        comp->id=id;
        comp->method=cm;
-       load_builtin_compressions();
-       if (ssl_comp_methods
-               && !sk_SSL_COMP_find(ssl_comp_methods,comp))
-               {
-               OPENSSL_free(comp);
-               MemCheck_on();
-               SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_DUPLICATE_COMPRESSION_ID);
-               return(1);
-               }
-       else if ((ssl_comp_methods == NULL)
-               || !sk_SSL_COMP_push(ssl_comp_methods,comp))
+       if (ssl_comp_methods == NULL)
+               sk=ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp);
+       else
+               sk=ssl_comp_methods;
+       if ((sk == NULL) || !sk_SSL_COMP_push(sk,comp))
                {
-               OPENSSL_free(comp);
                MemCheck_on();
                SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE);
                return(1);
@@ -1211,11 +1155,3 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
                return(0);
                }
        }
-
-const char *SSL_COMP_get_name(const COMP_METHOD *comp)
-       {
-       if (comp)
-               return comp->name;
-       return NULL;
-       }
-