diff options
Diffstat (limited to 'src/libcharon/sa/authenticators')
-rw-r--r-- | src/libcharon/sa/authenticators/authenticator.c | 98 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/authenticator.h | 166 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/eap/eap_manager.c | 162 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/eap/eap_manager.h | 82 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/eap/eap_method.c | 42 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/eap/eap_method.h | 177 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/eap_authenticator.c | 698 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/eap_authenticator.h | 102 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/psk_authenticator.c | 204 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/psk_authenticator.h | 65 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/pubkey_authenticator.c | 268 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/pubkey_authenticator.h | 66 |
12 files changed, 0 insertions, 2130 deletions
diff --git a/src/libcharon/sa/authenticators/authenticator.c b/src/libcharon/sa/authenticators/authenticator.c deleted file mode 100644 index 9ffe661cc..000000000 --- a/src/libcharon/sa/authenticators/authenticator.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2006-2009 Martin Willi - * Copyright (C) 2008 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 <string.h> - -#include "authenticator.h" - -#include <sa/authenticators/pubkey_authenticator.h> -#include <sa/authenticators/psk_authenticator.h> -#include <sa/authenticators/eap_authenticator.h> -#include <encoding/payloads/auth_payload.h> - - -ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS, - "RSA signature", - "pre-shared key", - "DSS signature"); -ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_GSPM, AUTH_DSS, - "ECDSA-256 signature", - "ECDSA-384 signature", - "ECDSA-521 signature", - "secure password method"); -ENUM_END(auth_method_names, AUTH_GSPM); - -/** - * Described in header. - */ -authenticator_t *authenticator_create_builder(ike_sa_t *ike_sa, auth_cfg_t *cfg, - chunk_t received_nonce, chunk_t sent_nonce, - chunk_t received_init, chunk_t sent_init, - char reserved[3]) -{ - switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS)) - { - case AUTH_CLASS_ANY: - /* defaults to PUBKEY */ - case AUTH_CLASS_PUBKEY: - return (authenticator_t*)pubkey_authenticator_create_builder(ike_sa, - received_nonce, sent_init, reserved); - case AUTH_CLASS_PSK: - return (authenticator_t*)psk_authenticator_create_builder(ike_sa, - received_nonce, sent_init, reserved); - case AUTH_CLASS_EAP: - return (authenticator_t*)eap_authenticator_create_builder(ike_sa, - received_nonce, sent_nonce, - received_init, sent_init, reserved); - default: - return NULL; - } -} - -/** - * Described in header. - */ -authenticator_t *authenticator_create_verifier( - ike_sa_t *ike_sa, message_t *message, - chunk_t received_nonce, chunk_t sent_nonce, - chunk_t received_init, chunk_t sent_init, - char reserved[3]) -{ - auth_payload_t *auth_payload; - - auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION); - if (auth_payload == NULL) - { - return (authenticator_t*)eap_authenticator_create_verifier(ike_sa, - received_nonce, sent_nonce, - received_init, sent_init, reserved); - } - switch (auth_payload->get_auth_method(auth_payload)) - { - case AUTH_RSA: - case AUTH_ECDSA_256: - case AUTH_ECDSA_384: - case AUTH_ECDSA_521: - return (authenticator_t*)pubkey_authenticator_create_verifier(ike_sa, - sent_nonce, received_init, reserved); - case AUTH_PSK: - return (authenticator_t*)psk_authenticator_create_verifier(ike_sa, - sent_nonce, received_init, reserved); - default: - return NULL; - } -} - diff --git a/src/libcharon/sa/authenticators/authenticator.h b/src/libcharon/sa/authenticators/authenticator.h deleted file mode 100644 index 5042e4a73..000000000 --- a/src/libcharon/sa/authenticators/authenticator.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2005-2009 Martin Willi - * Copyright (C) 2008 Tobias Brunner - * Copyright (C) 2005 Jan Hutter - * 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 authenticator authenticator - * @{ @ingroup authenticators - */ - -#ifndef AUTHENTICATOR_H_ -#define AUTHENTICATOR_H_ - -typedef enum auth_method_t auth_method_t; -typedef struct authenticator_t authenticator_t; - -#include <library.h> -#include <credentials/auth_cfg.h> -#include <sa/ike_sa.h> - -/** - * Method to use for authentication, as defined in IKEv2. - */ -enum auth_method_t { - /** - * Computed as specified in section 2.15 of RFC using - * an RSA private key over a PKCS#1 padded hash. - */ - AUTH_RSA = 1, - - /** - * Computed as specified in section 2.15 of RFC using the - * shared key associated with the identity in the ID payload - * and the negotiated prf function - */ - AUTH_PSK = 2, - - /** - * Computed as specified in section 2.15 of RFC using a - * DSS private key over a SHA-1 hash. - */ - AUTH_DSS = 3, - - /** - * ECDSA with SHA-256 on the P-256 curve as specified in RFC 4754 - */ - AUTH_ECDSA_256 = 9, - - /** - * ECDSA with SHA-384 on the P-384 curve as specified in RFC 4754 - */ - AUTH_ECDSA_384 = 10, - - /** - * ECDSA with SHA-512 on the P-521 curve as specified in RFC 4754 - */ - AUTH_ECDSA_521 = 11, - - /** - * Generic Secure Password Authentication Method as specified in RFC 6467 - */ - AUTH_GSPM = 12, - -}; - -/** - * enum names for auth_method_t. - */ -extern enum_name_t *auth_method_names; - -/** - * Authenticator interface implemented by the various authenticators. - * - * An authenticator implementation handles AUTH and EAP payloads. Received - * messages are passed to the process() method, to send authentication data - * the message is passed to the build() method. - */ -struct authenticator_t { - - /** - * Process an incoming message using the authenticator. - * - * @param message message containing authentication payloads - * @return - * - SUCCESS if authentication successful - * - FAILED if authentication failed - * - NEED_MORE if another exchange required - */ - status_t (*process)(authenticator_t *this, message_t *message); - - /** - * Attach authentication data to an outgoing message. - * - * @param message message to add authentication data to - * @return - * - SUCCESS if authentication successful - * - FAILED if authentication failed - * - NEED_MORE if another exchange required - */ - status_t (*build)(authenticator_t *this, message_t *message); - - /** - * Check if the authenticator is capable of mutual authentication. - * - * Some authenticator authenticate both peers, e.g. EAP. To support - * mutual authentication with only a single authenticator (EAP-only - * authentication), it must be mutual. This method is invoked in ike_auth - * to check if the given authenticator is capable of doing so. - */ - bool (*is_mutual)(authenticator_t *this); - - /** - * Destroy authenticator instance. - */ - void (*destroy) (authenticator_t *this); -}; - -/** - * Create an authenticator to build signatures. - * - * @param ike_sa associated ike_sa - * @param cfg authentication configuration - * @param received_nonce nonce received in IKE_SA_INIT - * @param sent_nonce nonce sent in IKE_SA_INIT - * @param received_init received IKE_SA_INIT message data - * @param sent_init sent IKE_SA_INIT message data - * @param reserved reserved bytes of the ID payload - * @return authenticator, NULL if not supported - */ -authenticator_t *authenticator_create_builder( - ike_sa_t *ike_sa, auth_cfg_t *cfg, - chunk_t received_nonce, chunk_t sent_nonce, - chunk_t received_init, chunk_t sent_init, - char reserved[3]); - -/** - * Create an authenticator to verify signatures. - * - * @param ike_sa associated ike_sa - * @param message message containing authentication data - * @param received_nonce nonce received in IKE_SA_INIT - * @param sent_nonce nonce sent in IKE_SA_INIT - * @param received_init received IKE_SA_INIT message data - * @param sent_init sent IKE_SA_INIT message data - * @param reserved reserved bytes of the ID payload - * @return authenticator, NULL if not supported - */ -authenticator_t *authenticator_create_verifier( - ike_sa_t *ike_sa, message_t *message, - chunk_t received_nonce, chunk_t sent_nonce, - chunk_t received_init, chunk_t sent_init, - char reserved[3]); - -#endif /** AUTHENTICATOR_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/eap_manager.c b/src/libcharon/sa/authenticators/eap/eap_manager.c deleted file mode 100644 index bc2c4a617..000000000 --- a/src/libcharon/sa/authenticators/eap/eap_manager.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2008 Martin Willi - * 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 "eap_manager.h" - -#include <utils/linked_list.h> -#include <threading/rwlock.h> - -typedef struct private_eap_manager_t private_eap_manager_t; -typedef struct eap_entry_t eap_entry_t; - -/** - * EAP constructor entry - */ -struct eap_entry_t { - - /** - * EAP method type, vendor specific if vendor is set - */ - eap_type_t type; - - /** - * vendor ID, 0 for default EAP methods - */ - u_int32_t vendor; - - /** - * Role of the method returned by the constructor, EAP_SERVER or EAP_PEER - */ - eap_role_t role; - - /** - * constructor function to create instance - */ - eap_constructor_t constructor; -}; - -/** - * private data of eap_manager - */ -struct private_eap_manager_t { - - /** - * public functions - */ - eap_manager_t public; - - /** - * list of eap_entry_t's - */ - linked_list_t *methods; - - /** - * rwlock to lock methods - */ - rwlock_t *lock; -}; - -METHOD(eap_manager_t, add_method, void, - private_eap_manager_t *this, eap_type_t type, u_int32_t vendor, - eap_role_t role, eap_constructor_t constructor) -{ - eap_entry_t *entry = malloc_thing(eap_entry_t); - - entry->type = type; - entry->vendor = vendor; - entry->role = role; - entry->constructor = constructor; - - this->lock->write_lock(this->lock); - this->methods->insert_last(this->methods, entry); - this->lock->unlock(this->lock); -} - -METHOD(eap_manager_t, remove_method, void, - private_eap_manager_t *this, eap_constructor_t constructor) -{ - enumerator_t *enumerator; - eap_entry_t *entry; - - this->lock->write_lock(this->lock); - enumerator = this->methods->create_enumerator(this->methods); - while (enumerator->enumerate(enumerator, &entry)) - { - if (constructor == entry->constructor) - { - this->methods->remove_at(this->methods, enumerator); - free(entry); - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); -} - -METHOD(eap_manager_t, create_instance, eap_method_t*, - private_eap_manager_t *this, eap_type_t type, u_int32_t vendor, - eap_role_t role, identification_t *server, identification_t *peer) -{ - enumerator_t *enumerator; - eap_entry_t *entry; - eap_method_t *method = NULL; - - this->lock->read_lock(this->lock); - enumerator = this->methods->create_enumerator(this->methods); - while (enumerator->enumerate(enumerator, &entry)) - { - if (type == entry->type && vendor == entry->vendor && - role == entry->role) - { - method = entry->constructor(server, peer); - if (method) - { - break; - } - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return method; -} - -METHOD(eap_manager_t, destroy, void, - private_eap_manager_t *this) -{ - this->methods->destroy_function(this->methods, free); - this->lock->destroy(this->lock); - free(this); -} - -/* - * See header - */ -eap_manager_t *eap_manager_create() -{ - private_eap_manager_t *this; - - INIT(this, - .public = { - .add_method = _add_method, - .remove_method = _remove_method, - .create_instance = _create_instance, - .destroy = _destroy, - }, - .methods = linked_list_create(), - .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), - ); - - return &this->public; -} - diff --git a/src/libcharon/sa/authenticators/eap/eap_manager.h b/src/libcharon/sa/authenticators/eap/eap_manager.h deleted file mode 100644 index 0333fb6da..000000000 --- a/src/libcharon/sa/authenticators/eap/eap_manager.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2008 Martin Willi - * 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 eap_manager eap_manager - * @{ @ingroup eap - */ - -#ifndef EAP_MANAGER_H_ -#define EAP_MANAGER_H_ - -#include <sa/authenticators/eap/eap_method.h> - -typedef struct eap_manager_t eap_manager_t; - -/** - * The EAP manager manages all EAP implementations and creates instances. - * - * A plugin registers it's implemented EAP method at the manager by - * providing type and a contructor function. The manager then instanciates - * eap_method_t instances through the provided constructor to handle - * EAP authentication. - */ -struct eap_manager_t { - - /** - * Register a EAP method implementation. - * - * @param method vendor specific method, if vendor != 0 - * @param vendor vendor ID, 0 for non-vendor (default) EAP methods - * @param role EAP role of the registered method - * @param constructor constructor function, returns an eap_method_t - */ - void (*add_method)(eap_manager_t *this, eap_type_t type, u_int32_t vendor, - eap_role_t role, eap_constructor_t constructor); - - /** - * Unregister a EAP method implementation using it's constructor. - * - * @param constructor constructor function to remove, as added in add_method - */ - void (*remove_method)(eap_manager_t *this, eap_constructor_t constructor); - - /** - * Create a new EAP method instance. - * - * @param type type of the EAP method - * @param vendor vendor ID, 0 for non-vendor (default) EAP methods - * @param role role of EAP method, either EAP_SERVER or EAP_PEER - * @param server identity of the server - * @param peer identity of the peer (client) - * @return EAP method instance, NULL if no constructor found - */ - eap_method_t* (*create_instance)(eap_manager_t *this, eap_type_t type, - u_int32_t vendor, eap_role_t role, - identification_t *server, - identification_t *peer); - - /** - * Destroy a eap_manager instance. - */ - void (*destroy)(eap_manager_t *this); -}; - -/** - * Create a eap_manager instance. - */ -eap_manager_t *eap_manager_create(); - -#endif /** EAP_MANAGER_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/eap_method.c b/src/libcharon/sa/authenticators/eap/eap_method.c deleted file mode 100644 index a05e8c59a..000000000 --- a/src/libcharon/sa/authenticators/eap/eap_method.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2006 Martin Willi - * 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 "eap_method.h" - -#include <daemon.h> - -ENUM(eap_role_names, EAP_SERVER, EAP_PEER, - "EAP_SERVER", - "EAP_PEER", -); - -/** - * See header - */ -bool eap_method_register(plugin_t *plugin, plugin_feature_t *feature, - bool reg, void *data) -{ - if (reg) - { - charon->eap->add_method(charon->eap, feature->arg.eap, 0, - feature->type == FEATURE_EAP_SERVER ? EAP_SERVER : EAP_PEER, - (eap_constructor_t)data); - } - else - { - charon->eap->remove_method(charon->eap, (eap_constructor_t)data); - } - return TRUE; -} diff --git a/src/libcharon/sa/authenticators/eap/eap_method.h b/src/libcharon/sa/authenticators/eap/eap_method.h deleted file mode 100644 index 6242a5a6e..000000000 --- a/src/libcharon/sa/authenticators/eap/eap_method.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2006 Martin Willi - * 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 eap_method eap_method - * @{ @ingroup eap - */ - -#ifndef EAP_METHOD_H_ -#define EAP_METHOD_H_ - -typedef struct eap_method_t eap_method_t; -typedef enum eap_role_t eap_role_t; - -#include <library.h> -#include <plugins/plugin.h> -#include <utils/identification.h> -#include <eap/eap.h> -#include <encoding/payloads/eap_payload.h> - -/** - * Role of an eap_method, SERVER or PEER (client) - */ -enum eap_role_t { - EAP_SERVER, - EAP_PEER, -}; -/** - * enum names for eap_role_t. - */ -extern enum_name_t *eap_role_names; - -/** - * Interface of an EAP method for server and client side. - * - * An EAP method initiates an EAP exchange and processes requests and - * responses. An EAP method may need multiple exchanges before succeeding, and - * the eap_authentication may use multiple EAP methods to authenticate a peer. - * To accomplish these requirements, all EAP methods have their own - * implementation while the eap_authenticatior uses one or more of these - * EAP methods. Sending of EAP(SUCCESS/FAILURE) message is not the job - * of the method, the eap_authenticator does this. - * An EAP method may establish a MSK, this is used the complete the - * authentication. Even if a mutual EAP method is used, the traditional - * AUTH payloads are required. Only these include the nonces and messages from - * ike_sa_init and therefore prevent man in the middle attacks. - * The EAP method must use an initial EAP identifier value != 0, as a preceding - * EAP-Identity exchange always uses identifier 0. - */ -struct eap_method_t { - - /** - * Initiate the EAP exchange. - * - * initiate() is only useable for server implementations, as clients only - * reply to server requests. - * A eap_payload is created in "out" if result is NEED_MORE. - * - * @param out eap_payload to send to the client - * @return - * - NEED_MORE, if an other exchange is required - * - FAILED, if unable to create eap request payload - */ - status_t (*initiate) (eap_method_t *this, eap_payload_t **out); - - /** - * Process a received EAP message. - * - * A eap_payload is created in "out" if result is NEED_MORE. - * - * @param in eap_payload response received - * @param out created eap_payload to send - * @return - * - NEED_MORE, if an other exchange is required - * - FAILED, if EAP method failed - * - SUCCESS, if EAP method succeeded - */ - status_t (*process) (eap_method_t *this, eap_payload_t *in, - eap_payload_t **out); - - /** - * Get the EAP type implemented in this method. - * - * @param vendor pointer receiving vendor identifier for type, 0 for none - * @return type of the EAP method - */ - eap_type_t (*get_type) (eap_method_t *this, u_int32_t *vendor); - - /** - * Check if this EAP method authenticates the server. - * - * Some EAP methods provide mutual authentication and - * allow authentication using only EAP, if the peer supports it. - * - * @return TRUE if methods provides mutual authentication - */ - bool (*is_mutual) (eap_method_t *this); - - /** - * Get the MSK established by this EAP method. - * - * Not all EAP methods establish a shared secret. For implementations of - * the EAP-Identity method, get_msk() returns the received identity. - * - * @param msk chunk receiving internal stored MSK - * @return - * - SUCCESS, or - * - FAILED, if MSK not established (yet) - */ - status_t (*get_msk) (eap_method_t *this, chunk_t *msk); - - /** - * Get the current EAP identifier. - * - * @return current EAP identifier - */ - u_int8_t (*get_identifier) (eap_method_t *this); - - /** - * Set the EAP identifier to a deterministic value, overwriting - * the randomly initialized default value. - * - * @param identifier current EAP identifier - */ - void (*set_identifier) (eap_method_t *this, u_int8_t identifier); - - /** - * Destroys a eap_method_t object. - */ - void (*destroy) (eap_method_t *this); -}; - -/** - * Constructor definition for a pluggable EAP method. - * - * Each EAP module must define a constructor function which will return - * an initialized object with the methods defined in eap_method_t. - * Constructors for server and peers are identical, to support both roles - * of a EAP method, a plugin needs register two constructors in the - * eap_manager_t. - * The passed identites are of type ID_EAP and valid only during the - * constructor invocation. - * - * @param server ID of the server to use for credential lookup - * @param peer ID of the peer to use for credential lookup - * @return implementation of the eap_method_t interface - */ -typedef eap_method_t *(*eap_constructor_t)(identification_t *server, - identification_t *peer); - -/** - * Helper function to (un-)register EAP methods from plugin features. - * - * This function is a plugin_feature_callback_t and can be used with the - * PLUGIN_CALLBACK macro to register a EAP method constructor. - * - * @param plugin plugin registering the EAP method constructor - * @param feature associated plugin feature - * @param reg TRUE to register, FALSE to unregister. - * @param data data passed to callback, an eap_constructor_t - */ -bool eap_method_register(plugin_t *plugin, plugin_feature_t *feature, - bool reg, void *data); - -#endif /** EAP_METHOD_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap_authenticator.c b/src/libcharon/sa/authenticators/eap_authenticator.c deleted file mode 100644 index 5c8f0b6ce..000000000 --- a/src/libcharon/sa/authenticators/eap_authenticator.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - * Copyright (C) 2006-2009 Martin Willi - * 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 "eap_authenticator.h" - -#include <daemon.h> -#include <sa/authenticators/eap/eap_method.h> -#include <encoding/payloads/auth_payload.h> -#include <encoding/payloads/eap_payload.h> - -typedef struct private_eap_authenticator_t private_eap_authenticator_t; - -/** - * Private data of an eap_authenticator_t object. - */ -struct private_eap_authenticator_t { - - /** - * Public authenticator_t interface. - */ - eap_authenticator_t public; - - /** - * Assigned IKE_SA - */ - ike_sa_t *ike_sa; - - /** - * others nonce to include in AUTH calculation - */ - chunk_t received_nonce; - - /** - * our nonce to include in AUTH calculation - */ - chunk_t sent_nonce; - - /** - * others IKE_SA_INIT message data to include in AUTH calculation - */ - chunk_t received_init; - - /** - * our IKE_SA_INIT message data to include in AUTH calculation - */ - chunk_t sent_init; - - /** - * Reserved bytes of ID payload - */ - char reserved[3]; - - /** - * Current EAP method processing - */ - eap_method_t *method; - - /** - * MSK used to build and verify auth payload - */ - chunk_t msk; - - /** - * EAP authentication method completed successfully - */ - bool eap_complete; - - /** - * Set if we require mutual EAP due EAP-only authentication - */ - bool require_mutual; - - /** - * authentication payload verified successfully - */ - bool auth_complete; - - /** - * generated EAP payload - */ - eap_payload_t *eap_payload; - - /** - * EAP identity of peer - */ - identification_t *eap_identity; -}; - -/** - * load an EAP method - */ -static eap_method_t *load_method(private_eap_authenticator_t *this, - eap_type_t type, u_int32_t vendor, eap_role_t role) -{ - identification_t *server, *peer, *aaa; - auth_cfg_t *auth; - - if (role == EAP_SERVER) - { - server = this->ike_sa->get_my_id(this->ike_sa); - peer = this->ike_sa->get_other_id(this->ike_sa); - auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); - } - else - { - server = this->ike_sa->get_other_id(this->ike_sa); - peer = this->ike_sa->get_my_id(this->ike_sa); - auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); - } - if (this->eap_identity) - { - peer = this->eap_identity; - } - aaa = auth->get(auth, AUTH_RULE_AAA_IDENTITY); - if (aaa) - { - server = aaa; - } - return charon->eap->create_instance(charon->eap, type, vendor, - role, server, peer); -} - -/** - * Initiate EAP conversation as server - */ -static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this, - bool do_identity) -{ - auth_cfg_t *auth; - eap_type_t type; - identification_t *id; - u_int32_t vendor; - eap_payload_t *out; - char *action; - - auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); - - /* initiate EAP-Identity exchange if required */ - if (!this->eap_identity && do_identity) - { - id = auth->get(auth, AUTH_RULE_EAP_IDENTITY); - if (id) - { - if (id->get_type(id) == ID_ANY) - { - this->method = load_method(this, EAP_IDENTITY, 0, EAP_SERVER); - if (this->method) - { - if (this->method->initiate(this->method, &out) == NEED_MORE) - { - DBG1(DBG_IKE, "initiating %N method (id 0x%02X)", - eap_type_names, EAP_IDENTITY, - this->method->get_identifier(this->method)); - return out; - } - this->method->destroy(this->method); - } - DBG1(DBG_IKE, "EAP-Identity request configured, " - "but not supported"); - } - else - { - DBG1(DBG_IKE, "using configured EAP-Identity %Y", id); - this->eap_identity = id->clone(id); - } - } - } - /* invoke real EAP method */ - type = (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE); - vendor = (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR); - action = "loading"; - this->method = load_method(this, type, vendor, EAP_SERVER); - if (this->method) - { - action = "initiating"; - type = this->method->get_type(this->method, &vendor); - if (this->method->initiate(this->method, &out) == NEED_MORE) - { - if (vendor) - { - DBG1(DBG_IKE, "initiating EAP vendor type %d-%d method (id 0x%02X)", - type, vendor, out->get_identifier(out)); - } - else - { - DBG1(DBG_IKE, "initiating %N method (id 0x%02X)", eap_type_names, - type, out->get_identifier(out)); - } - return out; - } - } - if (vendor) - { - DBG1(DBG_IKE, "%s EAP vendor type %d-%d method failed", - action, type, vendor); - } - else - { - DBG1(DBG_IKE, "%s %N method failed", action, eap_type_names, type); - } - return eap_payload_create_code(EAP_FAILURE, 0); -} - -/** - * Replace the existing EAP-Identity in other auth config - */ -static void replace_eap_identity(private_eap_authenticator_t *this) -{ - identification_t *eap_identity; - auth_cfg_t *cfg; - - eap_identity = this->eap_identity->clone(this->eap_identity); - cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); - cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, eap_identity); -} - -/** - * Handle EAP exchange as server - */ -static eap_payload_t* server_process_eap(private_eap_authenticator_t *this, - eap_payload_t *in) -{ - eap_type_t type, received_type; - u_int32_t vendor, received_vendor; - eap_payload_t *out; - - if (in->get_code(in) != EAP_RESPONSE) - { - DBG1(DBG_IKE, "received %N, sending %N", - eap_code_names, in->get_code(in), eap_code_names, EAP_FAILURE); - return eap_payload_create_code(EAP_FAILURE, in->get_identifier(in)); - } - - type = this->method->get_type(this->method, &vendor); - received_type = in->get_type(in, &received_vendor); - if (type != received_type || vendor != received_vendor) - { - if (received_vendor == 0 && received_type == EAP_NAK) - { - DBG1(DBG_IKE, "received %N, sending %N", - eap_type_names, EAP_NAK, eap_code_names, EAP_FAILURE); - } - else - { - DBG1(DBG_IKE, "received invalid EAP response, sending %N", - eap_code_names, EAP_FAILURE); - } - return eap_payload_create_code(EAP_FAILURE, in->get_identifier(in)); - } - - switch (this->method->process(this->method, in, &out)) - { - case NEED_MORE: - return out; - case SUCCESS: - if (!vendor && type == EAP_IDENTITY) - { - chunk_t data; - - if (this->method->get_msk(this->method, &data) == SUCCESS) - { - this->eap_identity = identification_create_from_data(data); - DBG1(DBG_IKE, "received EAP identity '%Y'", - this->eap_identity); - replace_eap_identity(this); - } - /* restart EAP exchange, but with real method */ - this->method->destroy(this->method); - return server_initiate_eap(this, FALSE); - } - if (this->method->get_msk(this->method, &this->msk) == SUCCESS) - { - this->msk = chunk_clone(this->msk); - } - if (vendor) - { - DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeeded, " - "%sMSK established", type, vendor, - this->msk.ptr ? "" : "no "); - } - else - { - DBG1(DBG_IKE, "EAP method %N succeeded, %sMSK established", - eap_type_names, type, this->msk.ptr ? "" : "no "); - } - this->ike_sa->set_condition(this->ike_sa, COND_EAP_AUTHENTICATED, - TRUE); - this->eap_complete = TRUE; - return eap_payload_create_code(EAP_SUCCESS, in->get_identifier(in)); - case FAILED: - default: - if (vendor) - { - DBG1(DBG_IKE, "EAP vendor specific method %d-%d failed for " - "peer %Y", type, vendor, - this->ike_sa->get_other_id(this->ike_sa)); - } - else - { - DBG1(DBG_IKE, "EAP method %N failed for peer %Y", - eap_type_names, type, - this->ike_sa->get_other_id(this->ike_sa)); - } - return eap_payload_create_code(EAP_FAILURE, in->get_identifier(in)); - } -} - -/** - * Processing method for a peer - */ -static eap_payload_t* client_process_eap(private_eap_authenticator_t *this, - eap_payload_t *in) -{ - eap_type_t type; - u_int32_t vendor; - auth_cfg_t *auth; - eap_payload_t *out; - identification_t *id; - - type = in->get_type(in, &vendor); - - if (!vendor && type == EAP_IDENTITY) - { - DESTROY_IF(this->eap_identity); - auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); - id = auth->get(auth, AUTH_RULE_EAP_IDENTITY); - if (!id || id->get_type(id) == ID_ANY) - { - id = this->ike_sa->get_my_id(this->ike_sa); - } - DBG1(DBG_IKE, "server requested %N (id 0x%02X), sending '%Y'", - eap_type_names, type, in->get_identifier(in), id); - this->eap_identity = id->clone(id); - - this->method = load_method(this, type, vendor, EAP_PEER); - if (this->method) - { - if (this->method->process(this->method, in, &out) == SUCCESS) - { - this->method->destroy(this->method); - this->method = NULL; - return out; - } - this->method->destroy(this->method); - this->method = NULL; - } - DBG1(DBG_IKE, "%N not supported, sending EAP_NAK", - eap_type_names, type); - return eap_payload_create_nak(in->get_identifier(in)); - } - if (this->method == NULL) - { - if (vendor) - { - DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d ", - "(id 0x%02X)", type, vendor, in->get_identifier(in)); - } - else - { - DBG1(DBG_IKE, "server requested %N authentication (id 0x%02X)", - eap_type_names, type, in->get_identifier(in)); - } - this->method = load_method(this, type, vendor, EAP_PEER); - if (!this->method) - { - DBG1(DBG_IKE, "EAP method not supported, sending EAP_NAK"); - return eap_payload_create_nak(in->get_identifier(in)); - } - } - - type = this->method->get_type(this->method, &vendor); - - if (this->method->process(this->method, in, &out) == NEED_MORE) - { /* client methods should never return SUCCESS */ - return out; - } - - if (vendor) - { - DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed", type, vendor); - } - else - { - DBG1(DBG_IKE, "%N method failed", eap_type_names, type); - } - return NULL; -} - -/** - * Verify AUTH payload - */ -static bool verify_auth(private_eap_authenticator_t *this, message_t *message, - chunk_t nonce, chunk_t init) -{ - auth_payload_t *auth_payload; - chunk_t auth_data, recv_auth_data; - identification_t *other_id; - auth_cfg_t *auth; - keymat_t *keymat; - - auth_payload = (auth_payload_t*)message->get_payload(message, - AUTHENTICATION); - if (!auth_payload) - { - DBG1(DBG_IKE, "AUTH payload missing"); - return FALSE; - } - other_id = this->ike_sa->get_other_id(this->ike_sa); - keymat = this->ike_sa->get_keymat(this->ike_sa); - auth_data = keymat->get_psk_sig(keymat, TRUE, init, nonce, - this->msk, other_id, this->reserved); - recv_auth_data = auth_payload->get_data(auth_payload); - if (!auth_data.len || !chunk_equals(auth_data, recv_auth_data)) - { - DBG1(DBG_IKE, "verification of AUTH payload with%s EAP MSK failed", - this->msk.ptr ? "" : "out"); - chunk_free(&auth_data); - return FALSE; - } - chunk_free(&auth_data); - - DBG1(DBG_IKE, "authentication of '%Y' with %N successful", - other_id, auth_class_names, AUTH_CLASS_EAP); - this->auth_complete = TRUE; - auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); - auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP); - return TRUE; -} - -/** - * Build AUTH payload - */ -static void build_auth(private_eap_authenticator_t *this, message_t *message, - chunk_t nonce, chunk_t init) -{ - auth_payload_t *auth_payload; - identification_t *my_id; - chunk_t auth_data; - keymat_t *keymat; - - my_id = this->ike_sa->get_my_id(this->ike_sa); - keymat = this->ike_sa->get_keymat(this->ike_sa); - - DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N", - my_id, auth_class_names, AUTH_CLASS_EAP); - - auth_data = keymat->get_psk_sig(keymat, FALSE, init, nonce, - this->msk, my_id, this->reserved); - auth_payload = auth_payload_create(); - auth_payload->set_auth_method(auth_payload, AUTH_PSK); - auth_payload->set_data(auth_payload, auth_data); - message->add_payload(message, (payload_t*)auth_payload); - chunk_free(&auth_data); -} - -METHOD(authenticator_t, process_server, status_t, - private_eap_authenticator_t *this, message_t *message) -{ - eap_payload_t *eap_payload; - - if (this->eap_complete) - { - if (!verify_auth(this, message, this->sent_nonce, this->received_init)) - { - return FAILED; - } - return NEED_MORE; - } - - if (!this->method) - { - this->eap_payload = server_initiate_eap(this, TRUE); - } - else - { - eap_payload = (eap_payload_t*)message->get_payload(message, - EXTENSIBLE_AUTHENTICATION); - if (!eap_payload) - { - return FAILED; - } - this->eap_payload = server_process_eap(this, eap_payload); - } - return NEED_MORE; -} - -METHOD(authenticator_t, build_server, status_t, - private_eap_authenticator_t *this, message_t *message) -{ - if (this->eap_payload) - { - eap_code_t code; - - code = this->eap_payload->get_code(this->eap_payload); - message->add_payload(message, (payload_t*)this->eap_payload); - this->eap_payload = NULL; - if (code == EAP_FAILURE) - { - return FAILED; - } - return NEED_MORE; - } - if (this->eap_complete && this->auth_complete) - { - build_auth(this, message, this->received_nonce, this->sent_init); - return SUCCESS; - } - return FAILED; -} - -METHOD(authenticator_t, process_client, status_t, - private_eap_authenticator_t *this, message_t *message) -{ - eap_payload_t *eap_payload; - - if (this->eap_complete) - { - if (!verify_auth(this, message, this->sent_nonce, this->received_init)) - { - return FAILED; - } - if (this->require_mutual && !this->method->is_mutual(this->method)) - { /* we require mutual authentication due to EAP-only */ - u_int32_t vendor; - - DBG1(DBG_IKE, "EAP-only authentication requires a mutual and " - "MSK deriving EAP method, but %N is not", - eap_type_names, this->method->get_type(this->method, &vendor)); - return FAILED; - } - return SUCCESS; - } - - eap_payload = (eap_payload_t*)message->get_payload(message, - EXTENSIBLE_AUTHENTICATION); - if (eap_payload) - { - switch (eap_payload->get_code(eap_payload)) - { - case EAP_REQUEST: - { - this->eap_payload = client_process_eap(this, eap_payload); - if (this->eap_payload) - { - return NEED_MORE; - } - return FAILED; - } - case EAP_SUCCESS: - { - eap_type_t type; - u_int32_t vendor; - auth_cfg_t *cfg; - - if (this->method->get_msk(this->method, &this->msk) == SUCCESS) - { - this->msk = chunk_clone(this->msk); - } - type = this->method->get_type(this->method, &vendor); - if (vendor) - { - DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeeded, " - "%sMSK established", type, vendor, - this->msk.ptr ? "" : "no "); - } - else - { - DBG1(DBG_IKE, "EAP method %N succeeded, %sMSK established", - eap_type_names, type, this->msk.ptr ? "" : "no "); - } - cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); - cfg->add(cfg, AUTH_RULE_EAP_TYPE, type); - if (vendor) - { - cfg->add(cfg, AUTH_RULE_EAP_VENDOR, vendor); - } - this->eap_complete = TRUE; - return NEED_MORE; - } - case EAP_FAILURE: - default: - { - DBG1(DBG_IKE, "received %N, EAP authentication failed", - eap_code_names, eap_payload->get_code(eap_payload)); - return FAILED; - } - } - } - return FAILED; -} - -METHOD(authenticator_t, build_client, status_t, - private_eap_authenticator_t *this, message_t *message) -{ - if (this->eap_payload) - { - message->add_payload(message, (payload_t*)this->eap_payload); - this->eap_payload = NULL; - return NEED_MORE; - } - if (this->eap_complete) - { - build_auth(this, message, this->received_nonce, this->sent_init); - return NEED_MORE; - } - return NEED_MORE; -} - -METHOD(authenticator_t, is_mutual, bool, - private_eap_authenticator_t *this) -{ - /* we don't know yet, but insist on it after EAP is complete */ - this->require_mutual = TRUE; - return TRUE; -} - -METHOD(authenticator_t, destroy, void, - private_eap_authenticator_t *this) -{ - DESTROY_IF(this->method); - DESTROY_IF(this->eap_payload); - DESTROY_IF(this->eap_identity); - chunk_free(&this->msk); - free(this); -} - -/* - * Described in header. - */ -eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_nonce, - chunk_t received_init, chunk_t sent_init, - char reserved[3]) -{ - private_eap_authenticator_t *this; - - INIT(this, - .public = { - .authenticator = { - .build = _build_client, - .process = _process_client, - .is_mutual = _is_mutual, - .destroy = _destroy, - }, - }, - .ike_sa = ike_sa, - .received_init = received_init, - .received_nonce = received_nonce, - .sent_init = sent_init, - .sent_nonce = sent_nonce, - ); - memcpy(this->reserved, reserved, sizeof(this->reserved)); - - return &this->public; -} - -/* - * Described in header. - */ -eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_nonce, - chunk_t received_init, chunk_t sent_init, - char reserved[3]) -{ - private_eap_authenticator_t *this; - - INIT(this, - .public = { - .authenticator = { - .build = _build_server, - .process = _process_server, - .is_mutual = _is_mutual, - .destroy = _destroy, - }, - }, - .ike_sa = ike_sa, - .received_init = received_init, - .received_nonce = received_nonce, - .sent_init = sent_init, - .sent_nonce = sent_nonce, - ); - memcpy(this->reserved, reserved, sizeof(this->reserved)); - - return &this->public; -} - diff --git a/src/libcharon/sa/authenticators/eap_authenticator.h b/src/libcharon/sa/authenticators/eap_authenticator.h deleted file mode 100644 index 726411a18..000000000 --- a/src/libcharon/sa/authenticators/eap_authenticator.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2006-2009 Martin Willi - * 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 eap_authenticator eap_authenticator - * @{ @ingroup authenticators - */ - -#ifndef EAP_AUTHENTICATOR_H_ -#define EAP_AUTHENTICATOR_H_ - -typedef struct eap_authenticator_t eap_authenticator_t; - -#include <sa/authenticators/authenticator.h> - -/** - * Implementation of authenticator_t using EAP authentication. - * - * Authentication using EAP involves the most complex authenticator. It stays - * alive over multiple ike_auth transactions and handles multiple EAP - * messages. - * - * @verbatim - ike_sa_init - -------------------------> - <------------------------- - followed by multiple ike_auth: - - +--------+ +--------+ - | EAP | IDi, [IDr,] SA, TS | EAP | - | client | ---------------------------> | server | - | | ID, AUTH, EAP | | - | | <--------------------------- | | - | | EAP | | - | | ---------------------------> | | - | | EAP | | - | | <--------------------------- | | - | | EAP | | - | | ---------------------------> | | - | | EAP(SUCCESS) | | - | | <--------------------------- | | - | | AUTH | | If EAP establishes - | | ---------------------------> | | a session key, AUTH - | | AUTH, SA, TS | | payloads use this - | | <--------------------------- | | key, not SK_pi/pr - +--------+ +--------+ - - @endverbatim - */ -struct eap_authenticator_t { - - /** - * Implemented authenticator_t interface. - */ - authenticator_t authenticator; -}; - -/** - * Create an authenticator to authenticate against an EAP server. - * - * @param ike_sa associated ike_sa - * @param received_nonce nonce received in IKE_SA_INIT - * @param sent_nonce nonce sent in IKE_SA_INIT - * @param received_init received IKE_SA_INIT message data - * @param sent_init sent IKE_SA_INIT message data - * @param reserved reserved bytes of ID payload - * @return EAP authenticator - */ -eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_nonce, - chunk_t received_init, chunk_t sent_init, - char reserved[3]); - -/** - * Create an authenticator to authenticate EAP clients. - * - * @param ike_sa associated ike_sa - * @param received_nonce nonce received in IKE_SA_INIT - * @param sent_nonce nonce sent in IKE_SA_INIT - * @param received_init received IKE_SA_INIT message data - * @param sent_init sent IKE_SA_INIT message data - * @param reserved reserved bytes of ID payload - * @return EAP authenticator - */ -eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_nonce, - chunk_t received_init, chunk_t sent_init, - char reserved[3]); - -#endif /** EAP_AUTHENTICATOR_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/psk_authenticator.c b/src/libcharon/sa/authenticators/psk_authenticator.c deleted file mode 100644 index 21fc0f9b8..000000000 --- a/src/libcharon/sa/authenticators/psk_authenticator.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2005-2009 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 "psk_authenticator.h" - -#include <daemon.h> -#include <encoding/payloads/auth_payload.h> - -typedef struct private_psk_authenticator_t private_psk_authenticator_t; - -/** - * Private data of an psk_authenticator_t object. - */ -struct private_psk_authenticator_t { - - /** - * Public authenticator_t interface. - */ - psk_authenticator_t public; - - /** - * Assigned IKE_SA - */ - ike_sa_t *ike_sa; - - /** - * nonce to include in AUTH calculation - */ - chunk_t nonce; - - /** - * IKE_SA_INIT message data to include in AUTH calculation - */ - chunk_t ike_sa_init; - - /** - * Reserved bytes of ID payload - */ - char reserved[3]; -}; - -METHOD(authenticator_t, build, status_t, - private_psk_authenticator_t *this, message_t *message) -{ - identification_t *my_id, *other_id; - auth_payload_t *auth_payload; - shared_key_t *key; - chunk_t auth_data; - keymat_t *keymat; - - keymat = this->ike_sa->get_keymat(this->ike_sa); - my_id = this->ike_sa->get_my_id(this->ike_sa); - other_id = this->ike_sa->get_other_id(this->ike_sa); - DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N", - my_id, auth_method_names, AUTH_PSK); - key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE, my_id, other_id); - if (key == NULL) - { - DBG1(DBG_IKE, "no shared key found for '%Y' - '%Y'", my_id, other_id); - return NOT_FOUND; - } - auth_data = keymat->get_psk_sig(keymat, FALSE, this->ike_sa_init, - this->nonce, key->get_key(key), my_id, this->reserved); - key->destroy(key); - DBG2(DBG_IKE, "successfully created shared key MAC"); - auth_payload = auth_payload_create(); - auth_payload->set_auth_method(auth_payload, AUTH_PSK); - auth_payload->set_data(auth_payload, auth_data); - chunk_free(&auth_data); - message->add_payload(message, (payload_t*)auth_payload); - - return SUCCESS; -} - -METHOD(authenticator_t, process, status_t, - private_psk_authenticator_t *this, message_t *message) -{ - chunk_t auth_data, recv_auth_data; - identification_t *my_id, *other_id; - auth_payload_t *auth_payload; - auth_cfg_t *auth; - shared_key_t *key; - enumerator_t *enumerator; - bool authenticated = FALSE; - int keys_found = 0; - keymat_t *keymat; - - auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION); - if (!auth_payload) - { - return FAILED; - } - keymat = this->ike_sa->get_keymat(this->ike_sa); - recv_auth_data = auth_payload->get_data(auth_payload); - my_id = this->ike_sa->get_my_id(this->ike_sa); - other_id = this->ike_sa->get_other_id(this->ike_sa); - enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr, - SHARED_IKE, my_id, other_id); - while (!authenticated && enumerator->enumerate(enumerator, &key, NULL, NULL)) - { - keys_found++; - - auth_data = keymat->get_psk_sig(keymat, TRUE, this->ike_sa_init, - this->nonce, key->get_key(key), other_id, this->reserved); - if (auth_data.len && chunk_equals(auth_data, recv_auth_data)) - { - DBG1(DBG_IKE, "authentication of '%Y' with %N successful", - other_id, auth_method_names, AUTH_PSK); - authenticated = TRUE; - } - chunk_free(&auth_data); - } - enumerator->destroy(enumerator); - - if (!authenticated) - { - if (keys_found == 0) - { - DBG1(DBG_IKE, "no shared key found for '%Y' - '%Y'", my_id, other_id); - return NOT_FOUND; - } - DBG1(DBG_IKE, "tried %d shared key%s for '%Y' - '%Y', but MAC mismatched", - keys_found, keys_found == 1 ? "" : "s", my_id, other_id); - return FAILED; - } - - auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); - auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK); - return SUCCESS; -} - -METHOD(authenticator_t, destroy, void, - private_psk_authenticator_t *this) -{ - free(this); -} - -/* - * Described in header. - */ -psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_init, - char reserved[3]) -{ - private_psk_authenticator_t *this; - - INIT(this, - .public = { - .authenticator = { - .build = _build, - .process = (void*)return_failed, - .is_mutual = (void*)return_false, - .destroy = _destroy, - }, - }, - .ike_sa = ike_sa, - .ike_sa_init = sent_init, - .nonce = received_nonce, - ); - memcpy(this->reserved, reserved, sizeof(this->reserved)); - - return &this->public; -} - -/* - * Described in header. - */ -psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa, - chunk_t sent_nonce, chunk_t received_init, - char reserved[3]) -{ - private_psk_authenticator_t *this; - - INIT(this, - .public = { - .authenticator = { - .build = (void*)return_failed, - .process = _process, - .is_mutual = (void*)return_false, - .destroy = _destroy, - }, - }, - .ike_sa = ike_sa, - .ike_sa_init = received_init, - .nonce = sent_nonce, - ); - memcpy(this->reserved, reserved, sizeof(this->reserved)); - - return &this->public; -} - diff --git a/src/libcharon/sa/authenticators/psk_authenticator.h b/src/libcharon/sa/authenticators/psk_authenticator.h deleted file mode 100644 index 8cf1a0f98..000000000 --- a/src/libcharon/sa/authenticators/psk_authenticator.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2006-2009 Martin Willi - * 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 psk_authenticator psk_authenticator - * @{ @ingroup authenticators - */ - -#ifndef PSK_AUTHENTICATOR_H_ -#define PSK_AUTHENTICATOR_H_ - -typedef struct psk_authenticator_t psk_authenticator_t; - -#include <sa/authenticators/authenticator.h> - -/** - * Implementation of authenticator_t using pre-shared keys. - */ -struct psk_authenticator_t { - - /** - * Implemented authenticator_t interface. - */ - authenticator_t authenticator; -}; - -/** - * Create an authenticator to build PSK signatures. - * - * @param ike_sa associated ike_sa - * @param received_nonce nonce received in IKE_SA_INIT - * @param sent_init sent IKE_SA_INIT message data - * @param reserved reserved bytes of ID payload - * @return PSK authenticator - */ -psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_init, - char reserved[3]); - -/** - * Create an authenticator to verify PSK signatures. - * - * @param ike_sa associated ike_sa - * @param sent_nonce nonce sent in IKE_SA_INIT - * @param received_init received IKE_SA_INIT message data - * @param reserved reserved bytes of ID payload - * @return PSK authenticator - */ -psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa, - chunk_t sent_nonce, chunk_t received_init, - char reserved[3]); - -#endif /** PSK_AUTHENTICATOR_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/pubkey_authenticator.c b/src/libcharon/sa/authenticators/pubkey_authenticator.c deleted file mode 100644 index 247891670..000000000 --- a/src/libcharon/sa/authenticators/pubkey_authenticator.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * Copyright (C) 2005-2009 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 "pubkey_authenticator.h" - -#include <daemon.h> -#include <encoding/payloads/auth_payload.h> - -typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t; - -/** - * Private data of an pubkey_authenticator_t object. - */ -struct private_pubkey_authenticator_t { - - /** - * Public authenticator_t interface. - */ - pubkey_authenticator_t public; - - /** - * Assigned IKE_SA - */ - ike_sa_t *ike_sa; - - /** - * nonce to include in AUTH calculation - */ - chunk_t nonce; - - /** - * IKE_SA_INIT message data to include in AUTH calculation - */ - chunk_t ike_sa_init; - - /** - * Reserved bytes of ID payload - */ - char reserved[3]; -}; - -METHOD(authenticator_t, build, status_t, - private_pubkey_authenticator_t *this, message_t *message) -{ - chunk_t octets, auth_data; - status_t status = FAILED; - private_key_t *private; - identification_t *id; - auth_cfg_t *auth; - auth_payload_t *auth_payload; - auth_method_t auth_method; - signature_scheme_t scheme; - keymat_t *keymat; - - id = this->ike_sa->get_my_id(this->ike_sa); - auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); - private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth); - if (private == NULL) - { - DBG1(DBG_IKE, "no private key found for '%Y'", id); - return NOT_FOUND; - } - - switch (private->get_type(private)) - { - case KEY_RSA: - /* we currently use always SHA1 for signatures, - * TODO: support other hashes depending on configuration/auth */ - scheme = SIGN_RSA_EMSA_PKCS1_SHA1; - auth_method = AUTH_RSA; - break; - case KEY_ECDSA: - /* we try to deduct the signature scheme from the keysize */ - switch (private->get_keysize(private)) - { - case 256: - scheme = SIGN_ECDSA_256; - auth_method = AUTH_ECDSA_256; - break; - case 384: - scheme = SIGN_ECDSA_384; - auth_method = AUTH_ECDSA_384; - break; - case 521: - scheme = SIGN_ECDSA_521; - auth_method = AUTH_ECDSA_521; - break; - default: - DBG1(DBG_IKE, "%d bit ECDSA private key size not supported", - private->get_keysize(private)); - return status; - } - break; - default: - DBG1(DBG_IKE, "private key of type %N not supported", - key_type_names, private->get_type(private)); - return status; - } - keymat = this->ike_sa->get_keymat(this->ike_sa); - octets = keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init, - this->nonce, id, this->reserved); - if (private->sign(private, scheme, octets, &auth_data)) - { - auth_payload = auth_payload_create(); - auth_payload->set_auth_method(auth_payload, auth_method); - auth_payload->set_data(auth_payload, auth_data); - chunk_free(&auth_data); - message->add_payload(message, (payload_t*)auth_payload); - status = SUCCESS; - } - DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id, - auth_method_names, auth_method, - (status == SUCCESS)? "successful":"failed"); - chunk_free(&octets); - private->destroy(private); - - return status; -} - -METHOD(authenticator_t, process, status_t, - private_pubkey_authenticator_t *this, message_t *message) -{ - public_key_t *public; - auth_method_t auth_method; - auth_payload_t *auth_payload; - chunk_t auth_data, octets; - identification_t *id; - auth_cfg_t *auth, *current_auth; - enumerator_t *enumerator; - key_type_t key_type = KEY_ECDSA; - signature_scheme_t scheme; - status_t status = NOT_FOUND; - keymat_t *keymat; - - auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION); - if (!auth_payload) - { - return FAILED; - } - auth_method = auth_payload->get_auth_method(auth_payload); - switch (auth_method) - { - case AUTH_RSA: - /* We currently accept SHA1 signatures only - * TODO: allow other hash algorithms and note it in "auth" */ - key_type = KEY_RSA; - scheme = SIGN_RSA_EMSA_PKCS1_SHA1; - break; - case AUTH_ECDSA_256: - scheme = SIGN_ECDSA_256; - break; - case AUTH_ECDSA_384: - scheme = SIGN_ECDSA_384; - break; - case AUTH_ECDSA_521: - scheme = SIGN_ECDSA_521; - break; - default: - return INVALID_ARG; - } - auth_data = auth_payload->get_data(auth_payload); - id = this->ike_sa->get_other_id(this->ike_sa); - keymat = this->ike_sa->get_keymat(this->ike_sa); - octets = keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init, - this->nonce, id, this->reserved); - auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); - enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, - key_type, id, auth); - while (enumerator->enumerate(enumerator, &public, ¤t_auth)) - { - if (public->verify(public, scheme, octets, auth_data)) - { - DBG1(DBG_IKE, "authentication of '%Y' with %N successful", - id, auth_method_names, auth_method); - status = SUCCESS; - auth->merge(auth, current_auth, FALSE); - auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); - break; - } - else - { - status = FAILED; - DBG1(DBG_IKE, "signature validation failed, looking for another key"); - } - } - enumerator->destroy(enumerator); - chunk_free(&octets); - if (status == NOT_FOUND) - { - DBG1(DBG_IKE, "no trusted %N public key found for '%Y'", - key_type_names, key_type, id); - } - return status; -} - -METHOD(authenticator_t, destroy, void, - private_pubkey_authenticator_t *this) -{ - free(this); -} - -/* - * Described in header. - */ -pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_init, - char reserved[3]) -{ - private_pubkey_authenticator_t *this; - - INIT(this, - .public = { - .authenticator = { - .build = _build, - .process = (void*)return_failed, - .is_mutual = (void*)return_false, - .destroy = _destroy, - }, - }, - .ike_sa = ike_sa, - .ike_sa_init = sent_init, - .nonce = received_nonce, - ); - memcpy(this->reserved, reserved, sizeof(this->reserved)); - - return &this->public; -} - -/* - * Described in header. - */ -pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa, - chunk_t sent_nonce, chunk_t received_init, - char reserved[3]) -{ - private_pubkey_authenticator_t *this; - - INIT(this, - .public = { - .authenticator = { - .build = (void*)return_failed, - .process = _process, - .is_mutual = (void*)return_false, - .destroy = _destroy, - }, - }, - .ike_sa = ike_sa, - .ike_sa_init = received_init, - .nonce = sent_nonce, - ); - memcpy(this->reserved, reserved, sizeof(this->reserved)); - - return &this->public; -} diff --git a/src/libcharon/sa/authenticators/pubkey_authenticator.h b/src/libcharon/sa/authenticators/pubkey_authenticator.h deleted file mode 100644 index 4c3937ecc..000000000 --- a/src/libcharon/sa/authenticators/pubkey_authenticator.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * Copyright (C) 2006-2009 Martin Willi - * 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 pubkey_authenticator pubkey_authenticator - * @{ @ingroup authenticators - */ - -#ifndef PUBKEY_AUTHENTICATOR_H_ -#define PUBKEY_AUTHENTICATOR_H_ - -typedef struct pubkey_authenticator_t pubkey_authenticator_t; - -#include <sa/authenticators/authenticator.h> - -/** - * Implementation of authenticator_t using public key authenitcation. - */ -struct pubkey_authenticator_t { - - /** - * Implemented authenticator_t interface. - */ - authenticator_t authenticator; -}; - -/** - * Create an authenticator to build public key signatures. - * - * @param ike_sa associated ike_sa - * @param received_nonce nonce received in IKE_SA_INIT - * @param sent_init sent IKE_SA_INIT message data - * @param reserved reserved bytes of ID payload - * @return public key authenticator - */ -pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_init, - char reserved[3]); - -/** - * Create an authenticator to verify public key signatures. - * - * @param ike_sa associated ike_sa - * @param sent_nonce nonce sent in IKE_SA_INIT - * @param received_init received IKE_SA_INIT message data - * @param reserved reserved bytes of ID payload - * @return public key authenticator - */ -pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa, - chunk_t sent_nonce, chunk_t received_init, - char reserved[3]); - -#endif /** PUBKEY_AUTHENTICATOR_H_ @}*/ |