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