diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2007-08-31 12:42:53 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2007-08-31 12:42:53 +0000 |
commit | 81025661a94034fef1386cb5d5137ba4ddb120f0 (patch) | |
tree | cde73075708fe40deb5c7dfcd0c03861794599cf /ssl/ssl_ciph.c | |
parent | 4ece7eb6f4d396008d8b4ee6beb6dca409d84882 (diff) |
Update ssl code to support digests other than MD5+SHA1 in handshake.
Submitted by: Victor B. Wagner <vitus@cryptocom.ru>
Diffstat (limited to 'ssl/ssl_ciph.c')
-rw-r--r-- | ssl/ssl_ciph.c | 67 |
1 files changed, 54 insertions, 13 deletions
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index d2e648bf30..e5730251ae 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -175,7 +175,10 @@ 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 +/*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 }; @@ -191,6 +194,11 @@ 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 #define CIPHER_KILL 2 #define CIPHER_DEL 3 @@ -299,6 +307,22 @@ static const SSL_CIPHER cipher_aliases[]={ {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}, }; +/* 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) { @@ -346,19 +370,10 @@ void ssl_load_ciphers(void) } 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); - } + } } #ifndef OPENSSL_NO_COMP @@ -534,6 +549,18 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, 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) == ',')) @@ -605,9 +632,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; |