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