X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_ciph.c;h=b0542d1b4a90ecb4b68e21406185ee5ad2399ad6;hp=e60a490a52cc41d0b300ec508c021783c099ab30;hb=0445ab3ae03d94ccb48eb9b1c22a11a296e3b5c3;hpb=babb379849ffb4112792f266f92e9ebb2bd35332 diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index e60a490a52..b0542d1b4a 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 @@ -175,28 +179,29 @@ 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_SHA256_IDX 4 /*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 }; /* 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 }; static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={ - 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_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256 }; #define CIPHER_ADD 1 @@ -243,6 +248,7 @@ 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 */ @@ -269,6 +275,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 */ @@ -292,6 +299,7 @@ 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}, /* protocol version aliases */ {0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0}, @@ -314,20 +322,38 @@ static const SSL_CIPHER cipher_aliases[]={ /* 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; - ENGINE *tmpeng = NULL; int pkey_id=0; - ameth = EVP_PKEY_asn1_find_str(&tmpeng,pkey_name,-1); + ameth = EVP_PKEY_asn1_find_str(NULL,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; } +#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) { ssl_cipher_methods[SSL_ENC_DES_IDX]= @@ -361,16 +387,19 @@ void ssl_load_ciphers(void) 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); @@ -379,6 +408,10 @@ void ssl_load_ciphers(void) ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32; } + 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]); } #ifndef OPENSSL_NO_COMP @@ -523,6 +556,9 @@ 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_GOST94: i = SSL_MD_GOST94_IDX; break; @@ -547,8 +583,29 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i]; } - if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef)) + 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 (s->ssl_version >= TLS1_VERSION && + 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 && + 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 && + c->algorithm_mac == SSL_SHA1 && + (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) + *enc = evp, *md = NULL; return(1); + } else return(0); } @@ -559,9 +616,11 @@ int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) { return 0; } - if (ssl_handshake_digest_flag[idx]==0) return 0; *mask = ssl_handshake_digest_flag[idx]; - *md = ssl_digest_methods[idx]; + if (*mask) + *md = ssl_digest_methods[idx]; + else + *md = NULL; return 1; } @@ -635,6 +694,9 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un #ifdef OPENSSL_NO_PSK *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 */ @@ -668,6 +730,7 @@ 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_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; @@ -698,6 +761,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) && @@ -1002,7 +1068,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, 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; @@ -1039,7 +1105,6 @@ static int ssl_cipher_process_rulestr(const char *rule_str, alg_ssl = 0; algo_strength = 0; - start=l; for (;;) { ch = *l; @@ -1353,8 +1418,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 @@ -1374,7 +1439,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 */ @@ -1398,7 +1463,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 @@ -1422,15 +1491,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, *cipher_list_by_id = tmp_cipher_list; (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 @@ -1443,7 +1513,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); @@ -1487,6 +1556,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"; } @@ -1571,6 +1643,9 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) case SSL_SHA1: mac="SHA1"; break; + case SSL_SHA256: + mac="SHA256"; + break; default: mac="unknown"; break; @@ -1628,6 +1703,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; @@ -1690,7 +1770,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();