1 /* 2 * EAP-TLS/PEAP/TTLS/FAST server common functions 3 * Copyright (c) 2004-2009, Jouni Malinen <j (at) w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "common.h" 12 #include "crypto/sha1.h" 13 #include "crypto/tls.h" 14 #include "eap_i.h" 15 #include "eap_tls_common.h" 16 17 18 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data); 19 20 21 struct wpabuf * eap_tls_msg_alloc(EapType type, size_t payload_len, 22 u8 code, u8 identifier) 23 { 24 if (type == EAP_UNAUTH_TLS_TYPE) 25 return eap_msg_alloc(EAP_VENDOR_UNAUTH_TLS, 26 EAP_VENDOR_TYPE_UNAUTH_TLS, payload_len, 27 code, identifier); 28 else if (type == EAP_WFA_UNAUTH_TLS_TYPE) 29 return eap_msg_alloc(EAP_VENDOR_WFA_NEW, 30 EAP_VENDOR_WFA_UNAUTH_TLS, payload_len, 31 code, identifier); 32 return eap_msg_alloc(EAP_VENDOR_IETF, type, payload_len, code, 33 identifier); 34 } 35 36 37 #ifdef CONFIG_TLS_INTERNAL 38 static void eap_server_tls_log_cb(void *ctx, const char *msg) 39 { 40 struct eap_sm *sm = ctx; 41 eap_log_msg(sm, "TLS: %s", msg); 42 } 43 #endif /* CONFIG_TLS_INTERNAL */ 44 45 46 int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, 47 int verify_peer, int eap_type) 48 { 49 u8 session_ctx[8]; 50 unsigned int flags = 0; 51 52 if (sm->ssl_ctx == NULL) { 53 wpa_printf(MSG_ERROR, "TLS context not initialized - cannot use TLS-based EAP method"); 54 return -1; 55 } 56 57 data->eap = sm; 58 data->phase2 = sm->init_phase2; 59 60 data->conn = tls_connection_init(sm->ssl_ctx); 61 if (data->conn == NULL) { 62 wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS " 63 "connection"); 64 return -1; 65 } 66 67 #ifdef CONFIG_TLS_INTERNAL 68 tls_connection_set_log_cb(data->conn, eap_server_tls_log_cb, sm); 69 #ifdef CONFIG_TESTING_OPTIONS 70 tls_connection_set_test_flags(data->conn, sm->tls_test_flags); 71 #endif /* CONFIG_TESTING_OPTIONS */ 72 #endif /* CONFIG_TLS_INTERNAL */ 73 74 if (eap_type != EAP_TYPE_FAST) 75 flags |= TLS_CONN_DISABLE_SESSION_TICKET; 76 os_memcpy(session_ctx, "hostapd", 7); 77 session_ctx[7] = (u8) eap_type; 78 if (tls_connection_set_verify(sm->ssl_ctx, data->conn, verify_peer, 79 flags, session_ctx, 80 sizeof(session_ctx))) { 81 wpa_printf(MSG_INFO, "SSL: Failed to configure verification " 82 "of TLS peer certificate"); 83 tls_connection_deinit(sm->ssl_ctx, data->conn); 84 data->conn = NULL; 85 return -1; 86 } 87 88 data->tls_out_limit = sm->fragment_size > 0 ? sm->fragment_size : 1398; 89 if (data->phase2) { 90 /* Limit the fragment size in the inner TLS authentication 91 * since the outer authentication with EAP-PEAP does not yet 92 * support fragmentation */ 93 if (data->tls_out_limit > 100) 94 data->tls_out_limit -= 100; 95 } 96 return 0; 97 } 98 99 100 void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data) 101 { 102 tls_connection_deinit(sm->ssl_ctx, data->conn); 103 eap_server_tls_free_in_buf(data); 104 wpabuf_free(data->tls_out); 105 data->tls_out = NULL; 106 } 107 108 109 u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, 110 char *label, size_t len) 111 { 112 u8 *out; 113 114 out = os_malloc(len); 115 if (out == NULL) 116 return NULL; 117 118 if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, 0, 119 out, len)) { 120 os_free(out); 121 return NULL; 122 } 123 124 return out; 125 } 126 127 128 /** 129 * eap_server_tls_derive_session_id - Derive a Session-Id based on TLS data 130 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 131 * @data: Data for TLS processing 132 * @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) 133 * @len: Pointer to length of the session ID generated 134 * Returns: Pointer to allocated Session-Id on success or %NULL on failure 135 * 136 * This function derive the Session-Id based on the TLS session data 137 * (client/server random and method type). 138 * 139 * The caller is responsible for freeing the returned buffer. 140 */ 141 u8 * eap_server_tls_derive_session_id(struct eap_sm *sm, 142 struct eap_ssl_data *data, u8 eap_type, 143 size_t *len) 144 { 145 struct tls_random keys; 146 u8 *out; 147 148 if (tls_connection_get_random(sm->ssl_ctx, data->conn, &keys)) 149 return NULL; 150 151 if (keys.client_random == NULL || keys.server_random == NULL) 152 return NULL; 153 154 *len = 1 + keys.client_random_len + keys.server_random_len; 155 out = os_malloc(*len); 156 if (out == NULL) 157 return NULL; 158 159 /* Session-Id = EAP type || client.random || server.random */ 160 out[0] = eap_type; 161 os_memcpy(out + 1, keys.client_random, keys.client_random_len); 162 os_memcpy(out + 1 + keys.client_random_len, keys.server_random, 163 keys.server_random_len); 164 165 return out; 166 } 167 168 169 struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data, 170 int eap_type, int version, u8 id) 171 { 172 struct wpabuf *req; 173 u8 flags; 174 size_t send_len, plen; 175 176 wpa_printf(MSG_DEBUG, "SSL: Generating Request"); 177 if (data->tls_out == NULL) { 178 wpa_printf(MSG_ERROR, "SSL: tls_out NULL in %s", __func__); 179 return NULL; 180 } 181 182 flags = version; 183 send_len = wpabuf_len(data->tls_out) - data->tls_out_pos; 184 if (1 + send_len > data->tls_out_limit) { 185 send_len = data->tls_out_limit - 1; 186 flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; 187 if (data->tls_out_pos == 0) { 188 flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; 189 send_len -= 4; 190 } 191 } 192 193 plen = 1 + send_len; 194 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 195 plen += 4; 196 197 req = eap_tls_msg_alloc(eap_type, plen, EAP_CODE_REQUEST, id); 198 if (req == NULL) 199 return NULL; 200 201 wpabuf_put_u8(req, flags); /* Flags */ 202 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 203 wpabuf_put_be32(req, wpabuf_len(data->tls_out)); 204 205 wpabuf_put_data(req, wpabuf_head_u8(data->tls_out) + data->tls_out_pos, 206 send_len); 207 data->tls_out_pos += send_len; 208 209 if (data->tls_out_pos == wpabuf_len(data->tls_out)) { 210 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 211 "(message sent completely)", 212 (unsigned long) send_len); 213 wpabuf_free(data->tls_out); 214 data->tls_out = NULL; 215 data->tls_out_pos = 0; 216 data->state = MSG; 217 } else { 218 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 219 "(%lu more to send)", (unsigned long) send_len, 220 (unsigned long) wpabuf_len(data->tls_out) - 221 data->tls_out_pos); 222 data->state = WAIT_FRAG_ACK; 223 } 224 225 return req; 226 } 227 228 229 struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version) 230 { 231 struct wpabuf *req; 232 233 req = eap_tls_msg_alloc(eap_type, 1, EAP_CODE_REQUEST, id); 234 if (req == NULL) 235 return NULL; 236 wpa_printf(MSG_DEBUG, "SSL: Building ACK"); 237 wpabuf_put_u8(req, version); /* Flags */ 238 return req; 239 } 240 241 242 static int eap_server_tls_process_cont(struct eap_ssl_data *data, 243 const u8 *buf, size_t len) 244 { 245 /* Process continuation of a pending message */ 246 if (len > wpabuf_tailroom(data->tls_in)) { 247 wpa_printf(MSG_DEBUG, "SSL: Fragment overflow"); 248 return -1; 249 } 250 251 wpabuf_put_data(data->tls_in, buf, len); 252 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes, waiting for %lu " 253 "bytes more", (unsigned long) len, 254 (unsigned long) wpabuf_tailroom(data->tls_in)); 255 256 return 0; 257 } 258 259 260 static int eap_server_tls_process_fragment(struct eap_ssl_data *data, 261 u8 flags, u32 message_length, 262 const u8 *buf, size_t len) 263 { 264 /* Process a fragment that is not the last one of the message */ 265 if (data->tls_in == NULL && !(flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)) { 266 wpa_printf(MSG_DEBUG, "SSL: No Message Length field in a " 267 "fragmented packet"); 268 return -1; 269 } 270 271 if (data->tls_in == NULL) { 272 /* First fragment of the message */ 273 274 /* Limit length to avoid rogue peers from causing large 275 * memory allocations. */ 276 if (message_length > 65536) { 277 wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size" 278 " over 64 kB)"); 279 return -1; 280 } 281 282 if (len > message_length) { 283 wpa_printf(MSG_INFO, "SSL: Too much data (%d bytes) in " 284 "first fragment of frame (TLS Message " 285 "Length %d bytes)", 286 (int) len, (int) message_length); 287 return -1; 288 } 289 290 data->tls_in = wpabuf_alloc(message_length); 291 if (data->tls_in == NULL) { 292 wpa_printf(MSG_DEBUG, "SSL: No memory for message"); 293 return -1; 294 } 295 wpabuf_put_data(data->tls_in, buf, len); 296 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes in first " 297 "fragment, waiting for %lu bytes more", 298 (unsigned long) len, 299 (unsigned long) wpabuf_tailroom(data->tls_in)); 300 } 301 302 return 0; 303 } 304 305 306 int eap_server_tls_phase1(struct eap_sm *sm, struct eap_ssl_data *data) 307 { 308 if (data->tls_out) { 309 /* This should not happen.. */ 310 wpa_printf(MSG_INFO, "SSL: pending tls_out data when " 311 "processing new message"); 312 wpabuf_free(data->tls_out); 313 WPA_ASSERT(data->tls_out == NULL); 314 } 315 316 data->tls_out = tls_connection_server_handshake(sm->ssl_ctx, 317 data->conn, 318 data->tls_in, NULL); 319 if (data->tls_out == NULL) { 320 wpa_printf(MSG_INFO, "SSL: TLS processing failed"); 321 return -1; 322 } 323 if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) { 324 /* TLS processing has failed - return error */ 325 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to " 326 "report error"); 327 return -1; 328 } 329 330 return 0; 331 } 332 333 334 static int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags, 335 const u8 **pos, size_t *left) 336 { 337 unsigned int tls_msg_len = 0; 338 const u8 *end = *pos + *left; 339 340 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 341 if (*left < 4) { 342 wpa_printf(MSG_INFO, "SSL: Short frame with TLS " 343 "length"); 344 return -1; 345 } 346 tls_msg_len = WPA_GET_BE32(*pos); 347 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d", 348 tls_msg_len); 349 *pos += 4; 350 *left -= 4; 351 352 if (*left > tls_msg_len) { 353 wpa_printf(MSG_INFO, "SSL: TLS Message Length (%d " 354 "bytes) smaller than this fragment (%d " 355 "bytes)", (int) tls_msg_len, (int) *left); 356 return -1; 357 } 358 } 359 360 wpa_printf(MSG_DEBUG, "SSL: Received packet: Flags 0x%x " 361 "Message Length %u", flags, tls_msg_len); 362 363 if (data->state == WAIT_FRAG_ACK) { 364 if (*left != 0) { 365 wpa_printf(MSG_DEBUG, "SSL: Unexpected payload in " 366 "WAIT_FRAG_ACK state"); 367 return -1; 368 } 369 wpa_printf(MSG_DEBUG, "SSL: Fragment acknowledged"); 370 return 1; 371 } 372 373 if (data->tls_in && 374 eap_server_tls_process_cont(data, *pos, end - *pos) < 0) 375 return -1; 376 377 if (flags & EAP_TLS_FLAGS_MORE_FRAGMENTS) { 378 if (eap_server_tls_process_fragment(data, flags, tls_msg_len, 379 *pos, end - *pos) < 0) 380 return -1; 381 382 data->state = FRAG_ACK; 383 return 1; 384 } 385 386 if (data->state == FRAG_ACK) { 387 wpa_printf(MSG_DEBUG, "SSL: All fragments received"); 388 data->state = MSG; 389 } 390 391 if (data->tls_in == NULL) { 392 /* Wrap unfragmented messages as wpabuf without extra copy */ 393 wpabuf_set(&data->tmpbuf, *pos, end - *pos); 394 data->tls_in = &data->tmpbuf; 395 } 396 397 return 0; 398 } 399 400 401 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data) 402 { 403 if (data->tls_in != &data->tmpbuf) 404 wpabuf_free(data->tls_in); 405 data->tls_in = NULL; 406 } 407 408 409 struct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm, 410 struct eap_ssl_data *data, 411 const struct wpabuf *plain) 412 { 413 struct wpabuf *buf; 414 415 buf = tls_connection_encrypt(sm->ssl_ctx, data->conn, 416 plain); 417 if (buf == NULL) { 418 wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 data"); 419 return NULL; 420 } 421 422 return buf; 423 } 424 425 426 int eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data, 427 struct wpabuf *respData, void *priv, int eap_type, 428 int (*proc_version)(struct eap_sm *sm, void *priv, 429 int peer_version), 430 void (*proc_msg)(struct eap_sm *sm, void *priv, 431 const struct wpabuf *respData)) 432 { 433 const u8 *pos; 434 u8 flags; 435 size_t left; 436 int ret, res = 0; 437 438 if (eap_type == EAP_UNAUTH_TLS_TYPE) 439 pos = eap_hdr_validate(EAP_VENDOR_UNAUTH_TLS, 440 EAP_VENDOR_TYPE_UNAUTH_TLS, respData, 441 &left); 442 else if (eap_type == EAP_WFA_UNAUTH_TLS_TYPE) 443 pos = eap_hdr_validate(EAP_VENDOR_WFA_NEW, 444 EAP_VENDOR_WFA_UNAUTH_TLS, respData, 445 &left); 446 else 447 pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, 448 &left); 449 if (pos == NULL || left < 1) 450 return 0; /* Should not happen - frame already validated */ 451 flags = *pos++; 452 left--; 453 wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - Flags 0x%02x", 454 (unsigned long) wpabuf_len(respData), flags); 455 456 if (proc_version && 457 proc_version(sm, priv, flags & EAP_TLS_VERSION_MASK) < 0) 458 return -1; 459 460 ret = eap_server_tls_reassemble(data, flags, &pos, &left); 461 if (ret < 0) { 462 res = -1; 463 goto done; 464 } else if (ret == 1) 465 return 0; 466 467 if (proc_msg) 468 proc_msg(sm, priv, respData); 469 470 if (tls_connection_get_write_alerts(sm->ssl_ctx, data->conn) > 1) { 471 wpa_printf(MSG_INFO, "SSL: Locally detected fatal error in " 472 "TLS processing"); 473 res = -1; 474 } 475 476 done: 477 eap_server_tls_free_in_buf(data); 478 479 return res; 480 } 481