diff options
Diffstat (limited to 'src/libstrongswan/credentials/auth_cfg.c')
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.c | 210 |
1 files changed, 161 insertions, 49 deletions
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index 12f75b240..6ee4f9b6e 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -23,20 +23,24 @@ #include <eap/eap.h> #include <credentials/certificates/certificate.h> -ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP, +ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_XAUTH, "any", "public key", "pre-shared key", "EAP", + "XAuth", ); ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_REVOCATION_CERT, "RULE_IDENTITY", + "RULE_IDENTITY_LOOSE", "RULE_AUTH_CLASS", "RULE_AAA_IDENTITY", "RULE_EAP_IDENTITY", "RULE_EAP_TYPE", "RULE_EAP_VENDOR", + "RULE_XAUTH_BACKEND", + "RULE_XAUTH_IDENTITY", "RULE_CA_CERT", "RULE_IM_CERT", "RULE_SUBJECT_CERT", @@ -45,6 +49,7 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_REVOCATION_CERT, "RULE_GROUP", "RULE_RSA_STRENGTH", "RULE_ECDSA_STRENGTH", + "RULE_SIGNATURE_SCHEME", "RULE_CERT_POLICY", "HELPER_IM_CERT", "HELPER_SUBJECT_CERT", @@ -66,8 +71,11 @@ static inline bool is_multi_value_rule(auth_rule_t type) case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_IDENTITY: + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_SUBJECT_CERT: case AUTH_HELPER_SUBJECT_CERT: case AUTH_HELPER_SUBJECT_HASH_URL: @@ -79,6 +87,7 @@ static inline bool is_multi_value_rule(auth_rule_t type) case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_SIGNATURE_SCHEME: case AUTH_HELPER_IM_CERT: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_REVOCATION_CERT: @@ -190,6 +199,7 @@ static entry_t *entry_create(auth_rule_t type, va_list args) this->type = type; switch (type) { + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -197,12 +207,15 @@ static entry_t *entry_create(auth_rule_t type, va_list args) case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: /* integer type */ this->value = (void*)(uintptr_t)va_arg(args, u_int); break; case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: @@ -234,6 +247,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) } switch (e1->type) { + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -241,6 +255,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: { return e1->value == e2->value; } @@ -261,6 +276,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: { identification_t *id1, *id2; @@ -271,6 +287,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) return id1->equals(id1, id2); } case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_XAUTH_BACKEND: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: { @@ -293,6 +310,7 @@ static void destroy_entry_value(entry_t *entry) case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id = (identification_t*)entry->value; id->destroy(id); @@ -310,12 +328,14 @@ static void destroy_entry_value(entry_t *entry) break; } case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_XAUTH_BACKEND: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: { free(entry->value); break; } + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -323,6 +343,7 @@ static void destroy_entry_value(entry_t *entry) case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: case AUTH_RULE_MAX: break; } @@ -345,6 +366,7 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator, entry->type = type; switch (type) { + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -352,12 +374,15 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator, case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: /* integer type */ entry->value = (void*)(uintptr_t)va_arg(args, u_int); break; case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: @@ -423,12 +448,18 @@ METHOD(auth_cfg_t, get, void*, case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: return (void*)0; + case AUTH_RULE_SIGNATURE_SCHEME: + return HASH_UNKNOWN; case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: return (void*)VALIDATION_FAILED; + case AUTH_RULE_IDENTITY_LOOSE: + return (void*)FALSE; case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: @@ -472,7 +503,10 @@ METHOD(auth_cfg_t, complies, bool, private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error) { enumerator_t *e1, *e2; - bool success = TRUE, has_group = FALSE, group_match = FALSE; + bool success = TRUE, group_match = FALSE; + identification_t *require_group = NULL; + signature_scheme_t scheme = SIGN_UNKNOWN; + u_int strength = 0; auth_rule_t t1, t2; void *value; @@ -571,6 +605,7 @@ METHOD(auth_cfg_t, complies, bool, case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id1, *id2; @@ -578,6 +613,17 @@ METHOD(auth_cfg_t, complies, bool, id2 = get(this, t1); if (!id2 || !id2->matches(id2, id1)) { + if (t1 == AUTH_RULE_IDENTITY && + constraints->get(constraints, AUTH_RULE_IDENTITY_LOOSE)) + { /* also verify identity against subjectAltNames */ + certificate_t *cert; + + cert = get(this, AUTH_HELPER_SUBJECT_CERT); + if (cert && cert->has_subject(cert, id1)) + { + break; + } + } success = FALSE; if (log_error) { @@ -633,15 +679,15 @@ METHOD(auth_cfg_t, complies, bool, } case AUTH_RULE_GROUP: { - identification_t *id1, *id2; + identification_t *group; /* for groups, a match of a single group is sufficient */ - has_group = TRUE; - id1 = (identification_t*)value; + require_group = (identification_t*)value; e2 = create_enumerator(this); - while (e2->enumerate(e2, &t2, &id2)) + while (e2->enumerate(e2, &t2, &group)) { - if (t2 == AUTH_RULE_GROUP && id2->matches(id2, id1)) + if (t2 == AUTH_RULE_GROUP && + group->matches(group, require_group)) { group_match = TRUE; } @@ -652,44 +698,12 @@ METHOD(auth_cfg_t, complies, bool, case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: { - uintptr_t strength; - - e2 = create_enumerator(this); - while (e2->enumerate(e2, &t2, &strength)) - { - if (t2 == t1) - { - 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); + strength = (uintptr_t)value; + break; + } + case AUTH_RULE_SIGNATURE_SCHEME: + { + scheme = (uintptr_t)value; break; } case AUTH_RULE_CERT_POLICY: @@ -714,6 +728,10 @@ METHOD(auth_cfg_t, complies, bool, } break; } + case AUTH_RULE_IDENTITY_LOOSE: + /* just an indication when verifying AUTH_RULE_IDENTITY */ + case AUTH_RULE_XAUTH_BACKEND: + /* not enforced, just a hint for local authentication */ case AUTH_HELPER_IM_CERT: case AUTH_HELPER_SUBJECT_CERT: case AUTH_HELPER_IM_HASH_URL: @@ -730,11 +748,83 @@ METHOD(auth_cfg_t, complies, bool, } e1->destroy(e1); - if (has_group && !group_match) + /* Check if we have a matching constraint (or none at all) for used + * signature schemes. */ + if (success && scheme != SIGN_UNKNOWN) + { + e2 = create_enumerator(this); + while (e2->enumerate(e2, &t2, &scheme)) + { + if (t2 == AUTH_RULE_SIGNATURE_SCHEME) + { + success = FALSE; + e1 = constraints->create_enumerator(constraints); + while (e1->enumerate(e1, &t1, &value)) + { + if (t1 == AUTH_RULE_SIGNATURE_SCHEME && + (uintptr_t)value == scheme) + { + success = TRUE; + break; + } + } + e1->destroy(e1); + if (!success) + { + if (log_error) + { + DBG1(DBG_CFG, "signature scheme %N not acceptable", + signature_scheme_names, (int)scheme); + } + break; + } + } + } + e2->destroy(e2); + } + + /* Check if we have a matching constraint (or none at all) for used + * public key strength */ + if (success && strength) + { + e2 = create_enumerator(this); + while (e2->enumerate(e2, &t2, &strength)) + { + if (t2 == AUTH_RULE_RSA_STRENGTH || + t2 == AUTH_RULE_ECDSA_STRENGTH) + { + success = FALSE; + e1 = constraints->create_enumerator(constraints); + while (e1->enumerate(e1, &t1, &value)) + { + if (t1 == t2 && (uintptr_t)value <= strength) + { + success = TRUE; + break; + } + } + e1->destroy(e1); + if (!success) + { + if (log_error) + { + DBG1(DBG_CFG, "%s-%d signatures not acceptable", + t2 == AUTH_RULE_RSA_STRENGTH ? "RSA" : "ECDSA", + strength); + } + break; + } + } + } + e2->destroy(e2); + } + + if (require_group && !group_match) { if (log_error) { - DBG1(DBG_CFG, "constraint check failed: group membership required"); + DBG1(DBG_CFG, "constraint check failed: group membership to " + "'%Y' required", require_group); } return FALSE; } @@ -774,6 +864,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy add(this, type, cert->get_ref(cert)); break; } + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_AUTH_CLASS: @@ -781,6 +872,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: { add(this, type, (uintptr_t)value); break; @@ -789,12 +881,14 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id = (identification_t*)value; add(this, type, id->clone(id)); break; } + case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_CERT_POLICY: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: @@ -821,9 +915,9 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy } /** - * Implementation of auth_cfg_t.equals. + * Compare two auth_cfg_t objects for equality. */ -static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) +static bool auth_cfg_equals(private_auth_cfg_t *this, private_auth_cfg_t *other) { enumerator_t *e1, *e2; entry_t *i1, *i2; @@ -860,6 +954,20 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) return equal; } +/** + * Implementation of auth_cfg_t.equals. + */ +static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) +{ + if (auth_cfg_equals(this, other)) + { + /* as 'other' might contain entries that 'this' doesn't we also check + * the other way around */ + return auth_cfg_equals(other, this); + } + return FALSE; +} + METHOD(auth_cfg_t, purge, void, private_auth_cfg_t *this, bool keep_ca) { @@ -904,6 +1012,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id = (identification_t*)entry->value; clone->add(clone, entry->type, id->clone(id)); @@ -920,6 +1029,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, clone->add(clone, entry->type, cert->get_ref(cert)); break; } + case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_CERT_POLICY: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: @@ -927,6 +1037,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, clone->add(clone, entry->type, strdup(entry->value)); break; } + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -934,6 +1045,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: clone->add(clone, entry->type, (uintptr_t)entry->value); break; case AUTH_RULE_MAX: |