1 /* $OpenBSD: ike_aggressive.c,v 1.13 2018/01/15 09:54:48 mpi Exp $ */
2 /* $EOM: ike_aggressive.c,v 1.4 2000/01/31 22:33:45 niklas Exp $ */
3
4 /*
5 * Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
6 * Copyright (c) 1999 Angelos D. Keromytis. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * This code was written under funding by Ericsson Radio Systems.
31 */
32
33 #include <sys/types.h>
34 #include <netinet/in.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include "attribute.h"
39 #include "conf.h"
40 #include "constants.h"
41 #include "crypto.h"
42 #include "dh.h"
43 #include "doi.h"
44 #include "exchange.h"
45 #include "hash.h"
46 #include "ike_auth.h"
47 #include "ike_aggressive.h"
48 #include "ike_phase_1.h"
49 #include "ipsec.h"
50 #include "ipsec_doi.h"
51 #include "isakmp.h"
52 #include "log.h"
53 #include "message.h"
54 #include "nat_traversal.h"
55 #include "prf.h"
56 #include "sa.h"
57 #include "transport.h"
58 #include "util.h"
59
60 static int initiator_recv_SA_KE_NONCE_ID_AUTH(struct message *);
61 static int initiator_send_SA_KE_NONCE_ID(struct message *);
62 static int initiator_send_AUTH(struct message *);
63 static int responder_recv_SA_KE_NONCE_ID(struct message *);
64 static int responder_send_SA_KE_NONCE_ID_AUTH(struct message *);
65 static int responder_recv_AUTH(struct message *);
66
67 int (*ike_aggressive_initiator[])(struct message *) = {
68 initiator_send_SA_KE_NONCE_ID,
69 initiator_recv_SA_KE_NONCE_ID_AUTH,
70 initiator_send_AUTH
71 };
72
73 int (*ike_aggressive_responder[])(struct message *) = {
74 responder_recv_SA_KE_NONCE_ID,
75 responder_send_SA_KE_NONCE_ID_AUTH,
76 responder_recv_AUTH
77 };
78
79 /* Offer a set of transforms to the responder in the MSG message. */
80 static int
initiator_send_SA_KE_NONCE_ID(struct message * msg)81 initiator_send_SA_KE_NONCE_ID(struct message *msg)
82 {
83 if (ike_phase_1_initiator_send_SA(msg))
84 return -1;
85
86 if (ike_phase_1_initiator_send_KE_NONCE(msg))
87 return -1;
88
89 return ike_phase_1_send_ID(msg);
90 }
91
92 /* Figure out what transform the responder chose. */
93 static int
initiator_recv_SA_KE_NONCE_ID_AUTH(struct message * msg)94 initiator_recv_SA_KE_NONCE_ID_AUTH(struct message *msg)
95 {
96 if (ike_phase_1_initiator_recv_SA(msg))
97 return -1;
98
99 if (ike_phase_1_initiator_recv_KE_NONCE(msg))
100 return -1;
101
102 return ike_phase_1_recv_ID_AUTH(msg);
103 }
104
105 static int
initiator_send_AUTH(struct message * msg)106 initiator_send_AUTH(struct message *msg)
107 {
108 msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
109
110 if (ike_phase_1_send_AUTH(msg))
111 return -1;
112
113 /*
114 * RFC 2407 4.6.3 says that, among others, INITIAL-CONTACT MUST NOT
115 * be sent in Aggressive Mode. This leaves us with the choice of
116 * doing it in an informational exchange of its own with no delivery
117 * guarantee or in the first Quick Mode, or not at all.
118 * draft-jenkins-ipsec-rekeying-01.txt has some text that requires
119 * INITIAL-CONTACT in phase 1, thus contradicting what we learned
120 * above. I will bring this up in the IPsec list. For now we don't
121 * do INITIAL-CONTACT at all when using aggressive mode.
122 */
123 return 0;
124 }
125
126 /*
127 * Accept a set of transforms offered by the initiator and chose one we can
128 * handle. Also accept initiator's public DH value, nonce and ID.
129 */
130 static int
responder_recv_SA_KE_NONCE_ID(struct message * msg)131 responder_recv_SA_KE_NONCE_ID(struct message *msg)
132 {
133 if (ike_phase_1_responder_recv_SA(msg))
134 return -1;
135
136 if (ike_phase_1_recv_ID(msg))
137 return -1;
138
139 return ike_phase_1_recv_KE_NONCE(msg);
140 }
141
142 /*
143 * Reply with the transform we chose. Send our public DH value and a nonce
144 * to the initiator.
145 */
146 static int
responder_send_SA_KE_NONCE_ID_AUTH(struct message * msg)147 responder_send_SA_KE_NONCE_ID_AUTH(struct message *msg)
148 {
149 /* Add the SA payload with the transform that was chosen. */
150 if (ike_phase_1_responder_send_SA(msg))
151 return -1;
152
153 /* XXX Should we really just use the initiator's nonce size? */
154 if (ike_phase_1_send_KE_NONCE(msg, msg->exchange->nonce_i_len))
155 return -1;
156
157 if (ike_phase_1_post_exchange_KE_NONCE(msg))
158 return -1;
159
160 return ike_phase_1_responder_send_ID_AUTH(msg);
161 }
162
163 /*
164 * Reply with the transform we chose. Send our public DH value and a nonce
165 * to the initiator.
166 */
167 static int
responder_recv_AUTH(struct message * msg)168 responder_recv_AUTH(struct message *msg)
169 {
170 if (ike_phase_1_recv_AUTH(msg))
171 return -1;
172
173 /* Aggressive: Check for NAT-D payloads and contents. */
174 if (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_CAP_PEER)
175 (void)nat_t_exchange_check_nat_d(msg);
176 return 0;
177 }
178