diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2015-04-11 22:03:59 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2015-04-11 22:03:59 +0200 |
commit | 83b8aebb19fe6e49e13a05d4e8f5ab9a06177642 (patch) | |
tree | 51255545ba43b84aa5d673bd0eb557cbd0155c9e /src/libstrongswan/credentials | |
parent | 2b8de74ff4c334c25e89988c4a401b24b5bcf03d (diff) | |
download | vyos-strongswan-83b8aebb19fe6e49e13a05d4e8f5ab9a06177642.tar.gz vyos-strongswan-83b8aebb19fe6e49e13a05d4e8f5ab9a06177642.zip |
Imported Upstream version 5.3.0
Diffstat (limited to 'src/libstrongswan/credentials')
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.c | 60 | ||||
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.h | 4 | ||||
-rw-r--r-- | src/libstrongswan/credentials/cred_encoding.h | 4 | ||||
-rw-r--r-- | src/libstrongswan/credentials/credential_manager.c | 3 | ||||
-rw-r--r-- | src/libstrongswan/credentials/keys/public_key.c | 168 | ||||
-rw-r--r-- | src/libstrongswan/credentials/keys/public_key.h | 41 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/cert_cache.c | 17 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/mem_cred.c | 19 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/mem_cred.h | 12 |
9 files changed, 292 insertions, 36 deletions
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index db08c6b96..0ca45a15b 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2007-2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -49,6 +49,7 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT, "RULE_GROUP", "RULE_RSA_STRENGTH", "RULE_ECDSA_STRENGTH", + "RULE_BLISS_STRENGTH", "RULE_SIGNATURE_SCHEME", "RULE_CERT_POLICY", "HELPER_IM_CERT", @@ -71,6 +72,7 @@ static inline bool is_multi_value_rule(auth_rule_t type) case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: case AUTH_RULE_IDENTITY: case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_EAP_IDENTITY: @@ -207,6 +209,7 @@ static void init_entry(entry_t *this, 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_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: /* integer type */ this->value = (void*)(uintptr_t)va_arg(args, u_int); @@ -255,6 +258,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_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: { return e1->value == e2->value; @@ -345,6 +349,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_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: case AUTH_RULE_MAX: break; @@ -376,6 +381,7 @@ 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_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: /* integer type */ entry->value = (void*)(uintptr_t)va_arg(args, u_int); @@ -450,6 +456,7 @@ METHOD(auth_cfg_t, get, void*, case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: return (void*)0; case AUTH_RULE_SIGNATURE_SCHEME: return (void*)HASH_UNKNOWN; @@ -513,6 +520,7 @@ METHOD(auth_cfg_t, complies, bool, signature_scheme_t scheme = SIGN_UNKNOWN; u_int strength = 0; auth_rule_t t1, t2; + char *key_type; void *value; e1 = constraints->create_enumerator(constraints); @@ -703,6 +711,7 @@ METHOD(auth_cfg_t, complies, bool, } case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: { strength = (uintptr_t)value; break; @@ -797,30 +806,39 @@ METHOD(auth_cfg_t, complies, bool, e2 = create_enumerator(this); while (e2->enumerate(e2, &t2, &strength)) { - if (t2 == AUTH_RULE_RSA_STRENGTH || - t2 == AUTH_RULE_ECDSA_STRENGTH) + switch (t2) { - success = FALSE; - e1 = constraints->create_enumerator(constraints); - while (e1->enumerate(e1, &t1, &value)) + default: + continue; + case AUTH_RULE_RSA_STRENGTH: + key_type = "RSA"; + break; + case AUTH_RULE_ECDSA_STRENGTH: + key_type = "ECDSA"; + break; + case AUTH_RULE_BLISS_STRENGTH: + key_type = "BLISS"; + break; + } + success = FALSE; + e1 = constraints->create_enumerator(constraints); + while (e1->enumerate(e1, &t1, &value)) + { + if (t1 == t2 && (uintptr_t)value <= strength) { - if (t1 == t2 && (uintptr_t)value <= strength) - { - success = TRUE; - break; - } + success = TRUE; + break; } - e1->destroy(e1); - if (!success) + } + e1->destroy(e1); + if (!success) + { + if (log_error) { - if (log_error) - { - DBG1(DBG_CFG, "%s-%d signatures not acceptable", - t2 == AUTH_RULE_RSA_STRENGTH ? "RSA" : "ECDSA", - strength); - } - break; + DBG1(DBG_CFG, "%s-%d signatures not acceptable", + key_type, strength); } + break; } } e2->destroy(e2); @@ -891,6 +909,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_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: { add(this, type, (uintptr_t)value); @@ -1060,6 +1079,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_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: clone->add(clone, type, (uintptr_t)value); break; diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h index 95b36d706..53f1b3805 100644 --- a/src/libstrongswan/credentials/auth_cfg.h +++ b/src/libstrongswan/credentials/auth_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2007-2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -102,6 +102,8 @@ enum auth_rule_t { AUTH_RULE_RSA_STRENGTH, /** required ECDSA public key strength, u_int in bits */ AUTH_RULE_ECDSA_STRENGTH, + /** required BLISS public key strength, u_int in bits */ + AUTH_RULE_BLISS_STRENGTH, /** required signature scheme, signature_scheme_t */ AUTH_RULE_SIGNATURE_SCHEME, /** certificatePolicy constraint, numerical OID as char* */ diff --git a/src/libstrongswan/credentials/cred_encoding.h b/src/libstrongswan/credentials/cred_encoding.h index a6c9c30af..b4d1f4c3c 100644 --- a/src/libstrongswan/credentials/cred_encoding.h +++ b/src/libstrongswan/credentials/cred_encoding.h @@ -144,6 +144,10 @@ enum cred_encoding_part_t { CRED_PART_PKCS10_ASN1_DER, /** a PGP encoded certificate */ CRED_PART_PGP_CERT, + /** a DER encoded BLISS public key */ + CRED_PART_BLISS_PUB_ASN1_DER, + /** a DER encoded BLISS private key */ + CRED_PART_BLISS_PRIV_ASN1_DER, CRED_PART_END, }; diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index b0c8e48ba..371e6404d 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -698,6 +698,9 @@ static void get_key_strength(certificate_t *cert, auth_cfg_t *auth) case KEY_ECDSA: auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength); break; + case KEY_BLISS: + auth->add(auth, AUTH_RULE_BLISS_STRENGTH, strength); + break; default: break; } diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c index 37bba77d1..bd5915e60 100644 --- a/src/libstrongswan/credentials/keys/public_key.c +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -1,6 +1,8 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -17,14 +19,15 @@ #include "public_key.h" -ENUM(key_type_names, KEY_ANY, KEY_DSA, +ENUM(key_type_names, KEY_ANY, KEY_BLISS, "ANY", "RSA", "ECDSA", - "DSA" + "DSA", + "BLISS" ); -ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521, +ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_BLISS_WITH_SHA512, "UNKNOWN", "RSA_EMSA_PKCS1_NULL", "RSA_EMSA_PKCS1_MD5", @@ -41,6 +44,9 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521, "ECDSA-256", "ECDSA-384", "ECDSA-521", + "BLISS_WITH_SHA256", + "BLISS_WITH_SHA384", + "BLISS_WITH_SHA512", ); ENUM(encryption_scheme_names, ENCRYPT_UNKNOWN, ENCRYPT_RSA_OAEP_SHA512, @@ -130,8 +136,158 @@ signature_scheme_t signature_scheme_from_oid(int oid) return SIGN_ECDSA_WITH_SHA384_DER; case OID_ECDSA_WITH_SHA512: return SIGN_ECDSA_WITH_SHA512_DER; - default: - return SIGN_UNKNOWN; + case OID_BLISS_PUBLICKEY: + case OID_BLISS_WITH_SHA512: + return SIGN_BLISS_WITH_SHA512; + case OID_BLISS_WITH_SHA256: + return SIGN_BLISS_WITH_SHA256; + case OID_BLISS_WITH_SHA384: + return SIGN_BLISS_WITH_SHA384; } + return SIGN_UNKNOWN; } +/* + * Defined in header. + */ +int signature_scheme_to_oid(signature_scheme_t scheme) +{ + switch (scheme) + { + case SIGN_UNKNOWN: + case SIGN_RSA_EMSA_PKCS1_NULL: + case SIGN_ECDSA_WITH_NULL: + case SIGN_ECDSA_256: + case SIGN_ECDSA_384: + case SIGN_ECDSA_521: + break; + case SIGN_RSA_EMSA_PKCS1_MD5: + return OID_MD5_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA1: + return OID_SHA1_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA224: + return OID_SHA224_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA256: + return OID_SHA256_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA384: + return OID_SHA384_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA512: + return OID_SHA512_WITH_RSA; + case SIGN_ECDSA_WITH_SHA1_DER: + return OID_ECDSA_WITH_SHA1; + case SIGN_ECDSA_WITH_SHA256_DER: + return OID_ECDSA_WITH_SHA256; + case SIGN_ECDSA_WITH_SHA384_DER: + return OID_ECDSA_WITH_SHA384; + case SIGN_ECDSA_WITH_SHA512_DER: + return OID_ECDSA_WITH_SHA512; + case SIGN_BLISS_WITH_SHA256: + return OID_BLISS_WITH_SHA256; + case SIGN_BLISS_WITH_SHA384: + return OID_BLISS_WITH_SHA384; + case SIGN_BLISS_WITH_SHA512: + return OID_BLISS_WITH_SHA512; + } + return OID_UNKNOWN; +} + +/** + * Map for signature schemes to the key type and maximum key size allowed. + * We only cover schemes with hash algorithms supported by IKEv2 signature + * authentication. + */ +static struct { + signature_scheme_t scheme; + key_type_t type; + int max_keysize; +} scheme_map[] = { + { SIGN_RSA_EMSA_PKCS1_SHA256, KEY_RSA, 3072 }, + { SIGN_RSA_EMSA_PKCS1_SHA384, KEY_RSA, 7680 }, + { SIGN_RSA_EMSA_PKCS1_SHA512, KEY_RSA, 0 }, + { SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, 256 }, + { SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, 384 }, + { SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, 0 }, + { SIGN_BLISS_WITH_SHA256, KEY_BLISS, 128 }, + { SIGN_BLISS_WITH_SHA384, KEY_BLISS, 192 }, + { SIGN_BLISS_WITH_SHA512, KEY_BLISS, 0 }, +}; + +/** + * Private data for signature scheme enumerator + */ +typedef struct { + enumerator_t public; + int index; + key_type_t type; + int size; +} private_enumerator_t; + +METHOD(enumerator_t, signature_schemes_enumerate, bool, + private_enumerator_t *this, signature_scheme_t *scheme) +{ + while (++this->index < countof(scheme_map)) + { + if (this->type == scheme_map[this->index].type && + (this->size <= scheme_map[this->index].max_keysize || + !scheme_map[this->index].max_keysize)) + { + *scheme = scheme_map[this->index].scheme; + return TRUE; + } + } + return FALSE; +} + +/* + * Defined in header. + */ +enumerator_t *signature_schemes_for_key(key_type_t type, int size) +{ + private_enumerator_t *this; + + INIT(this, + .public = { + .enumerate = (void*)_signature_schemes_enumerate, + .destroy = (void*)free, + }, + .index = -1, + .type = type, + .size = size, + ); + + return &this->public; +} + +/* + * Defined in header. + */ +key_type_t key_type_from_signature_scheme(signature_scheme_t scheme) +{ + switch (scheme) + { + case SIGN_UNKNOWN: + break; + case SIGN_RSA_EMSA_PKCS1_NULL: + case SIGN_RSA_EMSA_PKCS1_MD5: + case SIGN_RSA_EMSA_PKCS1_SHA1: + case SIGN_RSA_EMSA_PKCS1_SHA224: + case SIGN_RSA_EMSA_PKCS1_SHA256: + case SIGN_RSA_EMSA_PKCS1_SHA384: + case SIGN_RSA_EMSA_PKCS1_SHA512: + return KEY_RSA; + case SIGN_ECDSA_WITH_SHA1_DER: + case SIGN_ECDSA_WITH_SHA256_DER: + case SIGN_ECDSA_WITH_SHA384_DER: + case SIGN_ECDSA_WITH_SHA512_DER: + case SIGN_ECDSA_WITH_NULL: + case SIGN_ECDSA_256: + case SIGN_ECDSA_384: + case SIGN_ECDSA_521: + return KEY_ECDSA; + case SIGN_BLISS_WITH_SHA256: + case SIGN_BLISS_WITH_SHA384: + case SIGN_BLISS_WITH_SHA512: + return KEY_BLISS; + } + return KEY_ANY; +} diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h index 2afcf8325..66e98b294 100644 --- a/src/libstrongswan/credentials/keys/public_key.h +++ b/src/libstrongswan/credentials/keys/public_key.h @@ -1,6 +1,8 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -42,6 +44,8 @@ enum key_type_t { KEY_ECDSA = 2, /** DSA */ KEY_DSA = 3, + /** BLISS */ + KEY_BLISS = 4, /** ElGamal, ... */ }; @@ -90,6 +94,12 @@ enum signature_scheme_t { SIGN_ECDSA_384, /** ECDSA on the P-521 curve with SHA-512 as in RFC 4754 */ SIGN_ECDSA_521, + /** BLISS with SHA-256 */ + SIGN_BLISS_WITH_SHA256, + /** BLISS with SHA-384 */ + SIGN_BLISS_WITH_SHA384, + /** BLISS with SHA-512 */ + SIGN_BLISS_WITH_SHA512, }; /** @@ -234,8 +244,35 @@ bool public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint); * Conversion of ASN.1 signature or hash OID to signature scheme. * * @param oid ASN.1 OID - * @return signature_scheme, SIGN_UNKNOWN if OID is unsupported + * @return signature scheme, SIGN_UNKNOWN if OID is unsupported */ signature_scheme_t signature_scheme_from_oid(int oid); +/** + * Conversion of signature scheme to ASN.1 signature OID. + * + * @param scheme signature scheme + * @return ASN.1 OID, OID_UNKNOWN if not supported + */ +int signature_scheme_to_oid(signature_scheme_t scheme); + +/** + * Enumerate signature schemes that are appropriate for a key of the given type + * and size|strength. + * + * @param type type of the key + * @param size size or strength of the key + * @return enumerator over signature_scheme_t (increasing strength) + */ +enumerator_t *signature_schemes_for_key(key_type_t type, int size); + +/** + * Determine the type of key associated with a given signature scheme. + * + * @param scheme signature scheme + * @return key type (could be KEY_ANY) + */ +key_type_t key_type_from_signature_scheme(signature_scheme_t scheme); + + #endif /** PUBLIC_KEY_H_ @}*/ diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c index 563f4bdd5..60720dc57 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.c +++ b/src/libstrongswan/credentials/sets/cert_cache.c @@ -143,6 +143,7 @@ METHOD(cert_cache_t, issued_by, bool, private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer, signature_scheme_t *schemep) { + certificate_t *cached_issuer = NULL; relation_t *found = NULL, *current; signature_scheme_t scheme; int i; @@ -154,39 +155,41 @@ METHOD(cert_cache_t, issued_by, bool, current->lock->read_lock(current->lock); if (current->subject) { - /* check for equal issuer */ if (issuer->equals(issuer, current->issuer)) { - /* reuse issuer instance in cache() */ - issuer = current->issuer; if (subject->equals(subject, current->subject)) { - /* write hit counter is not locked, but not critical */ current->hits++; - found = current;; + found = current; if (schemep) { *schemep = current->scheme; } } + else if (!cached_issuer) + { + cached_issuer = current->issuer->get_ref(current->issuer); + } } } current->lock->unlock(current->lock); if (found) { + DESTROY_IF(cached_issuer); return TRUE; } } - /* no cache hit, check and cache signature */ if (subject->issued_by(subject, issuer, &scheme)) { - cache(this, subject, issuer, scheme); + cache(this, subject, cached_issuer ?: issuer, scheme); if (schemep) { *schemep = scheme; } + DESTROY_IF(cached_issuer); return TRUE; } + DESTROY_IF(cached_issuer); return FALSE; } diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c index d8f568d36..7ad011b5e 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.c +++ b/src/libstrongswan/credentials/sets/mem_cred.c @@ -192,6 +192,24 @@ METHOD(mem_cred_t, add_cert_ref, certificate_t*, return add_cert_internal(this, trusted, cert); } +METHOD(mem_cred_t, get_cert_ref, certificate_t*, + private_mem_cred_t *this, certificate_t *cert) +{ + certificate_t *cached; + + this->lock->write_lock(this->lock); + if (this->untrusted->find_first(this->untrusted, + (linked_list_match_t)certificate_equals, + (void**)&cached, cert) == SUCCESS) + { + cert->destroy(cert); + cert = cached->get_ref(cached); + } + this->lock->unlock(this->lock); + + return cert; +} + METHOD(mem_cred_t, add_crl, bool, private_mem_cred_t *this, crl_t *crl) { @@ -736,6 +754,7 @@ mem_cred_t *mem_cred_create() }, .add_cert = _add_cert, .add_cert_ref = _add_cert_ref, + .get_cert_ref = _get_cert_ref, .add_crl = _add_crl, .add_key = _add_key, .add_shared = _add_shared, diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h index d0dd51da1..3ce815abc 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.h +++ b/src/libstrongswan/credentials/sets/mem_cred.h @@ -59,6 +59,18 @@ struct mem_cred_t { certificate_t *cert); /** + * Get an existing reference to the same certificate. + * + * Searches for the same certficate in the set, and returns a reference + * to it, destroying the passed certificate. If the passed certificate + * is not found, it is just returned. + * + * @param cert certificate to look up + * @return the same certificate, potentially different instance + */ + certificate_t* (*get_cert_ref)(mem_cred_t *this, certificate_t *cert); + + /** * Add an X.509 CRL to the credential set. * * @param crl CRL, gets owned by set |