diff options
Diffstat (limited to 'src/libstrongswan/crypto/hashers')
-rw-r--r-- | src/libstrongswan/crypto/hashers/hash_algorithm_set.c | 113 | ||||
-rw-r--r-- | src/libstrongswan/crypto/hashers/hash_algorithm_set.h | 76 | ||||
-rw-r--r-- | src/libstrongswan/crypto/hashers/hasher.c | 102 | ||||
-rw-r--r-- | src/libstrongswan/crypto/hashers/hasher.h | 40 |
4 files changed, 304 insertions, 27 deletions
diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.c b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c new file mode 100644 index 000000000..93b67cb13 --- /dev/null +++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2015 Tobias Brunner + * 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "hash_algorithm_set.h" + +#include <collections/array.h> + +typedef struct private_hash_algorithm_set_t private_hash_algorithm_set_t; + +struct private_hash_algorithm_set_t { + + /** + * Public interface + */ + hash_algorithm_set_t public; + + /** + * Algorithms contained in the set + */ + array_t *algorithms; +}; + +/** + * Sort hash algorithms + */ +static int hash_sort(const void *a, const void *b, void *user) +{ + const hash_algorithm_t *ha = a, *hb = b; + return *ha - *hb; +} + +/** + * Find a hash algorithm + */ +static int hash_find(const void *a, const void *b) +{ + return hash_sort(a, b, NULL); +} + +METHOD(hash_algorithm_set_t, contains, bool, + private_hash_algorithm_set_t *this, hash_algorithm_t hash) +{ + return array_bsearch(this->algorithms, &hash, hash_find, NULL) != -1; +} + +METHOD(hash_algorithm_set_t, add, void, + private_hash_algorithm_set_t *this, hash_algorithm_t hash) +{ + if (!contains(this, hash)) + { + array_insert(this->algorithms, ARRAY_TAIL, &hash); + array_sort(this->algorithms, hash_sort, NULL); + } +} + +METHOD(hash_algorithm_set_t, count, int, + private_hash_algorithm_set_t *this) +{ + return array_count(this->algorithms); +} + +static bool hash_filter(void *data, void **in, hash_algorithm_t *out) +{ + *out = **(hash_algorithm_t**)in; + return TRUE; +} + +METHOD(hash_algorithm_set_t, create_enumerator, enumerator_t*, + private_hash_algorithm_set_t *this) +{ + return enumerator_create_filter(array_create_enumerator(this->algorithms), + (void*)hash_filter, NULL, NULL); +} + +METHOD(hash_algorithm_set_t, destroy, void, + private_hash_algorithm_set_t *this) +{ + array_destroy(this->algorithms); + free(this); +} + +/** + * Described in header + */ +hash_algorithm_set_t *hash_algorithm_set_create() +{ + private_hash_algorithm_set_t *this; + + INIT(this, + .public = { + .add = _add, + .contains = _contains, + .count = _count, + .create_enumerator = _create_enumerator, + .destroy = _destroy, + }, + .algorithms = array_create(sizeof(hash_algorithm_t), 0), + ); + + return &this->public; +}
\ No newline at end of file diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.h b/src/libstrongswan/crypto/hashers/hash_algorithm_set.h new file mode 100644 index 000000000..00e90cc2e --- /dev/null +++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015 Tobias Brunner + * 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup hash_algorithm_set hash_algorithm_set + * @{ @ingroup crypto + */ + +#ifndef HASH_ALGORITHM_SET_H_ +#define HASH_ALGORITHM_SET_H_ + +typedef struct hash_algorithm_set_t hash_algorithm_set_t; + +#include <library.h> +#include <crypto/hashers/hasher.h> + +/** + * A set of hash algorithms + */ +struct hash_algorithm_set_t { + + /** + * Add the given algorithm to the set. + * + * @param alg hash algorithm + */ + void (*add)(hash_algorithm_set_t *this, hash_algorithm_t alg); + + /** + * Check if the given algorithm is contained in the set. + * + * @param alg hash algorithm + * @return TRUE if contained in set + */ + bool (*contains)(hash_algorithm_set_t *this, hash_algorithm_t alg); + + /** + * Number of hash algorithms contained in the set. + * + * @return number of algorithms + */ + int (*count)(hash_algorithm_set_t *this); + + /** + * Enumerate the algorithms contained in the set. + * + * @return enumerator over hash_algorithm_t (sorted by identifier) + */ + enumerator_t *(*create_enumerator)(hash_algorithm_set_t *this); + + /** + * Destroy a hash_algorithm_set_t instance + */ + void (*destroy)(hash_algorithm_set_t *this); +}; + +/** + * Create a set of hash algorithms. + * + * @return hash_algorithm_set_t instance + */ +hash_algorithm_set_t *hash_algorithm_set_create(); + +#endif /** HASH_ALGORITHM_SET_H_ @}*/ diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c index 13cbb5a59..38eebea9c 100644 --- a/src/libstrongswan/crypto/hashers/hasher.c +++ b/src/libstrongswan/crypto/hashers/hasher.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -19,29 +19,31 @@ #include <asn1/oid.h> -ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512, +ENUM_BEGIN(hash_algorithm_names, HASH_SHA1, HASH_SHA512, + "HASH_SHA1", + "HASH_SHA256", + "HASH_SHA384", + "HASH_SHA512"); +ENUM_NEXT(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA224, HASH_SHA512, "HASH_UNKNOWN", "HASH_MD2", "HASH_MD4", "HASH_MD5", - "HASH_SHA1", - "HASH_SHA224", - "HASH_SHA256", - "HASH_SHA384", - "HASH_SHA512" -); + "HASH_SHA224"); +ENUM_END(hash_algorithm_names, HASH_SHA224); -ENUM(hash_algorithm_short_names, HASH_UNKNOWN, HASH_SHA512, +ENUM_BEGIN(hash_algorithm_short_names, HASH_SHA1, HASH_SHA512, + "sha1", + "sha256", + "sha384", + "sha512"); +ENUM_NEXT(hash_algorithm_short_names, HASH_UNKNOWN, HASH_SHA224, HASH_SHA512, "unknown", "md2", "md4", "md5", - "sha1", - "sha224", - "sha256", - "sha384", - "sha512" -); + "sha224"); +ENUM_END(hash_algorithm_short_names, HASH_SHA224); /* * Described in header. @@ -249,6 +251,28 @@ integrity_algorithm_t hasher_algorithm_to_integrity(hash_algorithm_t alg, /* * Described in header. */ +bool hasher_algorithm_for_ikev2(hash_algorithm_t alg) +{ + switch (alg) + { + case HASH_SHA1: + case HASH_SHA256: + case HASH_SHA384: + case HASH_SHA512: + return TRUE; + case HASH_UNKNOWN: + case HASH_MD2: + case HASH_MD4: + case HASH_MD5: + case HASH_SHA224: + break; + } + return FALSE; +} + +/* + * Described in header. + */ int hasher_algorithm_to_oid(hash_algorithm_t alg) { int oid; @@ -323,8 +347,56 @@ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key) default: return OID_UNKNOWN; } + case KEY_BLISS: + switch (alg) + { + case HASH_SHA256: + return OID_BLISS_WITH_SHA256; + case HASH_SHA384: + return OID_BLISS_WITH_SHA384; + case HASH_SHA512: + return OID_BLISS_WITH_SHA512; + default: + return OID_UNKNOWN; + } default: return OID_UNKNOWN; } } +/* + * Defined in header. + */ +hash_algorithm_t hasher_from_signature_scheme(signature_scheme_t scheme) +{ + switch (scheme) + { + case SIGN_UNKNOWN: + case SIGN_RSA_EMSA_PKCS1_NULL: + case SIGN_ECDSA_WITH_NULL: + break; + case SIGN_RSA_EMSA_PKCS1_MD5: + return HASH_MD5; + case SIGN_RSA_EMSA_PKCS1_SHA1: + case SIGN_ECDSA_WITH_SHA1_DER: + return HASH_SHA1; + case SIGN_RSA_EMSA_PKCS1_SHA224: + return HASH_SHA224; + case SIGN_RSA_EMSA_PKCS1_SHA256: + case SIGN_ECDSA_WITH_SHA256_DER: + case SIGN_ECDSA_256: + case SIGN_BLISS_WITH_SHA256: + return HASH_SHA256; + case SIGN_RSA_EMSA_PKCS1_SHA384: + case SIGN_ECDSA_WITH_SHA384_DER: + case SIGN_ECDSA_384: + case SIGN_BLISS_WITH_SHA384: + return HASH_SHA384; + case SIGN_RSA_EMSA_PKCS1_SHA512: + case SIGN_ECDSA_WITH_SHA512_DER: + case SIGN_ECDSA_521: + case SIGN_BLISS_WITH_SHA512: + return HASH_SHA512; + } + return HASH_UNKNOWN; +} diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h index 37ef0b6ab..772586308 100644 --- a/src/libstrongswan/crypto/hashers/hasher.h +++ b/src/libstrongswan/crypto/hashers/hasher.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -32,19 +32,19 @@ typedef struct hasher_t hasher_t; #include <credentials/keys/public_key.h> /** - * Algorithms to use for hashing. + * Hash algorithms as defined for IKEv2 by RFC 7427 */ enum hash_algorithm_t { - /** not specified hash function */ - HASH_UNKNOWN = 0, - HASH_MD2 = 1, - HASH_MD4 = 2, - HASH_MD5 = 3, - HASH_SHA1 = 4, - HASH_SHA224 = 5, - HASH_SHA256 = 6, - HASH_SHA384 = 7, - HASH_SHA512 = 8 + HASH_SHA1 = 1, + HASH_SHA256 = 2, + HASH_SHA384 = 3, + HASH_SHA512 = 4, + /* use private use range for algorithms not defined/permitted by RFC 7427 */ + HASH_UNKNOWN = 1024, + HASH_MD2 = 1025, + HASH_MD4 = 1026, + HASH_MD5 = 1027, + HASH_SHA224 = 1028, }; #define HASH_SIZE_MD2 16 @@ -163,6 +163,14 @@ integrity_algorithm_t hasher_algorithm_to_integrity(hash_algorithm_t alg, size_t length); /** + * Check if the given algorithm may be used for IKEv2 signature authentication. + * + * @param alg hash algorithm + * @return TRUE if algorithm may be used, FALSE otherwise + */ +bool hasher_algorithm_for_ikev2(hash_algorithm_t alg); + +/** * Conversion of hash algorithm into ASN.1 OID. * * @param alg hash algorithm @@ -179,4 +187,12 @@ int hasher_algorithm_to_oid(hash_algorithm_t alg); */ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key); +/** + * Determine the hash algorithm associated with a given signature scheme. + * + * @param scheme signature scheme + * @return hash algorithm (could be HASH_UNKNOWN) + */ +hash_algorithm_t hasher_from_signature_scheme(signature_scheme_t scheme); + #endif /** HASHER_H_ @}*/ |