tls_cache_t *cache;
/**
- * All handshake data concatentated
+ * All handshake data concatenated
*/
chunk_t handshake;
/**
* Filter a suite list using a transform enumerator
*/
-static void filter_suite(private_tls_crypto_t *this,
- suite_algs_t suites[], int *count, int offset,
+static void filter_suite(suite_algs_t suites[], int *count, int offset,
enumerator_t*(*create_enumerator)(crypto_factory_t*))
{
const char *plugin_name;
/**
* Purge NULL encryption cipher suites from list
*/
-static void filter_null_suites(private_tls_crypto_t *this,
- suite_algs_t suites[], int *count)
+static void filter_null_suites(suite_algs_t suites[], int *count)
{
int i, remaining = 0;
enumerator = enumerator_create_token(config, ",", " ");
while (enumerator->enumerate(enumerator, &token))
{
- suite = enum_from_name(tls_cipher_suite_names, token);
- if (suite == suites[i].suite)
+ if (enum_from_name(tls_cipher_suite_names, token, &suite) &&
+ suite == suites[i].suite)
{
suites[remaining++] = suites[i];
break;
}
}
+/**
+ * Filter out unsupported suites on given suite array
+ */
+static void filter_unsupported_suites(suite_algs_t suites[], int *count)
+{
+ /* filter suite list by each algorithm */
+ filter_suite(suites, count, offsetof(suite_algs_t, encr),
+ lib->crypto->create_crypter_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, encr),
+ lib->crypto->create_aead_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, mac),
+ lib->crypto->create_signer_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, prf),
+ lib->crypto->create_prf_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, hash),
+ lib->crypto->create_hasher_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, dh),
+ lib->crypto->create_dh_enumerator);
+}
+
/**
* Initialize the cipher suite list
*/
{
suites[i] = suite_algs[i];
}
+
if (require_encryption)
{
- filter_null_suites(this, suites, &count);
+ filter_null_suites(suites, &count);
}
if (!this->rsa)
{
filter_key_suites(this, suites, &count, KEY_ECDSA);
}
- /* 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, encr),
- lib->crypto->create_aead_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);
- filter_suite(this, suites, &count, offsetof(suite_algs_t, dh),
- lib->crypto->create_dh_enumerator);
+ filter_unsupported_suites(suites, &count);
/* filter suites with strongswan.conf options */
filter_key_exchange_config_suites(this, suites, &count);
tls_hash_algorithm_t hash;
signature_scheme_t scheme;
} schemes[] = {
- { TLS_SIG_ECDSA, TLS_HASH_SHA256, SIGN_ECDSA_WITH_SHA256_DER },
- { TLS_SIG_ECDSA, TLS_HASH_SHA384, SIGN_ECDSA_WITH_SHA384_DER },
- { TLS_SIG_ECDSA, TLS_HASH_SHA512, SIGN_ECDSA_WITH_SHA512_DER },
- { TLS_SIG_ECDSA, TLS_HASH_SHA1, SIGN_ECDSA_WITH_SHA1_DER },
- { TLS_SIG_RSA, TLS_HASH_SHA256, SIGN_RSA_EMSA_PKCS1_SHA256 },
- { TLS_SIG_RSA, TLS_HASH_SHA384, SIGN_RSA_EMSA_PKCS1_SHA384 },
- { TLS_SIG_RSA, TLS_HASH_SHA512, SIGN_RSA_EMSA_PKCS1_SHA512 },
- { TLS_SIG_RSA, TLS_HASH_SHA224, SIGN_RSA_EMSA_PKCS1_SHA224 },
- { TLS_SIG_RSA, TLS_HASH_SHA1, SIGN_RSA_EMSA_PKCS1_SHA1 },
- { TLS_SIG_RSA, TLS_HASH_MD5, SIGN_RSA_EMSA_PKCS1_MD5 },
+ { TLS_SIG_ECDSA, TLS_HASH_SHA256, SIGN_ECDSA_WITH_SHA256_DER },
+ { TLS_SIG_ECDSA, TLS_HASH_SHA384, SIGN_ECDSA_WITH_SHA384_DER },
+ { TLS_SIG_ECDSA, TLS_HASH_SHA512, SIGN_ECDSA_WITH_SHA512_DER },
+ { TLS_SIG_ECDSA, TLS_HASH_SHA1, SIGN_ECDSA_WITH_SHA1_DER },
+ { TLS_SIG_RSA, TLS_HASH_SHA256, SIGN_RSA_EMSA_PKCS1_SHA2_256 },
+ { TLS_SIG_RSA, TLS_HASH_SHA384, SIGN_RSA_EMSA_PKCS1_SHA2_384 },
+ { TLS_SIG_RSA, TLS_HASH_SHA512, SIGN_RSA_EMSA_PKCS1_SHA2_512 },
+ { TLS_SIG_RSA, TLS_HASH_SHA224, SIGN_RSA_EMSA_PKCS1_SHA2_224 },
+ { TLS_SIG_RSA, TLS_HASH_SHA1, SIGN_RSA_EMSA_PKCS1_SHA1 },
+ { TLS_SIG_RSA, TLS_HASH_MD5, SIGN_RSA_EMSA_PKCS1_MD5 },
};
METHOD(tls_crypto_t, get_signature_algorithms, void,
{ ECP_192_BIT, TLS_SECP192R1},
};
-/**
- * Filter EC groups, add TLS curve
- */
-static bool group_filter(void *null,
- diffie_hellman_group_t *in, diffie_hellman_group_t *out,
- void* dummy1, tls_named_curve_t *curve)
+CALLBACK(group_filter, bool,
+ void *null, enumerator_t *orig, va_list args)
{
+ diffie_hellman_group_t group, *out;
+ tls_named_curve_t *curve;
+ char *plugin;
int i;
- for (i = 0; i < countof(curves); i++)
+ VA_ARGS_VGET(args, out, curve);
+
+ while (orig->enumerate(orig, &group, &plugin))
{
- if (curves[i].group == *in)
+ for (i = 0; i < countof(curves); i++)
{
- if (out)
- {
- *out = curves[i].group;
- }
- if (curve)
+ if (curves[i].group == group)
{
- *curve = curves[i].curve;
+ if (out)
+ {
+ *out = curves[i].group;
+ }
+ if (curve)
+ {
+ *curve = curves[i].curve;
+ }
+ return TRUE;
}
- return TRUE;
}
}
return FALSE;
private_tls_crypto_t *this)
{
return enumerator_create_filter(
- lib->crypto->create_dh_enumerator(lib->crypto),
- (void*)group_filter, NULL, NULL);
+ lib->crypto->create_dh_enumerator(lib->crypto),
+ group_filter, NULL, NULL);
}
METHOD(tls_crypto_t, set_protection, void,
METHOD(tls_crypto_t, append_handshake, void,
private_tls_crypto_t *this, tls_handshake_type_t type, chunk_t data)
{
- u_int32_t header;
+ uint32_t header;
/* reconstruct handshake header */
header = htonl(data.len | (type << 24));
{
signature_scheme_t scheme;
bio_reader_t *reader;
- u_int8_t hash, alg;
+ uint8_t hash, alg;
chunk_t sig;
bool done = FALSE;
{
scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
if (scheme != SIGN_UNKNOWN &&
- key->sign(key, scheme, data, &sig))
+ key->sign(key, scheme, NULL, data, &sig))
{
done = TRUE;
break;
{
return FALSE;
}
- done = key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, &sig);
+ done = key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash,
+ &sig);
free(hash.ptr);
if (!done)
{
DBG2(DBG_TLS, "created signature with MD5+SHA1/RSA");
break;
case KEY_ECDSA:
- if (!key->sign(key, SIGN_ECDSA_WITH_SHA1_DER, data, &sig))
+ if (!key->sign(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data, &sig))
{
return FALSE;
}
if (this->tls->get_version(this->tls) >= TLS_1_2)
{
signature_scheme_t scheme = SIGN_UNKNOWN;
- u_int8_t hash, alg;
+ uint8_t hash, alg;
chunk_t sig;
if (!reader->read_uint8(reader, &hash) ||
tls_signature_algorithm_names, alg);
return FALSE;
}
- if (!key->verify(key, scheme, data, sig))
+ if (!key->verify(key, scheme, NULL, data, sig))
{
return FALSE;
}
{
return FALSE;
}
- done = key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, sig);
+ done = key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash,
+ sig);
free(hash.ptr);
if (!done)
{
DBG2(DBG_TLS, "verified signature data with MD5+SHA1/RSA");
break;
case KEY_ECDSA:
- if (!key->verify(key, SIGN_ECDSA_WITH_SHA1_DER, data, sig))
+ if (!key->verify(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data,
+ sig))
{
return FALSE;
}
case TLS_PURPOSE_GENERIC:
build_cipher_suite_list(this, TRUE);
break;
+ case TLS_PURPOSE_GENERIC_NULLOK:
+ build_cipher_suite_list(this, FALSE);
+ break;
default:
break;
}
return &this->public;
}
+
+/**
+ * See header.
+ */
+int tls_crypto_get_supported_suites(bool null, tls_cipher_suite_t **out)
+{
+ suite_algs_t suites[countof(suite_algs)];
+ int count = countof(suite_algs), i;
+
+ /* initialize copy of suite list */
+ for (i = 0; i < count; i++)
+ {
+ suites[i] = suite_algs[i];
+ }
+
+ filter_unsupported_suites(suites, &count);
+
+ if (!null)
+ {
+ filter_null_suites(suites, &count);
+ }
+
+ if (out)
+ {
+ *out = calloc(count, sizeof(tls_cipher_suite_t));
+ for (i = 0; i < count; i++)
+ {
+ (*out)[i] = suites[i].suite;
+ }
+ }
+ return count;
+}