1 /* $OpenBSD: ike_aggressive.c,v 1.11 2010/06/29 19:50:16 reyk 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 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 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 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 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 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 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