diff options
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.c | 28 | ||||
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.h | 4 | ||||
-rw-r--r-- | src/libstrongswan/credentials/credential_manager.c | 65 |
3 files changed, 97 insertions, 0 deletions
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index ce718b9cb..9bde66d16 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -147,6 +147,8 @@ static void destroy_entry_value(entry_t *entry) case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: + case AUTH_RULE_RSA_STRENGTH: + case AUTH_RULE_ECDSA_STRENGTH: break; } } @@ -172,6 +174,8 @@ static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator, case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: + case AUTH_RULE_RSA_STRENGTH: + case AUTH_RULE_ECDSA_STRENGTH: /* integer type */ enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int); break; @@ -237,6 +241,8 @@ static void* get(private_auth_cfg_t *this, auth_rule_t type) case AUTH_RULE_EAP_TYPE: return (void*)EAP_NAK; case AUTH_RULE_EAP_VENDOR: + case AUTH_RULE_RSA_STRENGTH: + case AUTH_RULE_ECDSA_STRENGTH: return (void*)0; case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: @@ -274,6 +280,8 @@ static void add(private_auth_cfg_t *this, auth_rule_t type, ...) case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: + case AUTH_RULE_RSA_STRENGTH: + case AUTH_RULE_ECDSA_STRENGTH: /* integer type */ entry->value = (void*)(uintptr_t)va_arg(args, u_int); break; @@ -473,6 +481,20 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints, e2->destroy(e2); break; } + case AUTH_RULE_RSA_STRENGTH: + case AUTH_RULE_ECDSA_STRENGTH: + { + if ((uintptr_t)value > (uintptr_t)get(this, t1)) + { + success = FALSE; + if (log_error) + { + DBG1(DBG_CFG, "constraint requires %d bit public key " + "strength", value); + } + } + break; + } case AUTH_HELPER_IM_CERT: case AUTH_HELPER_SUBJECT_CERT: case AUTH_HELPER_IM_HASH_URL: @@ -534,6 +556,8 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: + case AUTH_RULE_RSA_STRENGTH: + case AUTH_RULE_ECDSA_STRENGTH: { add(this, type, (uintptr_t)value); break; @@ -600,6 +624,8 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: + case AUTH_RULE_RSA_STRENGTH: + case AUTH_RULE_ECDSA_STRENGTH: { if (i1->value == i2->value) { @@ -741,6 +767,8 @@ static auth_cfg_t* clone_(private_auth_cfg_t *this) case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: + case AUTH_RULE_RSA_STRENGTH: + case AUTH_RULE_ECDSA_STRENGTH: clone->add(clone, entry->type, (uintptr_t)entry->value); break; } diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h index 19624a2fe..ba92b16e0 100644 --- a/src/libstrongswan/credentials/auth_cfg.h +++ b/src/libstrongswan/credentials/auth_cfg.h @@ -90,6 +90,10 @@ enum auth_rule_t { * The group membership constraint is fulfilled if the subject is member of * one group defined in the constraints. */ AUTH_RULE_GROUP, + /** required RSA public key strength, u_int in bits */ + AUTH_RULE_RSA_STRENGTH, + /** required ECDSA public key strength, u_int in bits */ + AUTH_RULE_ECDSA_STRENGTH, /** intermediate certificate, certificate_t* */ AUTH_HELPER_IM_CERT, diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index 97e8d8887..bb2bf5be9 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -551,6 +551,67 @@ static certificate_t *get_issuer_cert(private_credential_manager_t *this, } /** + * Get the strength of the weakest key in a trustchain + */ +static void calculate_trustchain_strength(auth_cfg_t *auth) +{ + enumerator_t *enumerator; + uintptr_t strength = 0; + key_type_t type = KEY_ANY; + certificate_t *cert; + public_key_t *key; + auth_rule_t rule; + + 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) + { + switch (type) + { + case KEY_RSA: + auth->add(auth, AUTH_RULE_RSA_STRENGTH, strength); + break; + case KEY_ECDSA: + auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength); + break; + default: + break; + } + } +} + +/** * try to verify the trust chain of subject, return TRUE if trusted */ static bool verify_trust_chain(private_credential_manager_t *this, @@ -685,6 +746,7 @@ 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; @@ -710,7 +772,10 @@ METHOD(enumerator_t, trusted_enumerate, bool, if (verify_trust_chain(this->this, current, this->auth, FALSE, this->online)) { + 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; |