xref: /openbsd/sbin/isakmpd/ike_aggressive.c (revision 2f1aa25b)
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