From: Nikos Mavrogiannopoulos Date: Sat, 21 May 2011 10:29:37 +0000 (+0200) Subject: Added ability to specify curves as priority strings. X-Git-Tag: gnutls_2_99_2~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eef638480f8da560dd0e9cb1b3916bbda3d3bf3f;p=thirdparty%2Fgnutls.git Added ability to specify curves as priority strings. --- diff --git a/doc/cha-intro-tls.texi b/doc/cha-intro-tls.texi index 94cd31c5be..cc2b62c83a 100644 --- a/doc/cha-intro-tls.texi +++ b/doc/cha-intro-tls.texi @@ -505,8 +505,9 @@ priority. @item Key exchange: RSA, DHE-RSA, DHE-DSS, SRP, SRP-RSA, SRP-DSS, -PSK, DHE-PSK, ANON-DH, RSA-EXPORT. The -key exchange methods do not have a catch all. +PSK, DHE-PSK, ECDHE-RSA, ANON-ECDH, ANON-DH, RSA-EXPORT. The +Catch all name is KX-ALL which will add all the algorithms from NORMAL +priority. @item MAC: MD5, SHA1, SHA256, AEAD (used with @@ -525,6 +526,9 @@ SIGN-RSA-SHA256, SIGN-RSA-SHA384, SIGN-RSA-SHA512, SIGN-DSA-SHA1, SIGN-DSA-SHA224, SIGN-DSA-SHA256, SIGN-RSA-MD5. Catch all is SIGN-ALL. This is only valid for TLS 1.2 and later. +@item Elliptic curves: +CURVE-SECP224R1, CURVE-SECP256R1, CURVE-SECP384R1, CURVE-SECP521R1. Catch all is CURVE-ALL. + @end table diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index df9d1e61f1..44cc0a05d2 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -875,7 +875,13 @@ gnutls_mac_get_id (const char *name) { gnutls_mac_algorithm_t ret = GNUTLS_MAC_UNKNOWN; - GNUTLS_HASH_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id); + GNUTLS_HASH_LOOP ( + if (strcasecmp (p->name, name) == 0) + { + ret = p->id; + break; + } + ); return ret; } @@ -1094,7 +1100,13 @@ gnutls_cipher_get_id (const char *name) { gnutls_cipher_algorithm_t ret = GNUTLS_CIPHER_UNKNOWN; - GNUTLS_CIPHER_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id); + GNUTLS_CIPHER_LOOP ( + if (strcasecmp (p->name, name) == 0) + { + ret = p->id; + break; + } + ); return ret; } @@ -1200,7 +1212,13 @@ gnutls_kx_get_id (const char *name) { gnutls_cipher_algorithm_t ret = GNUTLS_KX_UNKNOWN; - GNUTLS_KX_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->algorithm); + GNUTLS_KX_LOOP ( + if (strcasecmp (p->name, name) == 0) + { + ret = p->algorithm; + break; + } + ); return ret; } @@ -1348,7 +1366,13 @@ gnutls_protocol_get_id (const char *name) { gnutls_protocol_t ret = GNUTLS_VERSION_UNKNOWN; - GNUTLS_VERSION_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id); + GNUTLS_VERSION_LOOP ( + if (strcasecmp (p->name, name) == 0) + { + ret = p->id; + break; + } + ); return ret; } @@ -2117,7 +2141,13 @@ gnutls_sign_get_id (const char *name) { gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN; - GNUTLS_SIGN_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id); + GNUTLS_SIGN_LOOP ( + if (strcasecmp (p->name, name) == 0) + { + ret = p->id; + break; + } + ); return ret; @@ -2279,6 +2309,30 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { #define GNUTLS_ECC_CURVE_LOOP(b) \ { const gnutls_ecc_curve_entry_st *p; \ for(p = ecc_curves; p->name != NULL; p++) { b ; } } +/*- + * _gnutls_ecc_curve_get_id: + * @name: is a MAC algorithm name + * + * The names are compared in a case insensitive way. + * + * Returns: return a #ecc_curve_t value corresponding to + * the specified cipher, or %GNUTLS_ECC_CURVE_INVALID on error. + -*/ +ecc_curve_t +_gnutls_ecc_curve_get_id (const char *name) +{ + ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID; + + GNUTLS_ECC_CURVE_LOOP ( + if (strcasecmp (p->name, name) == 0) + { + ret = p->id; + break; + } + ); + + return ret; +} /*- * _gnutls_ecc_curve_get_name: @@ -2550,14 +2604,16 @@ gnutls_sec_param_to_pk_bits (gnutls_pk_algorithm_t algo, { GNUTLS_SEC_PARAM_LOOP (if (p->sec_param == param) { - ret = p->dsa_bits; break;} + ret = p->dsa_bits; break; + } ); return ret; } GNUTLS_SEC_PARAM_LOOP (if (p->sec_param == param) { - ret = p->pk_bits; break;} + ret = p->pk_bits; break; + } ); return ret; @@ -2573,7 +2629,8 @@ _gnutls_pk_bits_to_subgroup_bits (unsigned int pk_bits) GNUTLS_SEC_PARAM_LOOP (if (p->pk_bits >= pk_bits) { - ret = p->subgroup_bits; break;} + ret = p->subgroup_bits; break; + } ); return ret; @@ -2596,7 +2653,8 @@ gnutls_sec_param_get_name (gnutls_sec_param_t param) GNUTLS_SEC_PARAM_LOOP (if (p->sec_param == param) { - ret = p->name; break;} + ret = p->name; break; + } ); return ret; @@ -2621,7 +2679,8 @@ gnutls_pk_bits_to_sec_param (gnutls_pk_algorithm_t algo, unsigned int bits) GNUTLS_SEC_PARAM_LOOP (if (p->pk_bits > bits) { - break;} + break; + } ret = p->sec_param;); return ret; diff --git a/lib/gnutls_algorithms.h b/lib/gnutls_algorithms.h index c8b692dbb5..4877076284 100644 --- a/lib/gnutls_algorithms.h +++ b/lib/gnutls_algorithms.h @@ -150,5 +150,6 @@ typedef struct gnutls_ecc_curve_entry_st gnutls_ecc_curve_entry_st; const char * _gnutls_ecc_curve_get_name (ecc_curve_t curve); const gnutls_ecc_curve_entry_st * _gnutls_ecc_curve_get_params (ecc_curve_t curve); int _gnutls_ecc_curve_get_size (ecc_curve_t curve); +ecc_curve_t _gnutls_ecc_curve_get_id (const char *name); #endif diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c index 501c1a2cd3..f54bd51e42 100644 --- a/lib/gnutls_priority.c +++ b/lib/gnutls_priority.c @@ -215,13 +215,26 @@ gnutls_certificate_type_set_priority (gnutls_session_t session, #endif } -static const int supported_ecc_default[] = { +static const int supported_ecc_normal[] = { + GNUTLS_ECC_CURVE_SECP224R1, GNUTLS_ECC_CURVE_SECP256R1, GNUTLS_ECC_CURVE_SECP384R1, GNUTLS_ECC_CURVE_SECP521R1, 0 }; +static const int supported_ecc_secure128[] = { + GNUTLS_ECC_CURVE_SECP256R1, + GNUTLS_ECC_CURVE_SECP384R1, + GNUTLS_ECC_CURVE_SECP521R1, + 0 +}; + +static const int supported_ecc_secure256[] = { + GNUTLS_ECC_CURVE_SECP521R1, + 0 +}; + static const int protocol_priority[] = { GNUTLS_TLS1_2, GNUTLS_TLS1_1, @@ -528,6 +541,8 @@ gnutls_priority_set (gnutls_session_t session, gnutls_priority_t priority) * * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1", * + * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+ECDHE-RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1:+CURVE-SECP256R1", + * * "NORMAL:%COMPAT" is the most compatible mode. * * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned, @@ -577,12 +592,11 @@ gnutls_priority_init (gnutls_priority_t * priority_cache, _set_priority (&(*priority_cache)->compression, comp_priority); _set_priority (&(*priority_cache)->cert_type, cert_type_priority); _set_priority (&(*priority_cache)->sign_algo, sign_priority_default); - _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_default); + _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_normal); i = 0; } else { - _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_default); i = 1; } @@ -596,6 +610,7 @@ gnutls_priority_init (gnutls_priority_t * priority_cache, _set_priority (&(*priority_cache)->mac, mac_priority_normal); _set_priority (&(*priority_cache)->sign_algo, sign_priority_default); + _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_normal); } else if (strcasecmp (broken_list[i], "NORMAL") == 0) { @@ -604,6 +619,7 @@ gnutls_priority_init (gnutls_priority_t * priority_cache, _set_priority (&(*priority_cache)->mac, mac_priority_normal); _set_priority (&(*priority_cache)->sign_algo, sign_priority_default); + _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_normal); } else if (strcasecmp (broken_list[i], "SECURE256") == 0 || strcasecmp (broken_list[i], "SECURE") == 0) @@ -614,6 +630,7 @@ gnutls_priority_init (gnutls_priority_t * priority_cache, _set_priority (&(*priority_cache)->mac, mac_priority_secure); _set_priority (&(*priority_cache)->sign_algo, sign_priority_secure256); + _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_secure256); } else if (strcasecmp (broken_list[i], "SECURE128") == 0) { @@ -623,6 +640,7 @@ gnutls_priority_init (gnutls_priority_t * priority_cache, _set_priority (&(*priority_cache)->mac, mac_priority_secure); _set_priority (&(*priority_cache)->sign_algo, sign_priority_secure128); + _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_secure128); } else if (strcasecmp (broken_list[i], "EXPORT") == 0) { @@ -631,6 +649,7 @@ gnutls_priority_init (gnutls_priority_t * priority_cache, _set_priority (&(*priority_cache)->mac, mac_priority_secure); _set_priority (&(*priority_cache)->sign_algo, sign_priority_default); + _set_priority (&(*priority_cache)->supported_ecc, supported_ecc_normal); } /* now check if the element is something like -ALGO */ else if (broken_list[i][0] == '!' || broken_list[i][0] == '+' || broken_list[i][0] == '-') @@ -690,6 +709,23 @@ gnutls_priority_init (gnutls_priority_t * priority_cache, goto error; } } /* now check if the element is something like -ALGO */ + else if (strncasecmp (&broken_list[i][1], "CURVE-", 6) == 0) + { + if (strncasecmp (&broken_list[i][1], "CURVE-ALL", 9) == 0) + { + bulk_fn (&(*priority_cache)->supported_ecc, + supported_ecc_normal); + } + else + { + if ((algo = + _gnutls_ecc_curve_get_id (&broken_list[i][7])) != + GNUTLS_ECC_CURVE_INVALID) + fn (&(*priority_cache)->supported_ecc, algo); + else + goto error; + } + } /* now check if the element is something like -ALGO */ else if (strncasecmp (&broken_list[i][1], "CTYPE-", 6) == 0) { if (strncasecmp (&broken_list[i][1], "CTYPE-ALL", 9) == 0) @@ -729,11 +765,16 @@ gnutls_priority_init (gnutls_priority_t * priority_cache, bulk_fn (&(*priority_cache)->mac, mac_priority_secure); } - else if (strncasecmp (&broken_list[i][1], "CIPHER-ALL", 7) == 0) + else if (strncasecmp (&broken_list[i][1], "CIPHER-ALL", 10) == 0) { bulk_fn (&(*priority_cache)->cipher, cipher_priority_normal); } + else if (strncasecmp (&broken_list[i][1], "KX-ALL", 6) == 0) + { + bulk_fn (&(*priority_cache)->kx, + kx_priority_secure); + } else goto error; }