278 lines
8.2 KiB
C
278 lines
8.2 KiB
C
/*
|
|
* Copyright (C) 2009-2019 Tobias Brunner
|
|
* Copyright (C) 2006 Martin Willi
|
|
* 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
|
|
* 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 proposal proposal
|
|
* @{ @ingroup crypto
|
|
*/
|
|
|
|
#ifndef PROPOSAL_H_
|
|
#define PROPOSAL_H_
|
|
|
|
typedef enum protocol_id_t protocol_id_t;
|
|
typedef enum proposal_selection_flag_t proposal_selection_flag_t;
|
|
typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
|
|
typedef struct proposal_t proposal_t;
|
|
|
|
#include <library.h>
|
|
#include <utils/identification.h>
|
|
#include <collections/linked_list.h>
|
|
#include <networking/host.h>
|
|
#include <crypto/transform.h>
|
|
#include <crypto/crypters/crypter.h>
|
|
#include <crypto/signers/signer.h>
|
|
#include <crypto/diffie_hellman.h>
|
|
|
|
/**
|
|
* Protocol ID of a proposal.
|
|
*/
|
|
enum protocol_id_t {
|
|
PROTO_NONE = 0,
|
|
PROTO_IKE = 1,
|
|
PROTO_AH = 2,
|
|
PROTO_ESP = 3,
|
|
PROTO_IPCOMP = 4, /* IKEv1 only */
|
|
};
|
|
|
|
/**
|
|
* enum names for protocol_id_t
|
|
*/
|
|
extern enum_name_t *protocol_id_names;
|
|
|
|
/**
|
|
* Flags for selecting proposals.
|
|
*/
|
|
enum proposal_selection_flag_t {
|
|
/** Whether to prefer configured (default) or supplied proposals. */
|
|
PROPOSAL_PREFER_SUPPLIED = (1<<0),
|
|
/** Whether to skip and ignore algorithms from a private range. */
|
|
PROPOSAL_SKIP_PRIVATE = (1<<1),
|
|
/** Whether to skip and ignore diffie hellman groups. */
|
|
PROPOSAL_SKIP_DH = (1<<2),
|
|
};
|
|
|
|
/**
|
|
* Stores a set of algorithms used for an SA.
|
|
*
|
|
* A proposal stores algorithms for a specific protocol.
|
|
* Proposals with multiple protocols are not supported, as that's not specified
|
|
* in RFC 7296 anymore.
|
|
*/
|
|
struct proposal_t {
|
|
|
|
/**
|
|
* Add an algorithm to the proposal.
|
|
*
|
|
* The algorithms are stored by priority, first added is the most preferred.
|
|
* Key size is only needed for encryption algorithms with variable key
|
|
* size (such as AES). Must be set to zero if the key size is not specified.
|
|
*
|
|
* @param type kind of algorithm
|
|
* @param alg identifier for algorithm
|
|
* @param key_size key size to use
|
|
*/
|
|
void (*add_algorithm) (proposal_t *this, transform_type_t type,
|
|
uint16_t alg, uint16_t key_size);
|
|
|
|
/**
|
|
* Get an enumerator over algorithms for a specific transform type.
|
|
*
|
|
* @param type kind of algorithm
|
|
* @return enumerator over uint16_t alg, uint16_t key_size
|
|
*/
|
|
enumerator_t *(*create_enumerator) (proposal_t *this, transform_type_t type);
|
|
|
|
/**
|
|
* Get the algorithm for a type to use.
|
|
*
|
|
* If there are multiple algorithms, only the first is returned.
|
|
*
|
|
* @param type kind of algorithm
|
|
* @param alg pointer which receives algorithm
|
|
* @param key_size pointer which receives the key size
|
|
* @return TRUE if algorithm of this kind available
|
|
*/
|
|
bool (*get_algorithm) (proposal_t *this, transform_type_t type,
|
|
uint16_t *alg, uint16_t *key_size);
|
|
|
|
/**
|
|
* Check if the proposal has a specific DH group.
|
|
*
|
|
* @param group group to check for
|
|
* @return TRUE if algorithm included
|
|
*/
|
|
bool (*has_dh_group)(proposal_t *this, diffie_hellman_group_t group);
|
|
|
|
/**
|
|
* Move the given DH group to the front of the list if it was contained in
|
|
* the proposal.
|
|
*
|
|
* @param group group to promote
|
|
* @return TRUE if algorithm included
|
|
*/
|
|
bool (*promote_dh_group)(proposal_t *this, diffie_hellman_group_t group);
|
|
|
|
/**
|
|
* Compare two proposals and select a matching subset.
|
|
*
|
|
* If the proposals are for the same protocols (AH/ESP), they are
|
|
* compared. If they have at least one algorithm of each type
|
|
* in common, a resulting proposal of this kind is created.
|
|
*
|
|
* Unless the flag PROPOSAL_PREFER_SUPPLIED is set, other is expected to be
|
|
* the remote proposal from which to copy SPI and proposal number to the
|
|
* result, otherwise copy from this proposal.
|
|
*
|
|
* @param other proposal to compare against
|
|
* @param flags flags to consider during proposal selection
|
|
* @return selected proposal, NULL if proposals don't match
|
|
*/
|
|
proposal_t *(*select)(proposal_t *this, proposal_t *other,
|
|
proposal_selection_flag_t flags);
|
|
|
|
/**
|
|
* Check if the given proposal matches this proposal.
|
|
*
|
|
* This is similar to select, but no resulting proposal is selected.
|
|
*
|
|
* @param other proposal to compare against
|
|
* @param flags flags to consider during proposal selection
|
|
* @return TRUE if the proposals match
|
|
*/
|
|
bool (*matches)(proposal_t *this, proposal_t *other,
|
|
proposal_selection_flag_t flags);
|
|
|
|
/**
|
|
* Get the protocol ID of the proposal.
|
|
*
|
|
* @return protocol of the proposal
|
|
*/
|
|
protocol_id_t (*get_protocol) (proposal_t *this);
|
|
|
|
/**
|
|
* Get the SPI of the proposal.
|
|
*
|
|
* @return SPI of the proposal
|
|
*/
|
|
uint64_t (*get_spi) (proposal_t *this);
|
|
|
|
/**
|
|
* Set the SPI of the proposal.
|
|
*
|
|
* @param spi SPI to set for proposal
|
|
*/
|
|
void (*set_spi) (proposal_t *this, uint64_t spi);
|
|
|
|
/**
|
|
* Get the proposal number, as encoded in the SA payload.
|
|
*
|
|
* @return proposal number
|
|
*/
|
|
u_int (*get_number)(proposal_t *this);
|
|
|
|
/**
|
|
* Check for the equality of two proposals.
|
|
*
|
|
* @param other other proposal to check for equality
|
|
* @return TRUE if proposals are equal
|
|
*/
|
|
bool (*equals)(proposal_t *this, proposal_t *other);
|
|
|
|
/**
|
|
* Clone a proposal.
|
|
*
|
|
* @param flags flags to consider during cloning
|
|
* @return clone of proposal
|
|
*/
|
|
proposal_t *(*clone)(proposal_t *this, proposal_selection_flag_t flags);
|
|
|
|
/**
|
|
* Destroys the proposal object.
|
|
*/
|
|
void (*destroy) (proposal_t *this);
|
|
};
|
|
|
|
/**
|
|
* Create a proposal for IKE, ESP or AH.
|
|
*
|
|
* @param protocol protocol, such as PROTO_ESP
|
|
* @param number proposal number, as encoded in SA payload
|
|
* @return proposal_t object
|
|
*/
|
|
proposal_t *proposal_create(protocol_id_t protocol, u_int number);
|
|
|
|
/**
|
|
* Create a default proposal.
|
|
*
|
|
* @param protocol protocol, such as PROTO_ESP
|
|
* @return proposal_t object
|
|
*/
|
|
proposal_t *proposal_create_default(protocol_id_t protocol);
|
|
|
|
/**
|
|
* Create a default proposal for supported AEAD algorithms.
|
|
*
|
|
* @param protocol protocol, such as PROTO_ESP
|
|
* @return proposal_t object, NULL if none supported
|
|
*/
|
|
proposal_t *proposal_create_default_aead(protocol_id_t protocol);
|
|
|
|
/**
|
|
* Create a proposal from a string identifying the algorithms.
|
|
*
|
|
* Each algorithm identifier is separated with a '-' character e.g.
|
|
* aes256-sha2-curve25519. Multiple algorithms of the same transform type can be
|
|
* given (they don't have to be grouped together), the order is preserved e.g.
|
|
* curve25519-sha2-aes256-sha1-modp3072-aes128 is the same as
|
|
* aes256-aes128-sha2-sha1-curve25519-modp3072.
|
|
*
|
|
* The proposal is validated (e.g. PROTO_IKE proposals must contain a key
|
|
* exchange method, AEAD algorithms can't be combined with classic encryption
|
|
* algorithms etc.) and in some cases modified (e.g. by adding missing PRFs for
|
|
* PROTO_IKE, or by adding noesn in PROTO_ESP/AH proposals if neither esn, nor
|
|
* noesn is contained in the string etc.).
|
|
*
|
|
* @param protocol protocol, such as PROTO_ESP
|
|
* @param algs algorithms as string
|
|
* @return proposal_t object, NULL if invalid
|
|
*/
|
|
proposal_t *proposal_create_from_string(protocol_id_t protocol,
|
|
const char *algs);
|
|
|
|
/**
|
|
* Select a common proposal from the given lists of proposals.
|
|
*
|
|
* @param configured list of configured/local proposals
|
|
* @param supplied list of supplied/remote proposals
|
|
* @param flags flags to consider during proposal selection
|
|
* @return selected proposal, or NULL (allocated)
|
|
*/
|
|
proposal_t *proposal_select(linked_list_t *configured, linked_list_t *supplied,
|
|
proposal_selection_flag_t flags);
|
|
|
|
/**
|
|
* printf hook function for proposal_t.
|
|
*
|
|
* Arguments are:
|
|
* proposal_t*
|
|
* With the #-specifier, arguments are:
|
|
* linked_list_t* (containing proposal_t*)
|
|
*/
|
|
int proposal_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
|
|
const void *const *args);
|
|
|
|
#endif /** PROPOSAL_H_ @}*/
|