Extend sa_payload for IKEv1 support
This commit is contained in:
parent
8f3aea2f77
commit
b0b9d18593
|
@ -145,7 +145,8 @@ METHOD(listener_t, message, bool,
|
|||
proposal->get_protocol(proposal),
|
||||
proposal->get_spi(proposal));
|
||||
DBG1(DBG_CFG, "injecting custom proposal: %#P", new_props);
|
||||
new = sa_payload_create_from_proposal_list(new_props);
|
||||
new = sa_payload_create_from_proposal_list(
|
||||
SECURITY_ASSOCIATION, new_props);
|
||||
message->add_payload(message, (payload_t*)new);
|
||||
new_props->destroy_offset(new_props, offsetof(proposal_t, destroy));
|
||||
}
|
||||
|
|
|
@ -294,7 +294,8 @@ static void process_auth_response(private_pretend_auth_t *this,
|
|||
if (this->proposal)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)
|
||||
sa_payload_create_from_proposal(this->proposal));
|
||||
sa_payload_create_from_proposal(SECURITY_ASSOCIATION,
|
||||
this->proposal));
|
||||
}
|
||||
if (this->tsi)
|
||||
{
|
||||
|
|
|
@ -121,7 +121,7 @@ METHOD(listener_t, message, bool,
|
|||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
sa = sa_payload_create_from_proposal_list(updated);
|
||||
sa = sa_payload_create_from_proposal_list(SECURITY_ASSOCIATION, updated);
|
||||
list->destroy_offset(list, offsetof(proposal_t, destroy));
|
||||
updated->destroy_offset(updated, offsetof(proposal_t, destroy));
|
||||
message->add_payload(message, (payload_t*)sa);
|
||||
|
|
|
@ -496,6 +496,18 @@ METHOD(parser_t, parse_payload, status_t,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case PROPOSALS_V1:
|
||||
{
|
||||
if (payload_length < SA_PAYLOAD_V1_HEADER_LENGTH ||
|
||||
!parse_list(this, rule_number, output + rule->offset,
|
||||
PROPOSAL_SUBSTRUCTURE_V1,
|
||||
payload_length - SA_PAYLOAD_V1_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TRANSFORMS:
|
||||
{
|
||||
if (payload_length <
|
||||
|
|
|
@ -219,6 +219,11 @@ enum encoding_type_t {
|
|||
*/
|
||||
PROPOSALS,
|
||||
|
||||
/**
|
||||
* Same as PROPOSALS, but for IKEv1 in a SECURITY_ASSOCIATION_V1
|
||||
*/
|
||||
PROPOSALS_V1,
|
||||
|
||||
/**
|
||||
* Representating one or more transform substructures.
|
||||
*
|
||||
|
|
|
@ -156,7 +156,8 @@ payload_t *payload_create(payload_type_t type)
|
|||
case HEADER:
|
||||
return (payload_t*)ike_header_create();
|
||||
case SECURITY_ASSOCIATION:
|
||||
return (payload_t*)sa_payload_create();
|
||||
case SECURITY_ASSOCIATION_V1:
|
||||
return (payload_t*)sa_payload_create(type);
|
||||
case PROPOSAL_SUBSTRUCTURE:
|
||||
return (payload_t*)proposal_substructure_create();
|
||||
case TRANSFORM_SUBSTRUCTURE:
|
||||
|
|
|
@ -29,6 +29,10 @@ typedef struct payload_t payload_t;
|
|||
#include <library.h>
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
/**
|
||||
* Domain of interpretation used by IPsec/IKEv1
|
||||
*/
|
||||
#define IKEV1_DOI_IPSEC 1
|
||||
|
||||
/**
|
||||
* Payload-Types of an IKE message.
|
||||
|
@ -243,6 +247,14 @@ enum payload_type_t {
|
|||
* used internally to handle a transform attribute like a payload.
|
||||
*/
|
||||
CONFIGURATION_ATTRIBUTE = 261,
|
||||
|
||||
/**
|
||||
* PROPOSAL_SUBSTRUCTURE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not sent over wire and just
|
||||
* used internally to handle a proposal substructure like a payload.
|
||||
*/
|
||||
PROPOSAL_SUBSTRUCTURE_V1 = 262,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include <utils/linked_list.h>
|
||||
#include <daemon.h>
|
||||
|
||||
/* IKEv1 situation */
|
||||
#define SIT_IDENTITY_ONLY 1
|
||||
|
||||
typedef struct private_sa_payload_t private_sa_payload_t;
|
||||
|
||||
|
@ -48,7 +50,7 @@ struct private_sa_payload_t {
|
|||
/**
|
||||
* Reserved bits
|
||||
*/
|
||||
bool reserved[7];
|
||||
bool reserved[8];
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
|
@ -58,21 +60,75 @@ struct private_sa_payload_t {
|
|||
/**
|
||||
* Proposals in this payload are stored in a linked_list_t.
|
||||
*/
|
||||
linked_list_t * proposals;
|
||||
linked_list_t *proposals;
|
||||
|
||||
/**
|
||||
* Type of this payload, V1 or V2
|
||||
*/
|
||||
payload_type_t type;
|
||||
|
||||
/**
|
||||
* IKEv1 DOI
|
||||
*/
|
||||
u_int32_t doi;
|
||||
|
||||
/**
|
||||
* IKEv1 situation
|
||||
*/
|
||||
u_int32_t situation;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a IKEv2-SA Payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_sa_payload_t.
|
||||
* Encoding rules for IKEv1 SA payload
|
||||
*/
|
||||
encoding_rule_t sa_payload_encodings[] = {
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_sa_payload_t, next_payload) },
|
||||
/* 8 reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[4]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[6]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[7]) },
|
||||
/* Length of the whole SA payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_sa_payload_t, payload_length) },
|
||||
/* DOI*/
|
||||
{ U_INT_32, offsetof(private_sa_payload_t, doi) },
|
||||
/* Situation*/
|
||||
{ U_INT_32, offsetof(private_sa_payload_t, situation) },
|
||||
/* Proposals are stored in a proposal substructure,
|
||||
offset points to a linked_list_t pointer */
|
||||
{ PROPOSALS_V1, offsetof(private_sa_payload_t, proposals) },
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Next Payload ! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! DOI !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Situation !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ <Proposals> ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encoding rules for IKEv2 SA payload
|
||||
*/
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_sa_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_sa_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
/* 7 Bit reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[2]) },
|
||||
|
@ -144,14 +200,22 @@ METHOD(payload_t, verify, status_t,
|
|||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_sa_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = sa_payload_encodings;
|
||||
*rule_count = countof(sa_payload_encodings);
|
||||
if (this->type == SECURITY_ASSOCIATION_V1)
|
||||
{
|
||||
*rules = encodings_v1;
|
||||
*rule_count = countof(encodings_v1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*rules = encodings_v2;
|
||||
*rule_count = countof(encodings_v2);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_sa_payload_t *this)
|
||||
{
|
||||
return SECURITY_ASSOCIATION;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -175,6 +239,11 @@ static void compute_length(private_sa_payload_t *this)
|
|||
payload_t *current;
|
||||
size_t length = SA_PAYLOAD_HEADER_LENGTH;
|
||||
|
||||
if (this->type == SECURITY_ASSOCIATION_V1)
|
||||
{
|
||||
length = SA_PAYLOAD_V1_HEADER_LENGTH;
|
||||
}
|
||||
|
||||
enumerator = this->proposals->create_enumerator(this->proposals);
|
||||
while (enumerator->enumerate(enumerator, (void **)¤t))
|
||||
{
|
||||
|
@ -270,14 +339,14 @@ METHOD2(payload_t, sa_payload_t, destroy, void,
|
|||
private_sa_payload_t *this)
|
||||
{
|
||||
this->proposals->destroy_offset(this->proposals,
|
||||
offsetof(proposal_substructure_t, destroy));
|
||||
offsetof(payload_t, destroy));
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create()
|
||||
sa_payload_t *sa_payload_create(payload_type_t type)
|
||||
{
|
||||
private_sa_payload_t *this;
|
||||
|
||||
|
@ -298,41 +367,49 @@ sa_payload_t *sa_payload_create()
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = SA_PAYLOAD_HEADER_LENGTH,
|
||||
.proposals = linked_list_create(),
|
||||
.type = type,
|
||||
/* for IKEv1 only */
|
||||
.doi = IKEV1_DOI_IPSEC,
|
||||
.situation = SIT_IDENTITY_ONLY,
|
||||
);
|
||||
|
||||
compute_length(this);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals)
|
||||
sa_payload_t *sa_payload_create_from_proposal_list(payload_type_t type,
|
||||
linked_list_t *proposals)
|
||||
{
|
||||
private_sa_payload_t *this;
|
||||
sa_payload_t *this;
|
||||
enumerator_t *enumerator;
|
||||
proposal_t *proposal;
|
||||
|
||||
this = (private_sa_payload_t*)sa_payload_create();
|
||||
this = sa_payload_create(type);
|
||||
enumerator = proposals->create_enumerator(proposals);
|
||||
while (enumerator->enumerate(enumerator, &proposal))
|
||||
{
|
||||
add_proposal(this, proposal);
|
||||
this->add_proposal(this, proposal);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return &this->public;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal)
|
||||
sa_payload_t *sa_payload_create_from_proposal(payload_type_t type,
|
||||
proposal_t *proposal)
|
||||
{
|
||||
private_sa_payload_t *this;
|
||||
sa_payload_t *this;
|
||||
|
||||
this = (private_sa_payload_t*)sa_payload_create();
|
||||
add_proposal(this, proposal);
|
||||
this = sa_payload_create(type);
|
||||
this->add_proposal(this, proposal);
|
||||
|
||||
return &this->public;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -30,12 +30,17 @@ typedef struct sa_payload_t sa_payload_t;
|
|||
#include <utils/linked_list.h>
|
||||
|
||||
/**
|
||||
* SA_PAYLOAD length in bytes without any proposal substructure.
|
||||
* SECURITY_ASSOCIATION length in bytes without any proposal substructure.
|
||||
*/
|
||||
#define SA_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2-SA Payload.
|
||||
* SECURITY_ASSOCIATION_V1 length in bytes without any proposal substructure.
|
||||
*/
|
||||
#define SA_PAYLOAD_V1_HEADER_LENGTH 12
|
||||
|
||||
/**
|
||||
* Class representing an IKEv1 or IKEv2 SA Payload.
|
||||
*
|
||||
* The SA Payload format is described in RFC section 3.3.
|
||||
*/
|
||||
|
@ -76,17 +81,20 @@ struct sa_payload_t {
|
|||
/**
|
||||
* Creates an empty sa_payload_t object
|
||||
*
|
||||
* @param type SECURITY_ASSOCIATION or SECURITY_ASSOCIATION_V1
|
||||
* @return created sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create(void);
|
||||
sa_payload_t *sa_payload_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates a sa_payload_t object from a list of proposals.
|
||||
*
|
||||
* @param type SECURITY_ASSOCIATION or SECURITY_ASSOCIATION_V1
|
||||
* @param proposals list of proposals to build the payload from
|
||||
* @return sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
|
||||
sa_payload_t *sa_payload_create_from_proposal_list(payload_type_t type,
|
||||
linked_list_t *proposals);
|
||||
|
||||
/**
|
||||
* Creates a sa_payload_t object from a single proposal.
|
||||
|
@ -94,9 +102,11 @@ sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
|
|||
* This is only for convenience. Use sa_payload_create_from_proposal_list
|
||||
* if you want to add more than one proposal.
|
||||
*
|
||||
* @param type SECURITY_ASSOCIATION or SECURITY_ASSOCIATION_V1
|
||||
* @param proposal proposal from which the payload should be built.
|
||||
* @return sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal);
|
||||
sa_payload_t *sa_payload_create_from_proposal(payload_type_t type,
|
||||
proposal_t *proposal);
|
||||
|
||||
#endif /** SA_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -526,11 +526,13 @@ static void build_payloads(private_child_create_t *this, message_t *message)
|
|||
/* add SA payload */
|
||||
if (this->initiator)
|
||||
{
|
||||
sa_payload = sa_payload_create_from_proposal_list(this->proposals);
|
||||
sa_payload = sa_payload_create_from_proposal_list(SECURITY_ASSOCIATION,
|
||||
this->proposals);
|
||||
}
|
||||
else
|
||||
{
|
||||
sa_payload = sa_payload_create_from_proposal(this->proposal);
|
||||
sa_payload = sa_payload_create_from_proposal(SECURITY_ASSOCIATION,
|
||||
this->proposal);
|
||||
}
|
||||
message->add_payload(message, (payload_t*)sa_payload);
|
||||
|
||||
|
|
|
@ -132,7 +132,8 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
|
|||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
sa_payload = sa_payload_create_from_proposal_list(proposal_list);
|
||||
sa_payload = sa_payload_create_from_proposal_list(SECURITY_ASSOCIATION,
|
||||
proposal_list);
|
||||
proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy));
|
||||
}
|
||||
else
|
||||
|
@ -142,7 +143,8 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
|
|||
/* include SPI of new IKE_SA when we are rekeying */
|
||||
this->proposal->set_spi(this->proposal, id->get_responder_spi(id));
|
||||
}
|
||||
sa_payload = sa_payload_create_from_proposal(this->proposal);
|
||||
sa_payload = sa_payload_create_from_proposal(SECURITY_ASSOCIATION,
|
||||
this->proposal);
|
||||
}
|
||||
message->add_payload(message, (payload_t*)sa_payload);
|
||||
|
||||
|
|
Loading…
Reference in New Issue