xref: /openbsd-src/sbin/isakmpd/ike_aggressive.c (revision 2f1aa25b0f696ec888d7fe80b22e760eed552d21)
1*2f1aa25bSmpi /* $OpenBSD: ike_aggressive.c,v 1.13 2018/01/15 09:54:48 mpi Exp $	 */
2bdbf6df3Sniklas /* $EOM: ike_aggressive.c,v 1.4 2000/01/31 22:33:45 niklas Exp $	 */
3511b8570Sniklas 
4511b8570Sniklas /*
5511b8570Sniklas  * Copyright (c) 1999 Niklas Hallqvist.  All rights reserved.
6bdbf6df3Sniklas  * Copyright (c) 1999 Angelos D. Keromytis.  All rights reserved.
7511b8570Sniklas  *
8511b8570Sniklas  * Redistribution and use in source and binary forms, with or without
9511b8570Sniklas  * modification, are permitted provided that the following conditions
10511b8570Sniklas  * are met:
11511b8570Sniklas  * 1. Redistributions of source code must retain the above copyright
12511b8570Sniklas  *    notice, this list of conditions and the following disclaimer.
13511b8570Sniklas  * 2. Redistributions in binary form must reproduce the above copyright
14511b8570Sniklas  *    notice, this list of conditions and the following disclaimer in the
15511b8570Sniklas  *    documentation and/or other materials provided with the distribution.
16511b8570Sniklas  *
17511b8570Sniklas  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18511b8570Sniklas  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19511b8570Sniklas  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20511b8570Sniklas  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21511b8570Sniklas  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22511b8570Sniklas  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23511b8570Sniklas  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24511b8570Sniklas  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25511b8570Sniklas  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26511b8570Sniklas  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27511b8570Sniklas  */
28511b8570Sniklas 
29511b8570Sniklas /*
30511b8570Sniklas  * This code was written under funding by Ericsson Radio Systems.
31511b8570Sniklas  */
32511b8570Sniklas 
33511b8570Sniklas #include <sys/types.h>
34511b8570Sniklas #include <netinet/in.h>
35511b8570Sniklas #include <stdlib.h>
36511b8570Sniklas #include <string.h>
37511b8570Sniklas 
38511b8570Sniklas #include "attribute.h"
39511b8570Sniklas #include "conf.h"
40511b8570Sniklas #include "constants.h"
41511b8570Sniklas #include "crypto.h"
42511b8570Sniklas #include "dh.h"
43511b8570Sniklas #include "doi.h"
44511b8570Sniklas #include "exchange.h"
45511b8570Sniklas #include "hash.h"
46511b8570Sniklas #include "ike_auth.h"
47511b8570Sniklas #include "ike_aggressive.h"
48511b8570Sniklas #include "ike_phase_1.h"
49511b8570Sniklas #include "ipsec.h"
50511b8570Sniklas #include "ipsec_doi.h"
51511b8570Sniklas #include "isakmp.h"
52511b8570Sniklas #include "log.h"
53511b8570Sniklas #include "message.h"
543ca9511cSho #include "nat_traversal.h"
55511b8570Sniklas #include "prf.h"
56511b8570Sniklas #include "sa.h"
57511b8570Sniklas #include "transport.h"
58511b8570Sniklas #include "util.h"
59511b8570Sniklas 
60511b8570Sniklas static int	initiator_recv_SA_KE_NONCE_ID_AUTH(struct message *);
61511b8570Sniklas static int	initiator_send_SA_KE_NONCE_ID(struct message *);
62511b8570Sniklas static int	initiator_send_AUTH(struct message *);
63511b8570Sniklas static int	responder_recv_SA_KE_NONCE_ID(struct message *);
64511b8570Sniklas static int	responder_send_SA_KE_NONCE_ID_AUTH(struct message *);
653ca9511cSho static int	responder_recv_AUTH(struct message *);
66511b8570Sniklas 
67511b8570Sniklas int (*ike_aggressive_initiator[])(struct message *) = {
68511b8570Sniklas 	initiator_send_SA_KE_NONCE_ID,
69511b8570Sniklas 	initiator_recv_SA_KE_NONCE_ID_AUTH,
70511b8570Sniklas 	initiator_send_AUTH
71511b8570Sniklas };
72511b8570Sniklas 
73511b8570Sniklas int (*ike_aggressive_responder[])(struct message *) = {
74511b8570Sniklas 	responder_recv_SA_KE_NONCE_ID,
75511b8570Sniklas 	responder_send_SA_KE_NONCE_ID_AUTH,
763ca9511cSho 	responder_recv_AUTH
77511b8570Sniklas };
78511b8570Sniklas 
79511b8570Sniklas /* Offer a set of transforms to the responder in the MSG message.  */
80511b8570Sniklas static int
initiator_send_SA_KE_NONCE_ID(struct message * msg)81511b8570Sniklas initiator_send_SA_KE_NONCE_ID(struct message *msg)
82511b8570Sniklas {
83511b8570Sniklas 	if (ike_phase_1_initiator_send_SA(msg))
84511b8570Sniklas 		return -1;
85511b8570Sniklas 
86511b8570Sniklas 	if (ike_phase_1_initiator_send_KE_NONCE(msg))
87511b8570Sniklas 		return -1;
88511b8570Sniklas 
89511b8570Sniklas 	return ike_phase_1_send_ID(msg);
90511b8570Sniklas }
91511b8570Sniklas 
92511b8570Sniklas /* Figure out what transform the responder chose.  */
93511b8570Sniklas static int
initiator_recv_SA_KE_NONCE_ID_AUTH(struct message * msg)94511b8570Sniklas initiator_recv_SA_KE_NONCE_ID_AUTH(struct message *msg)
95511b8570Sniklas {
96511b8570Sniklas 	if (ike_phase_1_initiator_recv_SA(msg))
97511b8570Sniklas 		return -1;
98511b8570Sniklas 
99511b8570Sniklas 	if (ike_phase_1_initiator_recv_KE_NONCE(msg))
100511b8570Sniklas 		return -1;
101511b8570Sniklas 
102511b8570Sniklas 	return ike_phase_1_recv_ID_AUTH(msg);
103511b8570Sniklas }
104511b8570Sniklas 
105511b8570Sniklas static int
initiator_send_AUTH(struct message * msg)106511b8570Sniklas initiator_send_AUTH(struct message *msg)
107511b8570Sniklas {
108511b8570Sniklas 	msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
109511b8570Sniklas 
1108fa9b809Sniklas 	if (ike_phase_1_send_AUTH(msg))
1118fa9b809Sniklas 		return -1;
1128fa9b809Sniklas 
1138fa9b809Sniklas 	/*
1148fa9b809Sniklas 	 * RFC 2407 4.6.3 says that, among others, INITIAL-CONTACT MUST NOT
1158fa9b809Sniklas 	 * be sent in Aggressive Mode.  This leaves us with the choice of
1168fa9b809Sniklas 	 * doing it in an informational exchange of its own with no delivery
1178fa9b809Sniklas 	 * guarantee or in the first Quick Mode, or not at all.
1188fa9b809Sniklas 	 * draft-jenkins-ipsec-rekeying-01.txt has some text that requires
1198fa9b809Sniklas 	 * INITIAL-CONTACT in phase 1, thus contradicting what we learned
1208fa9b809Sniklas 	 * above.  I will bring this up in the IPsec list.  For now we don't
1218fa9b809Sniklas 	 * do INITIAL-CONTACT at all when using aggressive mode.
1228fa9b809Sniklas 	 */
1238fa9b809Sniklas 	return 0;
124511b8570Sniklas }
125511b8570Sniklas 
126511b8570Sniklas /*
127511b8570Sniklas  * Accept a set of transforms offered by the initiator and chose one we can
128511b8570Sniklas  * handle.  Also accept initiator's public DH value, nonce and ID.
129511b8570Sniklas  */
130511b8570Sniklas static int
responder_recv_SA_KE_NONCE_ID(struct message * msg)131511b8570Sniklas responder_recv_SA_KE_NONCE_ID(struct message *msg)
132511b8570Sniklas {
133511b8570Sniklas 	if (ike_phase_1_responder_recv_SA(msg))
134511b8570Sniklas 		return -1;
135511b8570Sniklas 
1365535dd38Sniklas 	if (ike_phase_1_recv_ID(msg))
137511b8570Sniklas 		return -1;
138511b8570Sniklas 
1395535dd38Sniklas 	return ike_phase_1_recv_KE_NONCE(msg);
140511b8570Sniklas }
141511b8570Sniklas 
142511b8570Sniklas /*
143511b8570Sniklas  * Reply with the transform we chose.  Send our public DH value and a nonce
144511b8570Sniklas  * to the initiator.
145511b8570Sniklas  */
146511b8570Sniklas static int
responder_send_SA_KE_NONCE_ID_AUTH(struct message * msg)147511b8570Sniklas responder_send_SA_KE_NONCE_ID_AUTH(struct message *msg)
148511b8570Sniklas {
149511b8570Sniklas 	/* Add the SA payload with the transform that was chosen.  */
150511b8570Sniklas 	if (ike_phase_1_responder_send_SA(msg))
151511b8570Sniklas 		return -1;
152511b8570Sniklas 
153511b8570Sniklas 	/* XXX Should we really just use the initiator's nonce size?  */
154511b8570Sniklas 	if (ike_phase_1_send_KE_NONCE(msg, msg->exchange->nonce_i_len))
155511b8570Sniklas 		return -1;
156511b8570Sniklas 
157511b8570Sniklas 	if (ike_phase_1_post_exchange_KE_NONCE(msg))
158511b8570Sniklas 		return -1;
159511b8570Sniklas 
160511b8570Sniklas 	return ike_phase_1_responder_send_ID_AUTH(msg);
1613ca9511cSho }
1623ca9511cSho 
1633ca9511cSho /*
1643ca9511cSho  * Reply with the transform we chose.  Send our public DH value and a nonce
1653ca9511cSho  * to the initiator.
1663ca9511cSho  */
1673ca9511cSho static int
responder_recv_AUTH(struct message * msg)1683ca9511cSho responder_recv_AUTH(struct message *msg)
1693ca9511cSho {
1703ca9511cSho 	if (ike_phase_1_recv_AUTH(msg))
171511b8570Sniklas 		return -1;
1723ca9511cSho 
1733ca9511cSho 	/* Aggressive: Check for NAT-D payloads and contents.  */
1743ca9511cSho 	if (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_CAP_PEER)
1753ca9511cSho 		(void)nat_t_exchange_check_nat_d(msg);
1763ca9511cSho 	return 0;
177511b8570Sniklas }
178