diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index 9bde66d16..e7e9f414d 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -366,38 +366,45 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints, case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: { - cert_validation_t validated, required; + uintptr_t validated; - required = (uintptr_t)value; - validated = (uintptr_t)get(this, t1); - switch (required) + e2 = create_enumerator(this); + while (e2->enumerate(e2, &t2, &validated)) { - case VALIDATION_FAILED: - /* no constraint */ - break; - case VALIDATION_SKIPPED: - if (validated == VALIDATION_SKIPPED) + if (t2 == t1) + { + switch ((uintptr_t)value) { - break; + case VALIDATION_FAILED: + /* no constraint */ + break; + case VALIDATION_SKIPPED: + if (validated == VALIDATION_SKIPPED) + { + break; + } + /* FALL */ + case VALIDATION_GOOD: + if (validated == VALIDATION_GOOD) + { + break; + } + /* FALL */ + default: + success = FALSE; + if (log_error) + { + DBG1(DBG_CFG, "constraint check failed: " + "%N is %N, but requires at least %N", + auth_rule_names, t1, + cert_validation_names, validated, + cert_validation_names, (uintptr_t)value); + } + break; } - /* FALL */ - case VALIDATION_GOOD: - if (validated == VALIDATION_GOOD) - { - break; - } - /* FALL */ - default: - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint check failed: %N is %N, " - "but requires at least %N", auth_rule_names, - t1, cert_validation_names, validated, - cert_validation_names, required); - } - break; + } } + e2->destroy(e2); break; } case AUTH_RULE_IDENTITY: @@ -484,15 +491,44 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints, case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: { - if ((uintptr_t)value > (uintptr_t)get(this, t1)) + uintptr_t strength; + + e2 = create_enumerator(this); + while (e2->enumerate(e2, &t2, &strength)) { - success = FALSE; - if (log_error) + if (t2 == t1) { - DBG1(DBG_CFG, "constraint requires %d bit public key " - "strength", value); + if ((uintptr_t)value > strength) + { + success = FALSE; + if (log_error) + { + DBG1(DBG_CFG, "constraint requires %d bit " + "public keys, but %d bit key used", + (uintptr_t)value, strength); + } + } + } + else if (t2 == AUTH_RULE_RSA_STRENGTH) + { + success = FALSE; + if (log_error) + { + DBG1(DBG_CFG, "constraint requires %d bit ECDSA, " + "but RSA used", (uintptr_t)value); + } + } + else if (t2 == AUTH_RULE_ECDSA_STRENGTH) + { + success = FALSE; + if (log_error) + { + DBG1(DBG_CFG, "constraint requires %d bit RSA, " + "but ECDSA used", (uintptr_t)value); + } } } + e2->destroy(e2); break; } case AUTH_HELPER_IM_CERT: diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index bb2bf5be9..f437bbf98 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -551,52 +551,21 @@ static certificate_t *get_issuer_cert(private_credential_manager_t *this, } /** - * Get the strength of the weakest key in a trustchain + * Get the strength of certificate, add it to auth */ -static void calculate_trustchain_strength(auth_cfg_t *auth) +static void get_key_strength(certificate_t *cert, auth_cfg_t *auth) { - enumerator_t *enumerator; - uintptr_t strength = 0; - key_type_t type = KEY_ANY; - certificate_t *cert; + uintptr_t strength; public_key_t *key; - auth_rule_t rule; + key_type_t type; - enumerator = auth->create_enumerator(auth); - while (enumerator->enumerate(enumerator, &rule, &cert)) - { - switch (rule) - { - case AUTH_RULE_SUBJECT_CERT: - case AUTH_RULE_IM_CERT: - case AUTH_RULE_CA_CERT: - { - key = cert->get_public_key(cert); - if (!key || (type != KEY_ANY && type != key->get_type(key))) - { /* no key, or different key families */ - DESTROY_IF(key); - enumerator->destroy(enumerator); - return; - } - type = key->get_type(key); - if (!strength) - { - strength = key->get_keysize(key); - } - else - { - strength = min(strength, key->get_keysize(key)); - } - key->destroy(key); - break; - } - default: - break; - } - } - enumerator->destroy(enumerator); - if (strength) + key = cert->get_public_key(cert); + if (key) { + type = key->get_type(key); + strength = key->get_keysize(key); + DBG2(DBG_CFG, " certificate \"%Y\" key: %d bit %N", + cert->get_subject(cert), strength, key_type_names, type); switch (type) { case KEY_RSA: @@ -608,6 +577,7 @@ static void calculate_trustchain_strength(auth_cfg_t *auth) default: break; } + key->destroy(key); } } @@ -623,6 +593,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, int pathlen; auth = auth_cfg_create(); + get_key_strength(subject, auth); current = subject->get_ref(subject); for (pathlen = 0; pathlen <= MAX_TRUST_PATH_LEN; pathlen++) @@ -675,6 +646,10 @@ static bool verify_trust_chain(private_credential_manager_t *this, issuer->destroy(issuer); break; } + if (issuer) + { + get_key_strength(issuer, auth); + } current->destroy(current); current = issuer; if (trusted) @@ -746,7 +721,6 @@ METHOD(enumerator_t, trusted_enumerate, bool, { this->auth->add(this->auth, AUTH_RULE_SUBJECT_CERT, this->pretrusted->get_ref(this->pretrusted)); - calculate_trustchain_strength(this->auth); DBG1(DBG_CFG, " using trusted certificate \"%Y\"", this->pretrusted->get_subject(this->pretrusted)); *cert = this->pretrusted; @@ -775,7 +749,6 @@ METHOD(enumerator_t, trusted_enumerate, bool, this->auth->add(this->auth, AUTH_RULE_SUBJECT_CERT, current->get_ref(current)); *cert = current; - calculate_trustchain_strength(this->auth); if (auth) { *auth = this->auth;