xref: /openbsd/sbin/isakmpd/DESIGN-NOTES (revision 76d0caae)
1$OpenBSD: DESIGN-NOTES,v 1.25 2006/06/02 19:35:55 hshoexer Exp $
2$EOM: DESIGN-NOTES,v 1.48 1999/08/12 22:34:25 niklas Exp $
3
4General coding conventions
5--------------------------
6GNU indentation, Max 80 characters per line, KNF comments, mem* instead of b*,
7BSD copyright, one header per module specifying the API.
8Multiple inclusion protection like this:
9
10#ifndef _HEADERNAME_H_
11#define _HEADERNAME_H_
12
13... Here comes the bulk of the header ...
14
15#endif /* _HEADERNAME_H_ */
16
17Start all files with RCS ID tags.
18
19GCC -Wall clean, ANSI prototypes.  System dependent facilities should be
20named sysdep_* and be placed in sysdep.c.  Every C file should include
21sysdep.h as the first isakmpd include file.  Primary target systems are OpenBSD
22and Linux, but porting to Microsoft Windows variants should not be made
23overly difficult.
24
25Note places which need reconsiderations with comments starting with the
26string "XXX", e.g.
27
28/* XXX Not implemented yet.  */
29
30TOC
31---
32app.c		Application support.
33attribute.c	Attribute handling.
34cert.c		Dispatching certificate related functions to the according
35		module based on the encoding.
36conf.c		Interface to isakmpd configuration.
37connection.c	Handle the high-level connection concept.
38constants.c	Value to name map of constants.
39cookie.c	Cookie generation.
40crypto.c	Generic cryptography.
41dh.c		Diffie-Hellman exchange logic.
42dnssec.c	IKE authentication using signed DNS KEY RRs.
43doi.c		Generic handling of different DOIs.
44exchange.c	Exchange state machinery.
45exchange_num.cst
46		Some constants used for exchange scripts.
47field.c		Generic handling of fields.
48genconstants.sh
49		Generate constant files from .cst source.
50genfields.sh	Generate field description files from .fld source.
51gmp_util.c	Utilities to ease interfacing to GMP.
52hash.c		Generic hash handling.
53if.c		Network interface details.
54ike_aggressive.c
55		IKE's aggressive mode exchange logic.
56ike_auth.c	IKE authentication method abstraction.
57ike_main_mode.c	IKE's main mode exchange logic.
58ike_phase_1.c	Common parts IKE's main & aggressive modes' exchange logic.
59ike_quick_mode.c
60		IKE's quick mode logic.
61init.c		Initialization of all modules (might be autogenned in the
62		future).
63ipsec.c		The IPsec DOI.
64ipsec_fld.fld	Description of IPsec DOI-specific packet layouts.
65ipsec_num.cst	Constants defined by the IPsec DOI.
66isakmp_doi.c	The ISAKMP pseudo-DOI.
67isakmp_fld.fld	Generic packet layout.
68isakmp_num.cst	ISAKMP constants.
69isakmpd.c	Main loop.
70key.c		Generic key handling.
71libcrypto.c	Initialize crypto (OpenSSL).
72log.c		Logging of exceptional or informational messages.
73math_2n.c	Polynomial math.
74math_ec2n.c	Elliptic curve math.
75math_group.c	Group math.
76message.c	Generic message handling.
77pf_key_v2.c	Interface with PF_KEY sockets (for use with IPsec).
78policy.c	Keynote glue.
79prf.c		Pseudo random functions.
80sa.c		Handling of Security Associations (SAs).
81sysdep/*/sysdep.c
82		System dependent stuff.
83timer.c		Timed events.
84transport.c	Generic transport handling.
85udp.c		The UDP transport.
86ui.c		The "User Interface", i.e. the FIFO command handler.
87util.c		Miscellaneous utility functions.
88x509.c		Encoding/Decoding X509 Certificates and related structures.
89
90Central datatypes
91-----------------
92
93struct connection	Persistent connections.
94struct constant_map	A map from constants to their ASCII names.
95struct crypto_xf	A crypto class
96struct doi		The DOI function switch
97struct event		An event that is to happen at some point in time.
98struct exchange		A description of an exchange while it is performed.
99struct field		A description of an ISAKMP field.
100struct group		A class abstracting out Oakley group operations
101struct hash		A hashing class
102struct ipsec_exch	IPsec-specific exchange fields.
103struct ipsec_proto	IPsec-specific protocol attributes.
104struct ipsec_sa		IPsec-specific SA stuff.
105struct message		A generic ISAKMP message.
106struct payload		A "fat" payload reference pointing into message buffers
107struct prf		A pseudo random function class
108struct proto		Per-protocol attributes.
109struct post_send	Post-send function chain node.
110struct sa		A security association.
111struct transport	An ISAKMP transport, i.e. a channel where ISAKMP
112			messages are passed (not necessarily connection-
113			oriented).  This is an abstract class, serving as
114			a superclass to the different specific transports.
115
116SAs & exchanges
117---------------
118
119struct exchange		Have all fields belonging to a simple exchange
120			+ a list of all the SAs being negotiated.
121			Short-lived.
122struct sa		Only hold SA-specific stuff.  Lives longer.
123
124In order to recognize exchanges and SAs it is good to know what constitutes
125their identities:
126
127Phase 1 exchange	Cookie pair (apart from the first message of course,
128			where the responder cookie is zero.
129
130ISAKMP SA		Cookie pair.  I.e. there exists a one-to-one
131			mapping to the negotiation in this case.
132
133Phase 2 exchange	Cookie pair + message ID.
134
135Generic SA		Cookie pair + message ID + SPI.
136
137However it would be really nice to have a name of any SA that is natural
138to use for human beings, for things like deleting SAs manually.  The simplest
139ID would be the struct sa address.  Another idea would be some kind of sequence
140number, either global or per-destination.  Right now I have introduced a name
141for SAs, non-unique, that binds together SAs and their configuration
142parameters.  This means both manual exchange runs and rekeying are simpler.
143Both struct exchange and struct sa does hold a reference count, but this is
144not entirely like a reference count in the traditional meaning where
145every reference gets counted.  Perhaps it will be in the future, but for now
146we increment the count at allocation time and at times we schedule events
147that might happen sometime in the future where we will need the structure.
148These events then release its reference when done.  This way intermediate
149deallocation of these structures are OK.
150
151The basic idea of control flow
152------------------------------
153
154The main loop just waits for events of any kind.  Supposedly a message
155comes in, then the daemon looks to see if the cookies describes an
156existing ISAKMP SA, if they don't and the rcookie is zero, it triggers a
157setup of a new ISAKMP SA.  An exhaustive validation phase of the message
158is gone through at this stage.  If anything goes wrong, we drop the packet
159and probably send some notification back.  After the SA is found we try to
160locate the exchange object and advance its state, else we try to create a
161new exchange.
162
163Need exchanges be an abstraction visible in the code?  If so an exchange is
164roughly a very simple FSM (only timeouts and retransmissions are events that
165does not just advance the state through a sequential single path).  The
166informational exchange is such a special case, I am not sure it's interesting
167to treat as an exchange in the logic of the implementation.  The only reason
168to do so would be to keep the implementation tightly coupled to the
169specification for ease of understanding.  As the code looks now, exchanges
170*are* an abstraction in the code, and it has proven to be a rather nice
171way of having things.
172
173When the exchange has been found the exchange engine "runs" a script which
174steps forward for each incoming message, and on each reply to them.
175
176Payload parsing details
177-----------------------
178
179After the generic header has been validated, we do a generic payload
180parsing pass over the message and sort out the payloads into buckets indexed
181by the payload type.  Note that proposals and transforms are part of the SA
182payloads.  We then pass over them once more validating each payload
183in numeric payload type order.  This makes SA payloads come naturally first.
184
185Messages
186--------
187
188I am not sure there is any use in sharing the message structure for both
189incoming and outgoing messages but I do it anyhow.  Specifically there are
190certain fields which only makes sense in one direction.  Incoming messages
191only use one segment in the iovec vector, while outgoing has one segment per
192payload as well as one for the ISAKMP header.  The iovec vector is
193reallocated for each payload added, maybe we should do it in chunks of a
194number of payloads instead, like 10 or so.
195
196Design "errors"
197---------------
198
199Currently there are two "errors" in our design.  The first one is that the
200coupling between the IPsec DOI and IKE is tight.  It should be separated by
201a clean interface letting other key exchange models fit in instead of IKE.
202The second problem is that we need a protocol-specific opaque SA part
203in the DOI specific one.  Now both IPsec ESP attributes takes place even
204in ISAKMP SA structures.
205
206User control
207------------
208
209In order to control the daemon you send commands through a FIFO called
210isakmpd.fifo.  The commands are one-letter codes followed by arguments.
211For now, eleven such commands are implemented:
212
213c	connect		Establish a connection with a peer
214C	configure	Add or remove configuration entries
215d	delete		Delete an SA given cookies and message-IDs
216D	debug		Change logging level for a debug class
217p	packet capture	Enable/disable packet capture feature
218r	report		Report status information of the daemon
219t	teardown	Teardown a connection
220Q       quit            Quit the isakmpd process
221R       reinitialize    Reinitialize isakmpd (re-read configuration file)
222S       report SA       Report SA information to file /var/run/isakmp_sa
223T       teardown all    Teardown all Phase 2 connections
224
225For example you can do:
226
227c ISAKMP-peer
228
229In order to delete an SA you use the 'd' command.  However this is not yet
230supported.
231
232To alter the level of debugging in the "LOG_MISC" logging class to 99 you do:
233
234D 0 99
235
236The report command is just an "r", and results in a list of active exchanges
237and security associations.
238
239The "C" command takes 3 subcommands: set, rm and rms, for adding and removing
240entries + remove complete sections respectively.  Examples:
241
242C set [Net-A]:Address=192.168.0.0
243C rm [Net-A]:Address
244C rms [Net-A]
245
246All these commands are atomic, i.e. they are not collected into larger
247transactions, which there should be a way to do, but currently isn't.
248
249The FIFO UI is also described in the isakmpd(8) man page.
250
251In addition to giving commands over the FIFO, you may send signals to the
252daemon. Currently two such signals are implemented:
253
254SIGHUP 	  Re-initialize isakmpd (not fully implemented yet)
255SIGUSR1   Generate a report, much as the "r" FIFO command.
256
257For example, to generate a report, you do:
258
259unix# kill -USR1 <PID of isakmpd process>
260
261The constant descriptions
262-------------------------
263
264We have invented a simple constant description language, for the sake
265of easily getting textual representations of manifest constants.
266The syntax is best described by an example:
267
268GROUP
269  CONSTANT_A		1
270  CONSTANT_B		2
271.
272
273This defines a constant map "group" with the following two defines:
274
275#define GROUP_CONSTANT_A 1
276#define GROUP_CONSTANT_B 2
277
278We can now get the textual representation by:
279
280  cp = constant_name (group, foo);
281
282Here foo is an integer with either of the two constants as a value.
283
284The field descriptions
285----------------------
286
287There is language for describing header and payload layouts too,
288similar to the constant descriptions.  Here too I just show an example:
289
290RECORD_A
291  FIELD_A	raw 4
292  FIELD_B	num 2
293  FIELD_C	mask 1		group_c_cst
294  FIELD_D	ign 1
295  FIELD_E	cst 2		group_e1_cst,group_e2_cst
296.
297
298RECORD_B : RECORD_A
299  FIELD_F	raw
300.
301
302This creates some utility constants like RECORD_A_SZ, RECORD_A_FIELD_A_LEN,
303RECORD_A_FIELD_A_OFF, RECORD_A_FIELD_B_LEN etc.  The *_OFF contains the
304octet offset into the record and the *_LEN constants are the lengths.
305The type fields can be: raw, num, mask, ign & cst.  Raw are used for
306octet buffers, num for (unsigned) numbers of 1, 2 or 4 octet's length
307in network byteorder, mask is a bitmask where the bit values have symbols
308coupled to them via the constant maps given after the length in octets
309(also 1, 2 or 4).  Ign is just a filler type, ot padding and lastly cst
310denotes constants whose values can be found in the given constant map(s).
311The last field in a record can be a raw, without a length, then just an
312_OFF symbol will be generated.  You can offset the first symbol to the
313size of another record, like is done above for RECORD_B, i.e. in that
314case RECORD_A_SZ == RECORD_B_FIELD_F_OFF.  All this data are collected
315in struct field arrays which makes it possible to symbolically print out
316entire payloads in readable form via field_dump_payload.
317
318Configuration
319-------------
320
321Internally isakmpd uses a section-tag-value triplet database for
322configuration.  Currently this happen to map really well to the
323configuration file format, which on the other hand does not map
324equally well to humans.  It is envisioned that the configuration
325database should be dynamically modifiable, and through a lot of
326different mechanisms.  Therefore we have designed an API for this
327purpose.
328
329int conf_begin ();
330int conf_set (int transaction, char *section, char *tag, char *value,
331	      int override);
332int conf_remove (int transaction, char *section, char *tag);
333int conf_remove_section (int transaction, char *section);
334int conf_end (int transaction, int commit);
335
336The caller will always be responsible for the memory management of the
337passed strings, conf_set will copy the values, and not use the original
338strings after it has returned.  Return value will be zero on success and
339non-zero otherwise.  Note that the conf_remove* functions consider not
340finding anything to remove as failure.
341
342Identification
343--------------
344
345ISAKMP supports a lot of identity types, and we should too of course.
346
347* Phase 1, Main mode or Aggressive mode
348
349Today when we connect we do it based on the peer's IP address.  That does not
350automatically mean we should do policy decision based on IPs, rather we should
351look at the ID the peer provide and get policy info keyed on that.
352
353Perhaps we get an ID saying the peer is FQDN niklas.hallqvist.se, then our
354policy rules might look like:
355
356[IQ_FQDN]
357# If commented, internal verification is used
358#Verificator=	verify_fqdn
359Accept=		no
360
361[ID_FQDN niklas.hallqvist.se]
362Policy=		MY_POLICY_001
363
364[MY_POLICY_001]
365# Whatever policy rules we might have.
366Accept=		yes
367
368Which means niklas.hallqvist.se is allowed to negotiate SAs with us, but
369noone else.
370
371* Phase 2, Quick mode
372
373In quick mode the identities are implicitly the IP addresses of the peers,
374which must mean the IP addresses actually used for the ISAKMP tunnel.
375Otherwise we today support IPV4_ADDR & IPV4_ADDR_SUBNET as ID types.
376
377X509-Certificates
378-----------------
379To use RSA Signature mode you are required to generate certificates.
380This can be done with ssleay, see man ssl. But the X509 certificates
381require a subjectAltname extension that can either be an IPV4 address,
382a User-FQDN or just FQDN.  ssleay can not create those extension,
383instead use the x509test program in src/regress/sbin/isakmpd/x509 to
384modify an existing certificate.  It will insert the subjectAltname
385extension and sign it with the provided private Key.  The resulting
386certificate then needs to be stored in the directory pointed to by
387"Certs-directory" in section "X509-certificates".
388
389License to use
390--------------
391/*
392 * Copyright (c) 1999 Niklas Hallqvist.  All rights reserved.
393 *
394 * Redistribution and use in source and binary forms, with or without
395 * modification, are permitted provided that the following conditions
396 * are met:
397 * 1. Redistributions of source code must retain the above copyright
398 *    notice, this list of conditions and the following disclaimer.
399 * 2. Redistributions in binary form must reproduce the above copyright
400 *    notice, this list of conditions and the following disclaimer in the
401 *    documentation and/or other materials provided with the distribution.
402 *
403 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
404 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
405 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
406 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
407 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
408 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
409 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
410 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
411 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
412 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
413 */
414
415