1 /* $OpenBSD: ike_aggressive.c,v 1.10 2005/04/08 22:32:10 cloder 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 "math_group.h"
54 #include "message.h"
55 #include "nat_traversal.h"
56 #include "prf.h"
57 #include "sa.h"
58 #include "transport.h"
59 #include "util.h"
60
61 static int initiator_recv_SA_KE_NONCE_ID_AUTH(struct message *);
62 static int initiator_send_SA_KE_NONCE_ID(struct message *);
63 static int initiator_send_AUTH(struct message *);
64 static int responder_recv_SA_KE_NONCE_ID(struct message *);
65 static int responder_send_SA_KE_NONCE_ID_AUTH(struct message *);
66 static int responder_recv_AUTH(struct message *);
67
68 int (*ike_aggressive_initiator[])(struct message *) = {
69 initiator_send_SA_KE_NONCE_ID,
70 initiator_recv_SA_KE_NONCE_ID_AUTH,
71 initiator_send_AUTH
72 };
73
74 int (*ike_aggressive_responder[])(struct message *) = {
75 responder_recv_SA_KE_NONCE_ID,
76 responder_send_SA_KE_NONCE_ID_AUTH,
77 responder_recv_AUTH
78 };
79
80 /* Offer a set of transforms to the responder in the MSG message. */
81 static int
initiator_send_SA_KE_NONCE_ID(struct message * msg)82 initiator_send_SA_KE_NONCE_ID(struct message *msg)
83 {
84 if (ike_phase_1_initiator_send_SA(msg))
85 return -1;
86
87 if (ike_phase_1_initiator_send_KE_NONCE(msg))
88 return -1;
89
90 return ike_phase_1_send_ID(msg);
91 }
92
93 /* Figure out what transform the responder chose. */
94 static int
initiator_recv_SA_KE_NONCE_ID_AUTH(struct message * msg)95 initiator_recv_SA_KE_NONCE_ID_AUTH(struct message *msg)
96 {
97 if (ike_phase_1_initiator_recv_SA(msg))
98 return -1;
99
100 if (ike_phase_1_initiator_recv_KE_NONCE(msg))
101 return -1;
102
103 return ike_phase_1_recv_ID_AUTH(msg);
104 }
105
106 static int
initiator_send_AUTH(struct message * msg)107 initiator_send_AUTH(struct message *msg)
108 {
109 msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
110
111 if (ike_phase_1_send_AUTH(msg))
112 return -1;
113
114 /*
115 * RFC 2407 4.6.3 says that, among others, INITIAL-CONTACT MUST NOT
116 * be sent in Aggressive Mode. This leaves us with the choice of
117 * doing it in an informational exchange of its own with no delivery
118 * guarantee or in the first Quick Mode, or not at all.
119 * draft-jenkins-ipsec-rekeying-01.txt has some text that requires
120 * INITIAL-CONTACT in phase 1, thus contradicting what we learned
121 * above. I will bring this up in the IPsec list. For now we don't
122 * do INITIAL-CONTACT at all when using aggressive mode.
123 */
124 return 0;
125 }
126
127 /*
128 * Accept a set of transforms offered by the initiator and chose one we can
129 * handle. Also accept initiator's public DH value, nonce and ID.
130 */
131 static int
responder_recv_SA_KE_NONCE_ID(struct message * msg)132 responder_recv_SA_KE_NONCE_ID(struct message *msg)
133 {
134 if (ike_phase_1_responder_recv_SA(msg))
135 return -1;
136
137 if (ike_phase_1_recv_ID(msg))
138 return -1;
139
140 return ike_phase_1_recv_KE_NONCE(msg);
141 }
142
143 /*
144 * Reply with the transform we chose. Send our public DH value and a nonce
145 * to the initiator.
146 */
147 static int
responder_send_SA_KE_NONCE_ID_AUTH(struct message * msg)148 responder_send_SA_KE_NONCE_ID_AUTH(struct message *msg)
149 {
150 /* Add the SA payload with the transform that was chosen. */
151 if (ike_phase_1_responder_send_SA(msg))
152 return -1;
153
154 /* XXX Should we really just use the initiator's nonce size? */
155 if (ike_phase_1_send_KE_NONCE(msg, msg->exchange->nonce_i_len))
156 return -1;
157
158 if (ike_phase_1_post_exchange_KE_NONCE(msg))
159 return -1;
160
161 return ike_phase_1_responder_send_ID_AUTH(msg);
162 }
163
164 /*
165 * Reply with the transform we chose. Send our public DH value and a nonce
166 * to the initiator.
167 */
168 static int
responder_recv_AUTH(struct message * msg)169 responder_recv_AUTH(struct message *msg)
170 {
171 if (ike_phase_1_recv_AUTH(msg))
172 return -1;
173
174 /* Aggressive: Check for NAT-D payloads and contents. */
175 if (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_CAP_PEER)
176 (void)nat_t_exchange_check_nat_d(msg);
177 return 0;
178 }
179