1 /* 2 * EAP-TLS/PEAP/TTLS/FAST server common functions 3 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #include "common.h" 18 #include "crypto/sha1.h" 19 #include "crypto/tls.h" 20 #include "eap_i.h" 21 #include "eap_tls_common.h" 22 23 24 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data); 25 26 27 int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, 28 int verify_peer) 29 { 30 data->eap = sm; 31 data->phase2 = sm->init_phase2; 32 33 data->conn = tls_connection_init(sm->ssl_ctx); 34 if (data->conn == NULL) { 35 wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS " 36 "connection"); 37 return -1; 38 } 39 40 if (tls_connection_set_verify(sm->ssl_ctx, data->conn, verify_peer)) { 41 wpa_printf(MSG_INFO, "SSL: Failed to configure verification " 42 "of TLS peer certificate"); 43 tls_connection_deinit(sm->ssl_ctx, data->conn); 44 data->conn = NULL; 45 return -1; 46 } 47 48 /* TODO: make this configurable */ 49 data->tls_out_limit = 1398; 50 if (data->phase2) { 51 /* Limit the fragment size in the inner TLS authentication 52 * since the outer authentication with EAP-PEAP does not yet 53 * support fragmentation */ 54 if (data->tls_out_limit > 100) 55 data->tls_out_limit -= 100; 56 } 57 return 0; 58 } 59 60 61 void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data) 62 { 63 tls_connection_deinit(sm->ssl_ctx, data->conn); 64 eap_server_tls_free_in_buf(data); 65 wpabuf_free(data->tls_out); 66 data->tls_out = NULL; 67 } 68 69 70 u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, 71 char *label, size_t len) 72 { 73 struct tls_keys keys; 74 u8 *rnd = NULL, *out; 75 76 out = os_malloc(len); 77 if (out == NULL) 78 return NULL; 79 80 if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) == 81 0) 82 return out; 83 84 if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys)) 85 goto fail; 86 87 if (keys.client_random == NULL || keys.server_random == NULL || 88 keys.master_key == NULL) 89 goto fail; 90 91 rnd = os_malloc(keys.client_random_len + keys.server_random_len); 92 if (rnd == NULL) 93 goto fail; 94 os_memcpy(rnd, keys.client_random, keys.client_random_len); 95 os_memcpy(rnd + keys.client_random_len, keys.server_random, 96 keys.server_random_len); 97 98 if (tls_prf(keys.master_key, keys.master_key_len, 99 label, rnd, keys.client_random_len + 100 keys.server_random_len, out, len)) 101 goto fail; 102 103 os_free(rnd); 104 return out; 105 106 fail: 107 os_free(out); 108 os_free(rnd); 109 return NULL; 110 } 111 112 113 struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data, 114 int eap_type, int version, u8 id) 115 { 116 struct wpabuf *req; 117 u8 flags; 118 size_t send_len, plen; 119 120 wpa_printf(MSG_DEBUG, "SSL: Generating Request"); 121 if (data->tls_out == NULL) { 122 wpa_printf(MSG_ERROR, "SSL: tls_out NULL in %s", __func__); 123 return NULL; 124 } 125 126 flags = version; 127 send_len = wpabuf_len(data->tls_out) - data->tls_out_pos; 128 if (1 + send_len > data->tls_out_limit) { 129 send_len = data->tls_out_limit - 1; 130 flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; 131 if (data->tls_out_pos == 0) { 132 flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; 133 send_len -= 4; 134 } 135 } 136 137 plen = 1 + send_len; 138 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 139 plen += 4; 140 141 req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, plen, 142 EAP_CODE_REQUEST, id); 143 if (req == NULL) 144 return NULL; 145 146 wpabuf_put_u8(req, flags); /* Flags */ 147 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 148 wpabuf_put_be32(req, wpabuf_len(data->tls_out)); 149 150 wpabuf_put_data(req, wpabuf_head_u8(data->tls_out) + data->tls_out_pos, 151 send_len); 152 data->tls_out_pos += send_len; 153 154 if (data->tls_out_pos == wpabuf_len(data->tls_out)) { 155 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 156 "(message sent completely)", 157 (unsigned long) send_len); 158 wpabuf_free(data->tls_out); 159 data->tls_out = NULL; 160 data->tls_out_pos = 0; 161 data->state = MSG; 162 } else { 163 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 164 "(%lu more to send)", (unsigned long) send_len, 165 (unsigned long) wpabuf_len(data->tls_out) - 166 data->tls_out_pos); 167 data->state = WAIT_FRAG_ACK; 168 } 169 170 return req; 171 } 172 173 174 struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version) 175 { 176 struct wpabuf *req; 177 178 req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, 1, EAP_CODE_REQUEST, 179 id); 180 if (req == NULL) 181 return NULL; 182 wpa_printf(MSG_DEBUG, "SSL: Building ACK"); 183 wpabuf_put_u8(req, version); /* Flags */ 184 return req; 185 } 186 187 188 static int eap_server_tls_process_cont(struct eap_ssl_data *data, 189 const u8 *buf, size_t len) 190 { 191 /* Process continuation of a pending message */ 192 if (len > wpabuf_tailroom(data->tls_in)) { 193 wpa_printf(MSG_DEBUG, "SSL: Fragment overflow"); 194 return -1; 195 } 196 197 wpabuf_put_data(data->tls_in, buf, len); 198 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes, waiting for %lu " 199 "bytes more", (unsigned long) len, 200 (unsigned long) wpabuf_tailroom(data->tls_in)); 201 202 return 0; 203 } 204 205 206 static int eap_server_tls_process_fragment(struct eap_ssl_data *data, 207 u8 flags, u32 message_length, 208 const u8 *buf, size_t len) 209 { 210 /* Process a fragment that is not the last one of the message */ 211 if (data->tls_in == NULL && !(flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)) { 212 wpa_printf(MSG_DEBUG, "SSL: No Message Length field in a " 213 "fragmented packet"); 214 return -1; 215 } 216 217 if (data->tls_in == NULL) { 218 /* First fragment of the message */ 219 220 /* Limit length to avoid rogue peers from causing large 221 * memory allocations. */ 222 if (message_length > 65536) { 223 wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size" 224 " over 64 kB)"); 225 return -1; 226 } 227 228 data->tls_in = wpabuf_alloc(message_length); 229 if (data->tls_in == NULL) { 230 wpa_printf(MSG_DEBUG, "SSL: No memory for message"); 231 return -1; 232 } 233 wpabuf_put_data(data->tls_in, buf, len); 234 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes in first " 235 "fragment, waiting for %lu bytes more", 236 (unsigned long) len, 237 (unsigned long) wpabuf_tailroom(data->tls_in)); 238 } 239 240 return 0; 241 } 242 243 244 int eap_server_tls_phase1(struct eap_sm *sm, struct eap_ssl_data *data) 245 { 246 if (data->tls_out) { 247 /* This should not happen.. */ 248 wpa_printf(MSG_INFO, "SSL: pending tls_out data when " 249 "processing new message"); 250 wpabuf_free(data->tls_out); 251 WPA_ASSERT(data->tls_out == NULL); 252 } 253 254 data->tls_out = tls_connection_server_handshake(sm->ssl_ctx, 255 data->conn, 256 data->tls_in, NULL); 257 if (data->tls_out == NULL) { 258 wpa_printf(MSG_INFO, "SSL: TLS processing failed"); 259 return -1; 260 } 261 if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) { 262 /* TLS processing has failed - return error */ 263 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to " 264 "report error"); 265 return -1; 266 } 267 268 return 0; 269 } 270 271 272 static int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags, 273 const u8 **pos, size_t *left) 274 { 275 unsigned int tls_msg_len = 0; 276 const u8 *end = *pos + *left; 277 278 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 279 if (*left < 4) { 280 wpa_printf(MSG_INFO, "SSL: Short frame with TLS " 281 "length"); 282 return -1; 283 } 284 tls_msg_len = WPA_GET_BE32(*pos); 285 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d", 286 tls_msg_len); 287 *pos += 4; 288 *left -= 4; 289 } 290 291 wpa_printf(MSG_DEBUG, "SSL: Received packet: Flags 0x%x " 292 "Message Length %u", flags, tls_msg_len); 293 294 if (data->state == WAIT_FRAG_ACK) { 295 if (*left != 0) { 296 wpa_printf(MSG_DEBUG, "SSL: Unexpected payload in " 297 "WAIT_FRAG_ACK state"); 298 return -1; 299 } 300 wpa_printf(MSG_DEBUG, "SSL: Fragment acknowledged"); 301 return 1; 302 } 303 304 if (data->tls_in && 305 eap_server_tls_process_cont(data, *pos, end - *pos) < 0) 306 return -1; 307 308 if (flags & EAP_TLS_FLAGS_MORE_FRAGMENTS) { 309 if (eap_server_tls_process_fragment(data, flags, tls_msg_len, 310 *pos, end - *pos) < 0) 311 return -1; 312 313 data->state = FRAG_ACK; 314 return 1; 315 } 316 317 if (data->state == FRAG_ACK) { 318 wpa_printf(MSG_DEBUG, "SSL: All fragments received"); 319 data->state = MSG; 320 } 321 322 if (data->tls_in == NULL) { 323 /* Wrap unfragmented messages as wpabuf without extra copy */ 324 wpabuf_set(&data->tmpbuf, *pos, end - *pos); 325 data->tls_in = &data->tmpbuf; 326 } 327 328 return 0; 329 } 330 331 332 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data) 333 { 334 if (data->tls_in != &data->tmpbuf) 335 wpabuf_free(data->tls_in); 336 data->tls_in = NULL; 337 } 338 339 340 struct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm, 341 struct eap_ssl_data *data, 342 const struct wpabuf *plain) 343 { 344 struct wpabuf *buf; 345 346 buf = tls_connection_encrypt(sm->ssl_ctx, data->conn, 347 plain); 348 if (buf == NULL) { 349 wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 data"); 350 return NULL; 351 } 352 353 return buf; 354 } 355 356 357 int eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data, 358 struct wpabuf *respData, void *priv, int eap_type, 359 int (*proc_version)(struct eap_sm *sm, void *priv, 360 int peer_version), 361 void (*proc_msg)(struct eap_sm *sm, void *priv, 362 const struct wpabuf *respData)) 363 { 364 const u8 *pos; 365 u8 flags; 366 size_t left; 367 int ret, res = 0; 368 369 pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, &left); 370 if (pos == NULL || left < 1) 371 return 0; /* Should not happen - frame already validated */ 372 flags = *pos++; 373 left--; 374 wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - Flags 0x%02x", 375 (unsigned long) wpabuf_len(respData), flags); 376 377 if (proc_version && 378 proc_version(sm, priv, flags & EAP_TLS_VERSION_MASK) < 0) 379 return -1; 380 381 ret = eap_server_tls_reassemble(data, flags, &pos, &left); 382 if (ret < 0) { 383 res = -1; 384 goto done; 385 } else if (ret == 1) 386 return 0; 387 388 if (proc_msg) 389 proc_msg(sm, priv, respData); 390 391 if (tls_connection_get_write_alerts(sm->ssl_ctx, data->conn) > 1) { 392 wpa_printf(MSG_INFO, "SSL: Locally detected fatal error in " 393 "TLS processing"); 394 res = -1; 395 } 396 397 done: 398 eap_server_tls_free_in_buf(data); 399 400 return res; 401 } 402