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 if (len > message_length) { 229 wpa_printf(MSG_INFO, "SSL: Too much data (%d bytes) in " 230 "first fragment of frame (TLS Message " 231 "Length %d bytes)", 232 (int) len, (int) message_length); 233 return -1; 234 } 235 236 data->tls_in = wpabuf_alloc(message_length); 237 if (data->tls_in == NULL) { 238 wpa_printf(MSG_DEBUG, "SSL: No memory for message"); 239 return -1; 240 } 241 wpabuf_put_data(data->tls_in, buf, len); 242 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes in first " 243 "fragment, waiting for %lu bytes more", 244 (unsigned long) len, 245 (unsigned long) wpabuf_tailroom(data->tls_in)); 246 } 247 248 return 0; 249 } 250 251 252 int eap_server_tls_phase1(struct eap_sm *sm, struct eap_ssl_data *data) 253 { 254 if (data->tls_out) { 255 /* This should not happen.. */ 256 wpa_printf(MSG_INFO, "SSL: pending tls_out data when " 257 "processing new message"); 258 wpabuf_free(data->tls_out); 259 WPA_ASSERT(data->tls_out == NULL); 260 } 261 262 data->tls_out = tls_connection_server_handshake(sm->ssl_ctx, 263 data->conn, 264 data->tls_in, NULL); 265 if (data->tls_out == NULL) { 266 wpa_printf(MSG_INFO, "SSL: TLS processing failed"); 267 return -1; 268 } 269 if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) { 270 /* TLS processing has failed - return error */ 271 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to " 272 "report error"); 273 return -1; 274 } 275 276 return 0; 277 } 278 279 280 static int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags, 281 const u8 **pos, size_t *left) 282 { 283 unsigned int tls_msg_len = 0; 284 const u8 *end = *pos + *left; 285 286 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 287 if (*left < 4) { 288 wpa_printf(MSG_INFO, "SSL: Short frame with TLS " 289 "length"); 290 return -1; 291 } 292 tls_msg_len = WPA_GET_BE32(*pos); 293 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d", 294 tls_msg_len); 295 *pos += 4; 296 *left -= 4; 297 } 298 299 wpa_printf(MSG_DEBUG, "SSL: Received packet: Flags 0x%x " 300 "Message Length %u", flags, tls_msg_len); 301 302 if (data->state == WAIT_FRAG_ACK) { 303 if (*left != 0) { 304 wpa_printf(MSG_DEBUG, "SSL: Unexpected payload in " 305 "WAIT_FRAG_ACK state"); 306 return -1; 307 } 308 wpa_printf(MSG_DEBUG, "SSL: Fragment acknowledged"); 309 return 1; 310 } 311 312 if (data->tls_in && 313 eap_server_tls_process_cont(data, *pos, end - *pos) < 0) 314 return -1; 315 316 if (flags & EAP_TLS_FLAGS_MORE_FRAGMENTS) { 317 if (eap_server_tls_process_fragment(data, flags, tls_msg_len, 318 *pos, end - *pos) < 0) 319 return -1; 320 321 data->state = FRAG_ACK; 322 return 1; 323 } 324 325 if (data->state == FRAG_ACK) { 326 wpa_printf(MSG_DEBUG, "SSL: All fragments received"); 327 data->state = MSG; 328 } 329 330 if (data->tls_in == NULL) { 331 /* Wrap unfragmented messages as wpabuf without extra copy */ 332 wpabuf_set(&data->tmpbuf, *pos, end - *pos); 333 data->tls_in = &data->tmpbuf; 334 } 335 336 return 0; 337 } 338 339 340 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data) 341 { 342 if (data->tls_in != &data->tmpbuf) 343 wpabuf_free(data->tls_in); 344 data->tls_in = NULL; 345 } 346 347 348 struct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm, 349 struct eap_ssl_data *data, 350 const struct wpabuf *plain) 351 { 352 struct wpabuf *buf; 353 354 buf = tls_connection_encrypt(sm->ssl_ctx, data->conn, 355 plain); 356 if (buf == NULL) { 357 wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 data"); 358 return NULL; 359 } 360 361 return buf; 362 } 363 364 365 int eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data, 366 struct wpabuf *respData, void *priv, int eap_type, 367 int (*proc_version)(struct eap_sm *sm, void *priv, 368 int peer_version), 369 void (*proc_msg)(struct eap_sm *sm, void *priv, 370 const struct wpabuf *respData)) 371 { 372 const u8 *pos; 373 u8 flags; 374 size_t left; 375 int ret, res = 0; 376 377 pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, &left); 378 if (pos == NULL || left < 1) 379 return 0; /* Should not happen - frame already validated */ 380 flags = *pos++; 381 left--; 382 wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - Flags 0x%02x", 383 (unsigned long) wpabuf_len(respData), flags); 384 385 if (proc_version && 386 proc_version(sm, priv, flags & EAP_TLS_VERSION_MASK) < 0) 387 return -1; 388 389 ret = eap_server_tls_reassemble(data, flags, &pos, &left); 390 if (ret < 0) { 391 res = -1; 392 goto done; 393 } else if (ret == 1) 394 return 0; 395 396 if (proc_msg) 397 proc_msg(sm, priv, respData); 398 399 if (tls_connection_get_write_alerts(sm->ssl_ctx, data->conn) > 1) { 400 wpa_printf(MSG_INFO, "SSL: Locally detected fatal error in " 401 "TLS processing"); 402 res = -1; 403 } 404 405 done: 406 eap_server_tls_free_in_buf(data); 407 408 return res; 409 } 410