summaryrefslogtreecommitdiff
path: root/src/libstrongswan/credentials/auth_cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/credentials/auth_cfg.c')
-rw-r--r--src/libstrongswan/credentials/auth_cfg.c248
1 files changed, 217 insertions, 31 deletions
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index 9988d8021..956ce08c9 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2015 Tobias Brunner
+ * Copyright (C) 2008-2016 Tobias Brunner
* Copyright (C) 2007-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -46,11 +46,13 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT,
"RULE_SUBJECT_CERT",
"RULE_CRL_VALIDATION",
"RULE_OCSP_VALIDATION",
+ "RULE_CERT_VALIDATION_SUSPENDED",
"RULE_GROUP",
"RULE_RSA_STRENGTH",
"RULE_ECDSA_STRENGTH",
"RULE_BLISS_STRENGTH",
"RULE_SIGNATURE_SCHEME",
+ "RULE_IKE_SIGNATURE_SCHEME",
"RULE_CERT_POLICY",
"HELPER_IM_CERT",
"HELPER_SUBJECT_CERT",
@@ -79,6 +81,7 @@ static inline bool is_multi_value_rule(auth_rule_t type)
case AUTH_RULE_AAA_IDENTITY:
case AUTH_RULE_XAUTH_IDENTITY:
case AUTH_RULE_XAUTH_BACKEND:
+ case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
case AUTH_HELPER_SUBJECT_CERT:
case AUTH_HELPER_SUBJECT_HASH_URL:
case AUTH_RULE_MAX:
@@ -91,6 +94,7 @@ static inline bool is_multi_value_rule(auth_rule_t type)
case AUTH_RULE_IM_CERT:
case AUTH_RULE_CERT_POLICY:
case AUTH_RULE_SIGNATURE_SCHEME:
+ case AUTH_RULE_IKE_SIGNATURE_SCHEME:
case AUTH_HELPER_IM_CERT:
case AUTH_HELPER_IM_HASH_URL:
case AUTH_HELPER_REVOCATION_CERT:
@@ -211,6 +215,8 @@ static void init_entry(entry_t *this, auth_rule_t type, va_list args)
case AUTH_RULE_ECDSA_STRENGTH:
case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
+ case AUTH_RULE_IKE_SIGNATURE_SCHEME:
+ case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
/* integer type */
this->value = (void*)(uintptr_t)va_arg(args, u_int);
break;
@@ -260,6 +266,8 @@ static bool entry_equals(entry_t *e1, entry_t *e2)
case AUTH_RULE_ECDSA_STRENGTH:
case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
+ case AUTH_RULE_IKE_SIGNATURE_SCHEME:
+ case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
{
return e1->value == e2->value;
}
@@ -351,6 +359,8 @@ static void destroy_entry_value(entry_t *entry)
case AUTH_RULE_ECDSA_STRENGTH:
case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
+ case AUTH_RULE_IKE_SIGNATURE_SCHEME:
+ case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
case AUTH_RULE_MAX:
break;
}
@@ -383,6 +393,8 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator,
case AUTH_RULE_ECDSA_STRENGTH:
case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
+ case AUTH_RULE_IKE_SIGNATURE_SCHEME:
+ case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
/* integer type */
entry->value = (void*)(uintptr_t)va_arg(args, u_int);
break;
@@ -459,11 +471,13 @@ METHOD(auth_cfg_t, get, void*,
case AUTH_RULE_BLISS_STRENGTH:
return (void*)0;
case AUTH_RULE_SIGNATURE_SCHEME:
+ case AUTH_RULE_IKE_SIGNATURE_SCHEME:
return (void*)HASH_UNKNOWN;
case AUTH_RULE_CRL_VALIDATION:
case AUTH_RULE_OCSP_VALIDATION:
return (void*)VALIDATION_FAILED;
case AUTH_RULE_IDENTITY_LOOSE:
+ case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
return (void*)FALSE;
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
@@ -510,6 +524,183 @@ static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
}
}
+METHOD(auth_cfg_t, add_pubkey_constraints, void,
+ private_auth_cfg_t *this, char* constraints, bool ike)
+{
+ enumerator_t *enumerator;
+ bool is_ike = FALSE, ike_added = FALSE;
+ key_type_t expected_type = -1;
+ auth_rule_t expected_strength = AUTH_RULE_MAX;
+ int strength;
+ char *token;
+ auth_rule_t type;
+ void *value;
+
+ enumerator = enumerator_create_token(constraints, "-", "");
+ while (enumerator->enumerate(enumerator, &token))
+ {
+ bool found = FALSE;
+ int i;
+ struct {
+ char *name;
+ signature_scheme_t scheme;
+ key_type_t key;
+ } schemes[] = {
+ { "md5", SIGN_RSA_EMSA_PKCS1_MD5, KEY_RSA, },
+ { "sha1", SIGN_RSA_EMSA_PKCS1_SHA1, KEY_RSA, },
+ { "sha224", SIGN_RSA_EMSA_PKCS1_SHA224, KEY_RSA, },
+ { "sha256", SIGN_RSA_EMSA_PKCS1_SHA256, KEY_RSA, },
+ { "sha384", SIGN_RSA_EMSA_PKCS1_SHA384, KEY_RSA, },
+ { "sha512", SIGN_RSA_EMSA_PKCS1_SHA512, KEY_RSA, },
+ { "sha1", SIGN_ECDSA_WITH_SHA1_DER, KEY_ECDSA, },
+ { "sha256", SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, },
+ { "sha384", SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, },
+ { "sha512", SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, },
+ { "sha256", SIGN_ECDSA_256, KEY_ECDSA, },
+ { "sha384", SIGN_ECDSA_384, KEY_ECDSA, },
+ { "sha512", SIGN_ECDSA_521, KEY_ECDSA, },
+ { "sha256", SIGN_BLISS_WITH_SHA2_256, KEY_BLISS, },
+ { "sha384", SIGN_BLISS_WITH_SHA2_384, KEY_BLISS, },
+ { "sha512", SIGN_BLISS_WITH_SHA2_512, KEY_BLISS, },
+ };
+
+ if (expected_strength != AUTH_RULE_MAX)
+ { /* expecting a key strength token */
+ strength = atoi(token);
+ if (strength)
+ {
+ add(this, expected_strength, (uintptr_t)strength);
+ }
+ expected_strength = AUTH_RULE_MAX;
+ if (strength)
+ {
+ continue;
+ }
+ }
+ if (streq(token, "rsa") || streq(token, "ike:rsa"))
+ {
+ expected_type = KEY_RSA;
+ expected_strength = AUTH_RULE_RSA_STRENGTH;
+ is_ike = strpfx(token, "ike:");
+ continue;
+ }
+ if (streq(token, "ecdsa") || streq(token, "ike:ecdsa"))
+ {
+ expected_type = KEY_ECDSA;
+ expected_strength = AUTH_RULE_ECDSA_STRENGTH;
+ is_ike = strpfx(token, "ike:");
+ continue;
+ }
+ if (streq(token, "bliss") || streq(token, "ike:bliss"))
+ {
+ expected_type = KEY_BLISS;
+ expected_strength = AUTH_RULE_BLISS_STRENGTH;
+ is_ike = strpfx(token, "ike:");
+ continue;
+ }
+ if (streq(token, "pubkey") || streq(token, "ike:pubkey"))
+ {
+ expected_type = KEY_ANY;
+ is_ike = strpfx(token, "ike:");
+ continue;
+ }
+ if (is_ike && !ike)
+ {
+ continue;
+ }
+
+ for (i = 0; i < countof(schemes); i++)
+ {
+ if (streq(schemes[i].name, token))
+ {
+ if (expected_type == KEY_ANY || expected_type == schemes[i].key)
+ {
+ if (is_ike)
+ {
+ add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME,
+ (uintptr_t)schemes[i].scheme);
+ ike_added = TRUE;
+ }
+ else
+ {
+ add(this, AUTH_RULE_SIGNATURE_SCHEME,
+ (uintptr_t)schemes[i].scheme);
+ }
+ }
+ found = TRUE;
+ }
+ }
+ if (!found)
+ {
+ DBG1(DBG_CFG, "ignoring invalid auth token: '%s'", token);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ /* if no explicit IKE signature contraints were added we add them for all
+ * configured signature contraints */
+ if (ike && !ike_added &&
+ lib->settings->get_bool(lib->settings,
+ "%s.signature_authentication_constraints", TRUE,
+ lib->ns))
+ {
+ enumerator = create_enumerator(this);
+ while (enumerator->enumerate(enumerator, &type, &value))
+ {
+ if (type == AUTH_RULE_SIGNATURE_SCHEME)
+ {
+ add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME,
+ (uintptr_t)value);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+}
+
+/**
+ * Check if signature schemes of a specific type are compliant
+ */
+static bool complies_scheme(private_auth_cfg_t *this, auth_cfg_t *constraints,
+ auth_rule_t type, bool log_error)
+{
+ enumerator_t *e1, *e2;
+ auth_rule_t t1, t2;
+ signature_scheme_t scheme;
+ void *value;
+ bool success = TRUE;
+
+ e2 = create_enumerator(this);
+ while (e2->enumerate(e2, &t2, &scheme))
+ {
+ if (t2 == type)
+ {
+ success = FALSE;
+ e1 = constraints->create_enumerator(constraints);
+ while (e1->enumerate(e1, &t1, &value))
+ {
+ if (t1 == type && (uintptr_t)value == scheme)
+ {
+ success = TRUE;
+ break;
+ }
+ }
+ e1->destroy(e1);
+ if (!success)
+ {
+ if (log_error)
+ {
+ DBG1(DBG_CFG, "%s signature scheme %N not acceptable",
+ AUTH_RULE_SIGNATURE_SCHEME == type ? "X.509" : "IKE",
+ signature_scheme_names, (int)scheme);
+ }
+ break;
+ }
+ }
+ }
+ e2->destroy(e2);
+ return success;
+}
+
METHOD(auth_cfg_t, complies, bool,
private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error)
{
@@ -518,7 +709,7 @@ METHOD(auth_cfg_t, complies, bool,
bool ca_match = FALSE, cert_match = FALSE;
identification_t *require_group = NULL;
certificate_t *require_ca = NULL, *require_cert = NULL;
- signature_scheme_t scheme = SIGN_UNKNOWN;
+ signature_scheme_t ike_scheme = SIGN_UNKNOWN, scheme = SIGN_UNKNOWN;
u_int strength = 0;
auth_rule_t t1, t2;
char *key_type;
@@ -573,6 +764,11 @@ METHOD(auth_cfg_t, complies, bool,
{
uintptr_t validated;
+ if (get(this, AUTH_RULE_CERT_VALIDATION_SUSPENDED))
+ { /* skip validation, may happen later */
+ break;
+ }
+
e2 = create_enumerator(this);
while (e2->enumerate(e2, &t2, &validated))
{
@@ -714,6 +910,11 @@ METHOD(auth_cfg_t, complies, bool,
strength = (uintptr_t)value;
break;
}
+ case AUTH_RULE_IKE_SIGNATURE_SCHEME:
+ {
+ ike_scheme = (uintptr_t)value;
+ break;
+ }
case AUTH_RULE_SIGNATURE_SCHEME:
{
scheme = (uintptr_t)value;
@@ -745,6 +946,8 @@ METHOD(auth_cfg_t, complies, bool,
/* just an indication when verifying AUTH_RULE_IDENTITY */
case AUTH_RULE_XAUTH_BACKEND:
/* not enforced, just a hint for local authentication */
+ case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
+ /* not a constraint */
case AUTH_HELPER_IM_CERT:
case AUTH_HELPER_SUBJECT_CERT:
case AUTH_HELPER_IM_HASH_URL:
@@ -766,35 +969,13 @@ METHOD(auth_cfg_t, complies, bool,
* 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);
+ success = complies_scheme(this, constraints,
+ AUTH_RULE_SIGNATURE_SCHEME, log_error);
+ }
+ if (success && ike_scheme != SIGN_UNKNOWN)
+ {
+ success = complies_scheme(this, constraints,
+ AUTH_RULE_IKE_SIGNATURE_SCHEME, log_error);
}
/* Check if we have a matching constraint (or none at all) for used
@@ -918,6 +1099,8 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
case AUTH_RULE_ECDSA_STRENGTH:
case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
+ case AUTH_RULE_IKE_SIGNATURE_SCHEME:
+ case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
{
add(this, type, (uintptr_t)value);
break;
@@ -1088,6 +1271,8 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*,
case AUTH_RULE_ECDSA_STRENGTH:
case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
+ case AUTH_RULE_IKE_SIGNATURE_SCHEME:
+ case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
clone->add(clone, type, (uintptr_t)value);
break;
case AUTH_RULE_MAX:
@@ -1116,6 +1301,7 @@ auth_cfg_t *auth_cfg_create()
INIT(this,
.public = {
.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add,
+ .add_pubkey_constraints = _add_pubkey_constraints,
.get = _get,
.create_enumerator = _create_enumerator,
.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace,