X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_ciph.c;h=a5c417a9ed55ac713ffec5144e7f23087095d6e8;hp=d2e648bf3071ff88403d45781fb63bc76f9bc527;hb=44314cf64d1e51c7493799e77b14ae4e94a4c8cf;hpb=b948e2c59e3a6bdbfdcc304793da4635db7ca339 diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index d2e648bf30..a5c417a9ed 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -142,8 +142,12 @@ #include #include +#ifndef OPENSSL_NO_COMP #include +#endif +#ifndef OPENSSL_NO_ENGINE #include +#endif #include "ssl_locl.h" #define SSL_ENC_DES_IDX 0 @@ -158,11 +162,13 @@ #define SSL_ENC_CAMELLIA256_IDX 9 #define SSL_ENC_GOST89_IDX 10 #define SSL_ENC_SEED_IDX 11 -#define SSL_ENC_NUM_IDX 12 +#define SSL_ENC_AES128GCM_IDX 12 +#define SSL_ENC_AES256GCM_IDX 13 +#define SSL_ENC_NUM_IDX 14 static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; #define SSL_COMP_NULL_IDX 0 @@ -175,20 +181,32 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL; #define SSL_MD_SHA1_IDX 1 #define SSL_MD_GOST94_IDX 2 #define SSL_MD_GOST89MAC_IDX 3 -#define SSL_MD_NUM_IDX 4 +#define SSL_MD_SHA256_IDX 4 +#define SSL_MD_SHA384_IDX 5 +/*Constant SSL_MAX_DIGEST equal to size of digests array should be + * defined in the + * ssl_locl.h */ +#define SSL_MD_NUM_IDX SSL_MAX_DIGEST static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ - NULL,NULL,NULL,NULL + NULL,NULL,NULL,NULL,NULL,NULL }; /* PKEY_TYPE for GOST89MAC is known in advance, but, because * implementation is engine-provided, we'll fill it only if * corresponding EVP_PKEY_METHOD is found */ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX]={ - EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef + EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef, + EVP_PKEY_HMAC,EVP_PKEY_HMAC }; static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={ - 0,0,0,0 + 0,0,0,0,0,0 + }; + +static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={ + SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA, + SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256, + SSL_HANDSHAKE_MAC_SHA384 }; #define CIPHER_ADD 1 @@ -199,7 +217,7 @@ static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={ typedef struct cipher_order_st { - SSL_CIPHER *cipher; + const SSL_CIPHER *cipher; int active; int dead; struct cipher_order_st *next,*prev; @@ -220,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}, @@ -235,7 +253,8 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0}, {0,SSL_TXT_kPSK,0, SSL_kPSK, 0,0,0,0,0,0,0,0}, - + {0,SSL_TXT_kSRP,0, SSL_kSRP, 0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kGOST,0, SSL_kGOST,0,0,0,0,0,0,0,0}, /* server authentication aliases */ {0,SSL_TXT_aRSA,0, 0,SSL_aRSA, 0,0,0,0,0,0,0}, @@ -248,7 +267,9 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_aECDSA,0, 0,SSL_aECDSA,0,0,0,0,0,0,0}, {0,SSL_TXT_ECDSA,0, 0,SSL_aECDSA, 0,0,0,0,0,0,0}, {0,SSL_TXT_aPSK,0, 0,SSL_aPSK, 0,0,0,0,0,0,0}, - + {0,SSL_TXT_aGOST94,0,0,SSL_aGOST94,0,0,0,0,0,0,0}, + {0,SSL_TXT_aGOST01,0,0,SSL_aGOST01,0,0,0,0,0,0,0}, + {0,SSL_TXT_aGOST,0,0,SSL_aGOST94|SSL_aGOST01,0,0,0,0,0,0,0}, /* aliases combining key exchange and server authentication */ {0,SSL_TXT_EDH,0, SSL_kEDH,~SSL_aNULL,0,0,0,0,0,0,0}, @@ -259,6 +280,7 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_ADH,0, SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0}, {0,SSL_TXT_AECDH,0, SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0}, {0,SSL_TXT_PSK,0, SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0}, + {0,SSL_TXT_SRP,0, SSL_kSRP,0,0,0,0,0,0,0,0}, /* symmetric encryption aliases */ @@ -269,9 +291,10 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_IDEA,0, 0,0,SSL_IDEA, 0,0,0,0,0,0}, {0,SSL_TXT_SEED,0, 0,0,SSL_SEED, 0,0,0,0,0,0}, {0,SSL_TXT_eNULL,0, 0,0,SSL_eNULL, 0,0,0,0,0,0}, - {0,SSL_TXT_AES128,0, 0,0,SSL_AES128,0,0,0,0,0,0}, - {0,SSL_TXT_AES256,0, 0,0,SSL_AES256,0,0,0,0,0,0}, - {0,SSL_TXT_AES,0, 0,0,SSL_AES128|SSL_AES256,0,0,0,0,0,0}, + {0,SSL_TXT_AES128,0, 0,0,SSL_AES128|SSL_AES128GCM,0,0,0,0,0,0}, + {0,SSL_TXT_AES256,0, 0,0,SSL_AES256|SSL_AES256GCM,0,0,0,0,0,0}, + {0,SSL_TXT_AES,0, 0,0,SSL_AES,0,0,0,0,0,0}, + {0,SSL_TXT_AES_GCM,0, 0,0,SSL_AES128GCM|SSL_AES256GCM,0,0,0,0,0,0}, {0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0}, {0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0}, {0,SSL_TXT_CAMELLIA ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0}, @@ -282,11 +305,14 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_SHA,0, 0,0,0,SSL_SHA1, 0,0,0,0,0}, {0,SSL_TXT_GOST94,0, 0,0,0,SSL_GOST94, 0,0,0,0,0}, {0,SSL_TXT_GOST89MAC,0, 0,0,0,SSL_GOST89MAC, 0,0,0,0,0}, + {0,SSL_TXT_SHA256,0, 0,0,0,SSL_SHA256, 0,0,0,0,0}, + {0,SSL_TXT_SHA384,0, 0,0,0,SSL_SHA384, 0,0,0,0,0}, /* protocol version 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}, @@ -298,7 +324,43 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_LOW,0, 0,0,0,0,0,SSL_LOW, 0,0,0}, {0,SSL_TXT_MEDIUM,0, 0,0,0,0,0,SSL_MEDIUM,0,0,0}, {0,SSL_TXT_HIGH,0, 0,0,0,0,0,SSL_HIGH, 0,0,0}, + /* FIPS 140-2 approved ciphersuite */ + {0,SSL_TXT_FIPS,0, 0,0,~SSL_eNULL,0,0,SSL_FIPS, 0,0,0}, }; +/* Search for public key algorithm with given name and + * return its pkey_id if it is available. Otherwise return 0 + */ +#ifdef OPENSSL_NO_ENGINE + +static int get_optional_pkey_id(const char *pkey_name) + { + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id=0; + ameth = EVP_PKEY_asn1_find_str(NULL,pkey_name,-1); + if (ameth) + { + EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth); + } + return pkey_id; + } + +#else + +static int get_optional_pkey_id(const char *pkey_name) + { + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *tmpeng = NULL; + int pkey_id=0; + ameth = EVP_PKEY_asn1_find_str(&tmpeng,pkey_name,-1); + if (ameth) + { + EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth); + } + if (tmpeng) ENGINE_finish(tmpeng); + return pkey_id; + } + +#endif void ssl_load_ciphers(void) { @@ -329,37 +391,44 @@ void ssl_load_ciphers(void) ssl_cipher_methods[SSL_ENC_SEED_IDX]= EVP_get_cipherbyname(SN_seed_cbc); + ssl_cipher_methods[SSL_ENC_AES128GCM_IDX]= + EVP_get_cipherbyname(SN_aes_128_gcm); + ssl_cipher_methods[SSL_ENC_AES256GCM_IDX]= + EVP_get_cipherbyname(SN_aes_256_gcm); + ssl_digest_methods[SSL_MD_MD5_IDX]= EVP_get_digestbyname(SN_md5); ssl_mac_secret_size[SSL_MD_MD5_IDX]= EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0); ssl_digest_methods[SSL_MD_SHA1_IDX]= EVP_get_digestbyname(SN_sha1); ssl_mac_secret_size[SSL_MD_SHA1_IDX]= EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0); ssl_digest_methods[SSL_MD_GOST94_IDX]= EVP_get_digestbyname(SN_id_GostR3411_94); if (ssl_digest_methods[SSL_MD_GOST94_IDX]) { ssl_mac_secret_size[SSL_MD_GOST94_IDX]= EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0); } ssl_digest_methods[SSL_MD_GOST89MAC_IDX]= EVP_get_digestbyname(SN_id_Gost28147_89_MAC); - { - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *tmpeng = NULL; - int pkey_id; - ameth = EVP_PKEY_asn1_find_str(&tmpeng,"gost-mac",-1); - if (ameth) - { - EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth); - ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]= pkey_id; + ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac"); + if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) { ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32; - } - if (tmpeng) ENGINE_finish(tmpeng); - } - + } + + ssl_digest_methods[SSL_MD_SHA256_IDX]= + EVP_get_digestbyname(SN_sha256); + ssl_mac_secret_size[SSL_MD_SHA256_IDX]= + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]); + ssl_digest_methods[SSL_MD_SHA384_IDX]= + EVP_get_digestbyname(SN_sha384); + ssl_mac_secret_size[SSL_MD_SHA384_IDX]= + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]); } #ifndef OPENSSL_NO_COMP @@ -402,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(); } @@ -415,10 +485,10 @@ static void load_builtin_compressions(void) #endif int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp) + const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp, int use_etm) { int i; - SSL_CIPHER *c; + const SSL_CIPHER *c; c=s->cipher; if (c == NULL) return(0); @@ -481,6 +551,12 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_SEED: i=SSL_ENC_SEED_IDX; break; + case SSL_AES128GCM: + i=SSL_ENC_AES128GCM_IDX; + break; + case SSL_AES256GCM: + i=SSL_ENC_AES256GCM_IDX; + break; default: i= -1; break; @@ -504,6 +580,12 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_SHA1: i=SSL_MD_SHA1_IDX; break; + case SSL_SHA256: + i=SSL_MD_SHA256_IDX; + break; + case SSL_SHA384: + i=SSL_MD_SHA384_IDX; + break; case SSL_GOST94: i = SSL_MD_GOST94_IDX; break; @@ -519,21 +601,74 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, *md=NULL; if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef; if (mac_secret_size!=NULL) *mac_secret_size = 0; - + if (c->algorithm_mac == SSL_AEAD) + mac_pkey_type = NULL; } else { *md=ssl_digest_methods[i]; if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i]; if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i]; - } + } + + if ((*enc != NULL) && + (*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) && + (!mac_pkey_type||*mac_pkey_type != NID_undef)) + { + const EVP_CIPHER *evp; - if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef)) + if (use_etm) + return 1; + + 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 (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 (c->algorithm_enc == SSL_AES256 && + c->algorithm_mac == SSL_SHA1 && + (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES128 && + c->algorithm_mac == SSL_SHA256 && + (evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES256 && + c->algorithm_mac == SSL_SHA256 && + (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256"))) + *enc = evp, *md = NULL; return(1); + } else return(0); } +int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) +{ + if (idx <0||idx>=SSL_MD_NUM_IDX) + { + return 0; + } + *mask = ssl_handshake_digest_flag[idx]; + if (*mask) + *md = ssl_digest_methods[idx]; + else + *md = NULL; + return 1; +} + #define ITEM_SEP(a) \ (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) @@ -584,8 +719,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; @@ -605,9 +738,26 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un *mkey |= SSL_kPSK; *auth |= SSL_aPSK; #endif +#ifdef OPENSSL_NO_SRP + *mkey |= SSL_kSRP; +#endif + /* Check for presence of GOST 34.10 algorithms, and if they + * do not present, disable appropriate auth and key exchange */ + if (!get_optional_pkey_id("gost94")) { + *auth |= SSL_aGOST94; + } + if (!get_optional_pkey_id("gost2001")) { + *auth |= SSL_aGOST01; + } + /* Disable GOST key exchange if no GOST signature algs are available * */ + if ((*auth & (SSL_aGOST94|SSL_aGOST01)) == (SSL_aGOST94|SSL_aGOST01)) { + *mkey |= SSL_kGOST; + } #ifdef SSL_FORBID_ENULL *enc |= SSL_eNULL; #endif + + *enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0; *enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0; @@ -616,6 +766,8 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128:0; *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256:0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == NULL) ? SSL_AES128GCM:0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == NULL) ? SSL_AES256GCM:0; *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128:0; *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256:0; *enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT:0; @@ -623,6 +775,8 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; + *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256:0; + *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384:0; *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0; *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0; @@ -637,7 +791,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { int i, co_list_num; - SSL_CIPHER *c; + const SSL_CIPHER *c; /* * We have num_of_ciphers descriptions compiled in, depending on the @@ -653,6 +807,9 @@ 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 */ if ((c != NULL) && c->valid && +#ifdef OPENSSL_FIPS + (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) && +#endif !(c->algorithm_mkey & disabled_mkey) && !(c->algorithm_auth & disabled_auth) && !(c->algorithm_enc & disabled_enc) && @@ -700,7 +857,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, } } -static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list, +static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, int num_of_group_aliases, unsigned long disabled_mkey, unsigned long disabled_auth, unsigned long disabled_enc, unsigned long disabled_mac, @@ -708,7 +865,7 @@ static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list, CIPHER_ORDER *head) { CIPHER_ORDER *ciph_curr; - SSL_CIPHER **ca_curr; + const SSL_CIPHER **ca_curr; int i; unsigned long mask_mkey = ~disabled_mkey; unsigned long mask_auth = ~disabled_auth; @@ -778,7 +935,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { CIPHER_ORDER *head, *tail, *curr, *curr2, *last; - SSL_CIPHER *cp; + const SSL_CIPHER *cp; int reverse = 0; #ifdef CIPHER_DEBUG @@ -826,7 +983,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)) @@ -954,10 +1114,10 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, static int ssl_cipher_process_rulestr(const char *rule_str, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p, - SSL_CIPHER **ca_list) + const SSL_CIPHER **ca_list) { unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength; - const char *l, *start, *buf; + const char *l, *buf; int j, multi, found, rule, retval, ok, buflen; unsigned long cipher_id = 0; char ch; @@ -994,7 +1154,6 @@ static int ssl_cipher_process_rulestr(const char *rule_str, alg_ssl = 0; algo_strength = 0; - start=l; for (;;) { ch = *l; @@ -1004,9 +1163,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); @@ -1202,24 +1361,89 @@ static int ssl_cipher_process_rulestr(const char *rule_str, return(retval); } +#ifndef OPENSSL_NO_EC +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: if TLS 1.2 ciphers allowed we can use Suite B */ + + if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) + { + if (meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) + SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, + SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); + else + SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, + SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); + return 0; + } + + 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; + } + /* Set auto ECDH parameter determination */ + c->ecdh_tmp_auto = 1; + return 1; + } +#endif + 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; STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list; const char *rule_p; CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; - SSL_CIPHER **ca_list = NULL; + const SSL_CIPHER **ca_list = NULL; /* * Return with error if nothing to do. */ if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL) return NULL; +#ifndef OPENSSL_NO_EC + if (!check_suiteb_cipher_list(ssl_method, c, &rule_str)) + return NULL; +#endif /* * To reduce the work to do we only want to process the compiled @@ -1300,8 +1524,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, */ num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; - ca_list = - (SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); + ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); if (ca_list == NULL) { OPENSSL_free(co_list); @@ -1309,8 +1532,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, return(NULL); /* Failure */ } ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, - disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl, - head); + disabled_mkey, disabled_auth, disabled_enc, + disabled_mac, disabled_ssl, head); /* * If the rule_string begins with DEFAULT, apply the default rule @@ -1330,7 +1553,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, if (ok && (strlen(rule_p) > 0)) ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list); - OPENSSL_free(ca_list); /* Not needed anymore */ + OPENSSL_free((void *)ca_list); /* Not needed anymore */ if (!ok) { /* Rule processing failure */ @@ -1354,7 +1577,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 @@ -1376,17 +1603,18 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, if (*cipher_list_by_id != NULL) sk_SSL_CIPHER_free(*cipher_list_by_id); *cipher_list_by_id = tmp_cipher_list; - sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp); + (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp); + sk_SSL_CIPHER_sort(*cipher_list_by_id); return(cipherstack); } -char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) +char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) { int is_export,pkl,kl; const char *ver,*exp_str; const char *kx,*au,*enc,*mac; - unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl,alg2,alg_s; + unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl,alg2; #ifdef KSSL_DEBUG static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n"; #else @@ -1399,7 +1627,6 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) alg_mac = cipher->algorithm_mac; alg_ssl = cipher->algorithm_ssl; - alg_s=cipher->algo_strength; alg2=cipher->algorithm2; is_export=SSL_C_IS_EXPORT(cipher); @@ -1411,6 +1638,8 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) ver="SSLv2"; else if (alg_ssl & SSL_SSLV3) ver="SSLv3"; + else if (alg_ssl & SSL_TLSV1_2) + ver="TLSv1.2"; else ver="unknown"; @@ -1443,6 +1672,9 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) case SSL_kPSK: kx="PSK"; break; + case SSL_kSRP: + kx="SRP"; + break; default: kx="unknown"; } @@ -1505,6 +1737,12 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) case SSL_AES256: enc="AES(256)"; break; + case SSL_AES128GCM: + enc="AESGCM(128)"; + break; + case SSL_AES256GCM: + enc="AESGCM(256)"; + break; case SSL_CAMELLIA128: enc="Camellia(128)"; break; @@ -1527,6 +1765,15 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) case SSL_SHA1: mac="SHA1"; break; + case SSL_SHA256: + mac="SHA256"; + break; + case SSL_SHA384: + mac="SHA384"; + break; + case SSL_AEAD: + mac="AEAD"; + break; default: mac="unknown"; break; @@ -1584,6 +1831,11 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) return(ret); } +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c) + { + return c->id; + } + SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) { SSL_COMP *ctmp; @@ -1646,7 +1898,7 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) comp->method=cm; load_builtin_compressions(); if (ssl_comp_methods - && !sk_SSL_COMP_find(ssl_comp_methods,comp)) + && sk_SSL_COMP_find(ssl_comp_methods,comp) >= 0) { OPENSSL_free(comp); MemCheck_on(); @@ -1674,5 +1926,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); + }