File: ikev2.h

package info (click to toggle)
libreswan 5.2-2.3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 81,644 kB
  • sloc: ansic: 129,988; sh: 32,018; xml: 20,646; python: 10,303; makefile: 3,022; javascript: 1,506; sed: 574; yacc: 511; perl: 264; awk: 52
file content (243 lines) | stat: -rw-r--r-- 7,294 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/*
 * IKEv2 functions: that ikev2_parent.c/ikev2_child.c needs.
 * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com>
 * Copyright (C) 2013 Matt Rogers <mrogers@redhat.com>
 * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org>
 * Copyright (C) 2018 Paul Wouters <pwouters@redhat.com>
 * Copyright (C) 2017-2019 Andrew Cagney <cagney@gnu.org>
 * Copyright (C) 2018 Sahana Prasad <sahana.prasad07@gmail.com>
 * Copyright (C) 2020 Yulia Kuzovkova <ukuzovkova@gmail.com>
 */

#ifndef IKEV2_H
#define IKEV2_H

#include "fd.h"

#include "message_role.h"

struct pending;
struct pluto_crypto_req;
struct spd;
struct crypt_mac;
struct hash_desc;
struct payload_digest;
struct ikev2_ipseckey_dns;
struct hash_signature;
enum payload_security;
struct msg_digest;
struct state;
struct ike_sa;
struct child_sa;
struct pbs_in;
struct dh_desc;
struct connection;

typedef stf_status crypto_transition_fn(struct state *st, struct msg_digest *md,
					struct pluto_crypto_req *r);

void ikev2_process_packet(struct msg_digest *mdp);

void process_protected_v2_message(struct ike_sa *ike, struct msg_digest *md);

typedef stf_status ikev2_state_transition_fn(struct ike_sa *ike,
					     struct child_sa *child, /* could be NULL */
					     struct msg_digest *md /* could be NULL */);

extern void complete_v2_state_transition(struct ike_sa *ike,
					 struct msg_digest *mdp,
					 stf_status result);

void schedule_reinitiate_v2_ike_sa_init(struct ike_sa *ike,
					stf_status (*resume)(struct ike_sa *ike));

struct crypt_mac ikev2_rsa_sha1_hash(const struct crypt_mac *hash);

extern void ikev2_derive_child_keys(struct ike_sa *ike, struct child_sa *child);

bool ikev2_parse_cp_r_body(struct payload_digest *cp_pd, struct child_sa *child);

struct ikev2_expected_payloads {
	/* For liveness, so that no payloads means no payloads */
	bool exact_match;
	/* required payloads: one of each type must be present */
	lset_t required;
	/* optional payloads: up to one of each type can be present */
	lset_t optional;
	/* required notification, if not v2N_NOTHING_WRONG */
	v2_notification_t notification;
};

/* Short forms for building payload type sets */

#define v2P(N) LELEM(ISAKMP_NEXT_v2##N)

struct v2_transition {
	const char *const story;	/* state transition story (not state_story[]) */
	const struct finite_state *to;
	struct {
		bool release_whack;
	} flags;

	/*
	 * The message type being exchanged.
	 *
	 * Incoming message must match RECV_ROLE.
	 *
	 * When RECV_ROLE is NO_MESSAGE, the transition is for a new
	 * exchange.
	 */
	const enum ikev2_exchange exchange;
	enum message_role recv_role;

	/*
	 * The message contents.
	 *
	 * These field names, what ever they are, should exactly match
	 * equivalent struct payload_summary fields found in struct
	 * msg_digest.
	 */
	struct ikev2_expected_payloads message_payloads;
	struct ikev2_expected_payloads encrypted_payloads; /* contents of SK payload */

	const enum event_type timeout_event;
	ikev2_state_transition_fn *const processor;

	/*
	 * When non-NULL, use this to log the IKE SA's successful
	 * state transition.
	 */
	void (*llog_success)(struct ike_sa *ike);
};

struct v2_transitions {
	const struct v2_transition *list;
	size_t len;
};

struct v2_exchange {
	const enum ikev2_exchange type;
	const char *subplot;
	bool secured;
	struct {
		const struct v2_transition *transition;
		const struct finite_state *from[3];	/* grow as needed */
	} initiate;
	const struct v2_transitions *responder;
	const struct v2_transitions *response;
};

struct v2_exchanges {
	const struct v2_exchange *const *list;
	size_t len;
};

#define V2_EXCHANGE(KIND, SUBPLOT, NEXT_STORY, I_CAT, IR_CAT, SECURED, ...) \
									\
	static const struct v2_transitions v2_##KIND##_response_transitions = { \
		ARRAY_REF(v2_##KIND##_response_transition),		\
	};								\
									\
	static const struct v2_transitions v2_##KIND##_responder_transitions = { \
		ARRAY_REF(v2_##KIND##_responder_transition),		\
	};								\
									\
	const struct finite_state state_v2_##KIND##_I = {		\
		.kind = STATE_V2_##KIND##_I,				\
		.name = #KIND"_I",					\
		.short_name = #KIND"_I",				\
		.story = "sent "#KIND" request",			\
		.category = I_CAT,					\
		.ike_version = IKEv2,					\
		.v2.secured = SECURED,					\
	};								\
									\
	const struct finite_state state_v2_##KIND##_IR = {		\
		.kind = STATE_V2_##KIND##_IR,				\
		.name = #KIND"_IR",					\
		.short_name = #KIND"_IR",				\
		.story = "processed "#KIND" response"NEXT_STORY,	\
		.category = IR_CAT,					\
		.ike_version = IKEv2,					\
		.v2.secured = SECURED,					\
	};								\
									\
	const struct v2_exchange v2_##KIND##_exchange = {		\
		.type = ISAKMP_v2_##KIND,				\
		.subplot = SUBPLOT,					\
		.secured = SECURED,					\
		.initiate.transition = &v2_##KIND##_initiate_transition, \
		.initiate.from = { __VA_ARGS__ },			\
		.responder = &v2_##KIND##_responder_transitions,	\
		.response = &v2_##KIND##_response_transitions,		\
	}

#define V2_STATE(KIND, STORY, CAT, SECURED, ...)			\
									\
	static const struct v2_exchange *v2_##KIND##_responder_exchange[] = { \
		__VA_ARGS__						\
	};								\
									\
	static const struct v2_exchanges v2_##KIND##_responder_exchanges = { \
		ARRAY_REF(v2_##KIND##_responder_exchange),		\
	};								\
									\
	const struct finite_state state_v2_##KIND = {			\
		.kind = STATE_V2_##KIND,				\
		.name = #KIND,						\
		.short_name = #KIND,					\
		.story = STORY,						\
		.category = CAT,					\
		.ike_version = IKEv2,					\
		.v2.ike_exchanges = &v2_##KIND##_responder_exchanges,	\
		.v2.secured = SECURED,					\
	}

extern void init_ikev2(void);

struct payload_summary ikev2_decode_payloads(struct logger *log,
					     struct msg_digest *md,
					     struct pbs_in *in_pbs,
					     enum next_payload_types_ikev2 np);

void v2_dispatch(struct ike_sa *ike, struct msg_digest *md,
		 const struct v2_transition *transition);

bool v2_accept_ke_for_proposal(struct ike_sa *ike,
			       struct state *st,
			       struct msg_digest *md,
			       const struct dh_desc *accepted_dh,
			       enum payload_security security);
/*
 * See 2.21. Error Handling.  In particular the IKE_AUTH discussion.
 */

bool v2_notification_fatal(v2_notification_t n);

bool already_has_larval_v2_child(struct ike_sa *ike, const struct connection *c);

void llog_v2_success_exchange_sent_to(struct ike_sa *ike);
void llog_v2_success_exchange_processed(struct ike_sa *ike);
void llog_v2_success_state_story(struct ike_sa *ike);
void ldbg_v2_success(struct ike_sa *ike);
void llog_v2_success_state_story_to(struct ike_sa *ike);

bool accept_v2_notification(v2_notification_t n,
			    struct logger *logger,
			    struct msg_digest *md,
			    bool enabled);

void start_v2_exchange(struct ike_sa *ike, const struct v2_exchange *exchange, where_t where);
void start_v2_transition(struct ike_sa *ike,
			 const struct v2_transition *transition,
			 struct msg_digest *md, where_t where);

stf_status next_v2_exchange(struct ike_sa *ike, struct msg_digest *md,
			    const struct v2_exchange *exchange,
			    where_t where);

extern void jam_v2_transition(struct jambuf *buf, const struct v2_transition *transition);

bool v2_ike_sa_can_initiate_exchange(const struct ike_sa *ike, const struct v2_exchange *exchange);

#endif