diff options
author | Martin Willi <martin@revosec.ch> | 2010-08-20 12:10:21 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-08-20 12:11:21 +0200 |
commit | a2bfc45bfd6f6ec19eb91810e51478e022bca6c8 (patch) | |
tree | 8ea833071a5fe22cccdbdd04b73fc2d6725fae02 | |
parent | 2e64455ee1530f4d2dbcbd061c0ae8f9c10352f4 (diff) | |
download | strongswan-a2bfc45bfd6f6ec19eb91810e51478e022bca6c8.tar.bz2 strongswan-a2bfc45bfd6f6ec19eb91810e51478e022bca6c8.tar.xz |
Build TLS cipher suite list in a generic fashion
-rw-r--r-- | src/libtls/tls_crypto.c | 125 |
1 files changed, 51 insertions, 74 deletions
diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c index 5668f1302..acb732ef0 100644 --- a/src/libtls/tls_crypto.c +++ b/src/libtls/tls_crypto.c @@ -401,94 +401,71 @@ static suite_algs_t *find_suite(tls_cipher_suite_t suite) } /** - * Initialize the cipher suite list + * Filter a suite list using a transform enumerator */ -static void build_cipher_suite_list(private_tls_crypto_t *this) +static void filter_suite(private_tls_crypto_t *this, + suite_algs_t suites[], int *count, int offset, + enumerator_t*(*create_enumerator)(crypto_factory_t*)) { - encryption_algorithm_t encr; - integrity_algorithm_t mac; - enumerator_t *encrs, *macs; - tls_cipher_suite_t supported[64], unique[64]; - int count = 0, i, j; + suite_algs_t current; + int i, remaining = 0; + enumerator_t *enumerator; - /* we assume that we support RSA, but no DHE yet */ - macs = lib->crypto->create_signer_enumerator(lib->crypto); - while (macs->enumerate(macs, &mac)) + memset(¤t, 0, sizeof(current)); + for (i = 0; i < *count; i++) { - switch (mac) + enumerator = create_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, ((char*)¤t) + offset)) { - case AUTH_HMAC_SHA1_160: - supported[count++] = TLS_RSA_WITH_NULL_SHA; - break; - case AUTH_HMAC_SHA2_256_256: - supported[count++] = TLS_RSA_WITH_NULL_SHA256; - break; - case AUTH_HMAC_MD5_128: - supported[count++] = TLS_RSA_WITH_NULL_MD5; - break; - default: - break; - } - encrs = lib->crypto->create_crypter_enumerator(lib->crypto); - while (encrs->enumerate(encrs, &encr)) - { - switch (encr) + if ((suites[i].encr == ENCR_NULL || + !current.encr || current.encr == suites[i].encr) && + (!current.mac || current.mac == suites[i].mac) && + (!current.prf || current.prf == suites[i].prf) && + (!current.hash || current.hash == suites[i].hash)) { - case ENCR_AES_CBC: - switch (mac) - { - case AUTH_HMAC_SHA1_160: - supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA; - supported[count++] = TLS_RSA_WITH_AES_256_CBC_SHA; - break; - case AUTH_HMAC_SHA2_256_256: - supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256; - supported[count++] = TLS_RSA_WITH_AES_256_CBC_SHA256; - break; - default: - break; - } - break; - case ENCR_3DES: - switch (mac) - { - case AUTH_HMAC_SHA1_160: - supported[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA; - break; - default: - break; - } - break; - default: - break; + suites[remaining] = suites[i]; + remaining++; + break; } } - encrs->destroy(encrs); + enumerator->destroy(enumerator); } - macs->destroy(macs); + *count = remaining; +} + +/** + * Initialize the cipher suite list + */ +static void build_cipher_suite_list(private_tls_crypto_t *this) +{ + suite_algs_t suites[countof(suite_algs)]; + int count = countof(suite_algs), i; - /* remove duplicates */ - this->suite_count = 0; + /* copy all suites */ for (i = 0; i < count; i++) { - bool match = FALSE; - - for (j = 0; j < this->suite_count; j++) - { - if (supported[i] == unique[j]) - { - match = TRUE; - break; - } - } - if (!match) - { - unique[this->suite_count++] = supported[i]; - } + suites[i] = suite_algs[i]; } + /* filter suite list by each algorithm */ + filter_suite(this, suites, &count, offsetof(suite_algs_t, encr), + lib->crypto->create_crypter_enumerator); + filter_suite(this, suites, &count, offsetof(suite_algs_t, mac), + lib->crypto->create_signer_enumerator); + filter_suite(this, suites, &count, offsetof(suite_algs_t, prf), + lib->crypto->create_prf_enumerator); + filter_suite(this, suites, &count, offsetof(suite_algs_t, hash), + lib->crypto->create_hasher_enumerator); + + DBG2(DBG_CFG, "%d supported TLS cipher suites:", count); + for (i = 0; i < count; i++) + { + DBG2(DBG_CFG, " %N", tls_cipher_suite_names, suites[i]); + } + free(this->suites); - this->suites = malloc(sizeof(tls_cipher_suite_t) * this->suite_count); - memcpy(this->suites, unique, sizeof(tls_cipher_suite_t) * this->suite_count); + this->suite_count = count; + this->suites = malloc(sizeof(tls_cipher_suite_t) * count); + memcpy(this->suites, suites, sizeof(tls_cipher_suite_t) * this->suite_count); } METHOD(tls_crypto_t, get_cipher_suites, int, |