X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=ssl%2Fssl_ciph.c;h=c31d6e0c782f7545364b11da4f8981a071d60240;hb=96562f2fb31a014fb5da44859900058b39b5bfaf;hp=0a56042931e07c0b69ec6d25916ae4436747123a;hpb=96afc1cfd53a0ffcca8544fa751eb9bf17749133;p=oweals%2Fopenssl.git diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 0a56042931..c31d6e0c78 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -143,6 +143,7 @@ #include #include #include +#include #include "ssl_locl.h" #define SSL_ENC_DES_IDX 0 @@ -172,9 +173,30 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL; #define SSL_MD_MD5_IDX 0 #define SSL_MD_SHA1_IDX 1 -#define SSL_MD_NUM_IDX 2 +#define SSL_MD_GOST94_IDX 2 +#define SSL_MD_GOST89MAC_IDX 3 +/*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 + }; +/* 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 + }; + +static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={ + 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 }; #define CIPHER_ADD 1 @@ -221,7 +243,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_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}, @@ -234,7 +256,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}, @@ -266,6 +290,8 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_MD5,0, 0,0,0,SSL_MD5, 0,0,0,0,0}, {0,SSL_TXT_SHA1,0, 0,0,0,SSL_SHA1, 0,0,0,0,0}, {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}, /* protocol version aliases */ {0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0}, @@ -282,7 +308,25 @@ 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 + */ +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; + } void ssl_load_ciphers(void) { @@ -315,11 +359,27 @@ void ssl_load_ciphers(void) 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]); 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]); + 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]); + } + ssl_digest_methods[SSL_MD_GOST89MAC_IDX]= + EVP_get_digestbyname(SN_id_Gost28147_89_MAC); + 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; + } + } #ifndef OPENSSL_NO_COMP static int sk_comp_cmp(const SSL_COMP * const *a, @@ -374,7 +434,7 @@ static void load_builtin_compressions(void) #endif int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, SSL_COMP **comp) + const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp) { int i; SSL_CIPHER *c; @@ -463,21 +523,48 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_SHA1: i=SSL_MD_SHA1_IDX; break; + case SSL_GOST94: + i = SSL_MD_GOST94_IDX; + break; + case SSL_GOST89MAC: + i = SSL_MD_GOST89MAC_IDX; + break; default: i= -1; break; } if ((i < 0) || (i > SSL_MD_NUM_IDX)) - *md=NULL; + { + *md=NULL; + if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef; + if (mac_secret_size!=NULL) *mac_secret_size = 0; + + } 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)) + if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef)) 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; + } + if (ssl_handshake_digest_flag[idx]==0) return 0; + *mask = ssl_handshake_digest_flag[idx]; + *md = ssl_digest_methods[idx]; + return 1; +} + #define ITEM_SEP(a) \ (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) @@ -549,9 +636,23 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un *mkey |= SSL_kPSK; *auth |= SSL_aPSK; #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; @@ -567,6 +668,9 @@ 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_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; + } static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, @@ -1317,7 +1421,7 @@ 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); return(cipherstack); }