File: ikev2.h

package info (click to toggle)
libreswan 4.3-1%2Bdeb11u4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 62,688 kB
  • sloc: ansic: 108,293; sh: 25,973; xml: 11,756; python: 10,230; makefile: 1,580; javascript: 1,353; yacc: 825; sed: 647; perl: 584; lex: 159; awk: 156
file content (294 lines) | stat: -rw-r--r-- 10,308 bytes parent folder | download
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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/*
 * 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"

struct pending;
struct pluto_crypto_req;
struct spd_route;
struct crypt_mac;
struct hash_desc;
struct payload_digest;

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 ikev2_process_state_packet(struct ike_sa *ike, struct state *st,
				struct msg_digest *mdp);

/* extern initiator_function ikev2_parent_outI1; */
extern void ikev2_parent_outI1(struct fd *whack_sock,
			      struct connection *c,
			      struct state *predecessor,
			      lset_t policy,
			      unsigned long try,
			      const threadtime_t *inception,
			      chunk_t sec_label);

extern void log_ipsec_sa_established(const char *m, const struct state *st);

extern void complete_v2_state_transition(struct state *st,
					 struct msg_digest *mdp,
					 stf_status result);

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 ikev2_state_transition_fn process_encrypted_informational_ikev2;

extern ikev2_state_transition_fn ikev2_child_ike_inIoutR;
extern ikev2_state_transition_fn ikev2_child_ike_inR;
extern ikev2_state_transition_fn ikev2_child_inR;
extern ikev2_state_transition_fn ikev2_child_inIoutR;

extern ikev2_state_transition_fn ikev2_parent_inI1outR1;
extern ikev2_state_transition_fn ikev2_auth_initiator_process_failure_notification;
extern ikev2_state_transition_fn ikev2_auth_initiator_process_unknown_notification;
extern ikev2_state_transition_fn ikev2_ike_sa_process_intermediate_request_no_skeyid;
extern ikev2_state_transition_fn ikev2_ike_sa_process_auth_request_no_skeyid;
extern ikev2_state_transition_fn ikev2_ike_sa_process_auth_request;
extern ikev2_state_transition_fn ikev2_parent_inR1outI2;
extern ikev2_state_transition_fn ikev2_parent_inR2;

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

bool record_v2_IKE_SA_INIT_request(struct ike_sa *ike);
extern ikev2_state_transition_fn process_IKE_SA_INIT_v2N_INVALID_KE_PAYLOAD_response;

extern void ikev2_initiate_child_sa(struct pending *p);

void ikev2_rekey_ike_start(struct ike_sa *ike);

extern void ikev2_child_outI(struct state *st);

extern stf_status ikev2_parent_inI2outR2_id_tail(struct msg_digest * md);

/* MAGIC: perform f, a function that returns notification_t
 * and return from the ENCLOSING stf_status returning function if it fails.
 */
/* macro that returns STF_STATUS on failure */
#define RETURN_STF_FAILURE_STATUS(f) { \
	stf_status res = (f); \
	if (res != STF_OK) { \
		return res; \
	} \
}

struct ikev2_proposal;
struct ikev2_proposals;

void DBG_log_ikev2_proposal(const char *prefix, const struct ikev2_proposal *proposal);

void free_ikev2_proposal(struct ikev2_proposal **proposal);
void free_ikev2_proposals(struct ikev2_proposals **proposals);

/*
 * On-demand, generate proposals for either the IKE SA or the CHILD
 * SA.
 *
 * For CHILD SAs, two different proposal suites are used: during the
 * IKE_AUTH exchange a stripped down proposal that excludes DH; and
 * during the CREATE_CHILD_SA exchange DH a mashed up proposal that
 * can include the IKE SA's latest DH.
 *
 * This is done on-demand as, only at the point where the IKE or CHILD
 * SA is being instantiated, is it clear what proposals are needed.
 * For instance, when a CHILD SA shares an existing IKE SA, the CHILD
 * won't need IKE proposals but will need the IKE SA's DH.
 *
 * XXX: Should the CREATE CHILD SA proposals be stored in the state?
 */

struct ikev2_proposals *get_v2_ike_proposals(struct connection *c, const char *why,
					     struct logger *logger);
struct ikev2_proposals *get_v2_ike_auth_child_proposals(struct connection *c, const char *why,
							struct logger *logger);
struct ikev2_proposals *get_v2_create_child_proposals(struct connection *c, const char *why,
						      const struct dh_desc *default_dh,
						      struct logger *logger);

bool ikev2_emit_sa_proposal(struct pbs_out *pbs,
			    const struct ikev2_proposal *proposal,
			    const chunk_t *local_spi);

bool ikev2_emit_sa_proposals(struct pbs_out *outs,
			     const struct ikev2_proposals *proposals,
			     const chunk_t *local_spi);

const struct dh_desc *ikev2_proposals_first_dh(const struct ikev2_proposals *proposals,
					       struct logger *logger);

bool ikev2_proposals_include_modp(const struct ikev2_proposals *proposals,
				  oakley_group_t modp);

stf_status ikev2_process_sa_payload(const char *what,
				    pb_stream *sa_payload,
				    bool expect_ike,  /* IKE vs ESP or AH */
				    bool expect_spi,
				    bool expect_accepted,
				    bool opportunistic,
				    struct ikev2_proposal **chosen,
				    const struct ikev2_proposals *local_proposals,
				    struct logger *logger);

bool ikev2_proposal_to_proto_info(const struct ikev2_proposal *proposal,
				  struct ipsec_proto_info *proto_info,
				  struct logger *logger);

bool ikev2_proposal_to_trans_attrs(const struct ikev2_proposal *chosen,
				   struct trans_attrs *ta_out, struct logger *logger);

struct ipsec_proto_info *ikev2_child_sa_proto_info(struct child_sa *child, lset_t policy);

ipsec_spi_t ikev2_child_sa_spi(const struct spd_route *spd_route, lset_t policy,
			       struct logger *logger);

extern bool ikev2_decode_peer_id(struct msg_digest *md);

extern void ikev2_log_parentSA(const struct state *st);

extern bool ikev2_calculate_rsa_hash(struct ike_sa *ike,
				     const struct crypt_mac *idhash,
				     pb_stream *a_pbs,
				     chunk_t *no_ppk_auth /* optional output */,
				     const struct hash_desc *hash_algo);

extern bool ikev2_emit_psk_auth(enum keyword_authby authby,
				const struct ike_sa *ike,
				const struct crypt_mac *idhash,
				pb_stream *a_pbs);

extern bool ikev2_create_psk_auth(enum keyword_authby authby,
				  const struct ike_sa *ike,
				  const struct crypt_mac *idhash,
				  chunk_t *additional_auth /* output */);

extern stf_status ikev2_verify_rsa_hash(struct ike_sa *ike,
					const struct crypt_mac *idhash,
					pb_stream *sig_pbs,
					const struct hash_desc *hash_algo);

extern stf_status ikev2_verify_ecdsa_hash(struct ike_sa *ike,
					const struct crypt_mac *idhash,
					pb_stream *sig_pbs,
					const struct hash_desc *hash_algo);

extern bool ikev2_verify_psk_auth(enum keyword_authby authby,
				  const struct ike_sa *ike,
				  const struct crypt_mac *idhash,
				  pb_stream *sig_pbs);

extern void ikev2_derive_child_keys(struct child_sa *child);

stf_status ikev2_child_sa_respond(struct ike_sa *ike,
				  struct child_sa *child,
				  struct msg_digest *md,
				  pb_stream *outpbs,
				  enum isakmp_xchg_types isa_xchg);

void v2_schedule_replace_event(struct state *st);

bool emit_v2_child_configuration_payload(struct connection *c,
					 struct child_sa *child,
					 pb_stream *outpbs);

bool ikev2_parse_cp_r_body(struct payload_digest *cp_pd, struct state *st);

struct ikev2_payload_errors {
	bool bad;
	lset_t excessive;
	lset_t missing;
	lset_t unexpected;
	v2_notification_t notification;
};

struct ikev2_expected_payloads {
	/* 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;
};

struct state_v2_microcode {
	const char *const story;	/* state transition story (not state_story[]) */
	const enum state_kind state;
	const enum state_kind next_state;
	const enum isakmp_xchg_types recv_type;
	enum message_role recv_role;
	const lset_t flags;

	/*
	 * During a successful state transition is an out going
	 * message expected and, if so, is it a request or response.
	 *
	 * Old code had a simple flag (SMF2_SEND) and then tried to
	 * reverse engineer this value from the incoming message.
	 * While in theory possible, it didn't seem to go well.  For
	 * instance, because the code didn't clearly differentiate
	 * between a FAKE_MD (created because old code insisted on
	 * there always being an incoming message) and a real request
	 * or response it ended up trying to use STATE_KIND to figure
	 * things out.  While perhaps it is possible to make all this
	 * work, spelling it out seems clearer.
	 */
	enum message_role send;

	/*
	 * 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;
};

void ikev2_copy_cookie_from_sa(const struct ikev2_proposal *accepted_ike_proposal,
				ike_spi_t *cookie);

void ikev2_ike_sa_established(struct ike_sa *ike,
			      const struct state_v2_microcode *svm,
			      enum state_kind new_state);

struct ikev2_ipseckey_dns;

extern stf_status ikev2_process_child_sa_pl(struct ike_sa *ike, struct child_sa *child,
					    struct msg_digest *md, bool expect_accepted);

extern bool emit_v2KE(chunk_t *g, const struct dh_desc *group, pb_stream *outs);

extern void init_ikev2(void);

extern void ikev2_record_newaddr(struct state *st, void *arg_ip);
extern void ikev2_record_deladdr(struct state *st, void *arg_ip);
extern void ikev2_addr_change(struct state *st);

void jam_v2_stf_status(struct jambuf *buf, unsigned ret);

void v2_event_sa_rekey(struct state *st);
void v2_event_sa_replace(struct state *st);

/* used by parent and child to emit v2N_IPCOMP_SUPPORTED if appropriate */
bool emit_v2N_compression(struct state *cst,
			bool OK,
			pb_stream *s);

#endif