1 /* 2 * EAP-TLS/PEAP/TTLS/FAST server common functions 3 * Copyright (c) 2004-2009, Jouni Malinen <j@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 = sm->tls_flags; 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 const char *label, const u8 *context, 111 size_t context_len, size_t len) 112 { 113 u8 *out; 114 115 out = os_malloc(len); 116 if (out == NULL) 117 return NULL; 118 119 if (tls_connection_export_key(sm->ssl_ctx, data->conn, label, 120 context, context_len, out, len)) { 121 os_free(out); 122 return NULL; 123 } 124 125 return out; 126 } 127 128 129 /** 130 * eap_server_tls_derive_session_id - Derive a Session-Id based on TLS data 131 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 132 * @data: Data for TLS processing 133 * @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) 134 * @len: Pointer to length of the session ID generated 135 * Returns: Pointer to allocated Session-Id on success or %NULL on failure 136 * 137 * This function derive the Session-Id based on the TLS session data 138 * (client/server random and method type). 139 * 140 * The caller is responsible for freeing the returned buffer. 141 */ 142 u8 * eap_server_tls_derive_session_id(struct eap_sm *sm, 143 struct eap_ssl_data *data, u8 eap_type, 144 size_t *len) 145 { 146 struct tls_random keys; 147 u8 *out; 148 149 if (eap_type == EAP_TYPE_TLS && data->tls_v13) { 150 u8 *id, *method_id; 151 152 /* Session-Id = <EAP-Type> || Method-Id 153 * Method-Id = TLS-Exporter("EXPORTER_EAP_TLS_Method-Id", 154 * "", 64) 155 */ 156 *len = 1 + 64; 157 id = os_malloc(*len); 158 if (!id) 159 return NULL; 160 method_id = eap_server_tls_derive_key( 161 sm, data, "EXPORTER_EAP_TLS_Method-Id", NULL, 0, 64); 162 if (!method_id) { 163 os_free(id); 164 return NULL; 165 } 166 id[0] = eap_type; 167 os_memcpy(id + 1, method_id, 64); 168 os_free(method_id); 169 return id; 170 } 171 172 if (tls_connection_get_random(sm->ssl_ctx, data->conn, &keys)) 173 return NULL; 174 175 if (keys.client_random == NULL || keys.server_random == NULL) 176 return NULL; 177 178 *len = 1 + keys.client_random_len + keys.server_random_len; 179 out = os_malloc(*len); 180 if (out == NULL) 181 return NULL; 182 183 /* Session-Id = EAP type || client.random || server.random */ 184 out[0] = eap_type; 185 os_memcpy(out + 1, keys.client_random, keys.client_random_len); 186 os_memcpy(out + 1 + keys.client_random_len, keys.server_random, 187 keys.server_random_len); 188 189 return out; 190 } 191 192 193 struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data, 194 int eap_type, int version, u8 id) 195 { 196 struct wpabuf *req; 197 u8 flags; 198 size_t send_len, plen; 199 200 wpa_printf(MSG_DEBUG, "SSL: Generating Request"); 201 if (data->tls_out == NULL) { 202 wpa_printf(MSG_ERROR, "SSL: tls_out NULL in %s", __func__); 203 return NULL; 204 } 205 206 flags = version; 207 send_len = wpabuf_len(data->tls_out) - data->tls_out_pos; 208 if (1 + send_len > data->tls_out_limit) { 209 send_len = data->tls_out_limit - 1; 210 flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; 211 if (data->tls_out_pos == 0) { 212 flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; 213 send_len -= 4; 214 } 215 } 216 217 plen = 1 + send_len; 218 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 219 plen += 4; 220 221 req = eap_tls_msg_alloc(eap_type, plen, EAP_CODE_REQUEST, id); 222 if (req == NULL) 223 return NULL; 224 225 wpabuf_put_u8(req, flags); /* Flags */ 226 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 227 wpabuf_put_be32(req, wpabuf_len(data->tls_out)); 228 229 wpabuf_put_data(req, wpabuf_head_u8(data->tls_out) + data->tls_out_pos, 230 send_len); 231 data->tls_out_pos += send_len; 232 233 if (data->tls_out_pos == wpabuf_len(data->tls_out)) { 234 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 235 "(message sent completely)", 236 (unsigned long) send_len); 237 wpabuf_free(data->tls_out); 238 data->tls_out = NULL; 239 data->tls_out_pos = 0; 240 data->state = MSG; 241 } else { 242 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 243 "(%lu more to send)", (unsigned long) send_len, 244 (unsigned long) wpabuf_len(data->tls_out) - 245 data->tls_out_pos); 246 data->state = WAIT_FRAG_ACK; 247 } 248 249 return req; 250 } 251 252 253 struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version) 254 { 255 struct wpabuf *req; 256 257 req = eap_tls_msg_alloc(eap_type, 1, EAP_CODE_REQUEST, id); 258 if (req == NULL) 259 return NULL; 260 wpa_printf(MSG_DEBUG, "SSL: Building ACK"); 261 wpabuf_put_u8(req, version); /* Flags */ 262 return req; 263 } 264 265 266 static int eap_server_tls_process_cont(struct eap_ssl_data *data, 267 const u8 *buf, size_t len) 268 { 269 /* Process continuation of a pending message */ 270 if (len > wpabuf_tailroom(data->tls_in)) { 271 wpa_printf(MSG_DEBUG, "SSL: Fragment overflow"); 272 return -1; 273 } 274 275 wpabuf_put_data(data->tls_in, buf, len); 276 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes, waiting for %lu " 277 "bytes more", (unsigned long) len, 278 (unsigned long) wpabuf_tailroom(data->tls_in)); 279 280 return 0; 281 } 282 283 284 static int eap_server_tls_process_fragment(struct eap_ssl_data *data, 285 u8 flags, u32 message_length, 286 const u8 *buf, size_t len) 287 { 288 /* Process a fragment that is not the last one of the message */ 289 if (data->tls_in == NULL && !(flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)) { 290 wpa_printf(MSG_DEBUG, "SSL: No Message Length field in a " 291 "fragmented packet"); 292 return -1; 293 } 294 295 if (data->tls_in == NULL) { 296 /* First fragment of the message */ 297 298 /* Limit length to avoid rogue peers from causing large 299 * memory allocations. */ 300 if (message_length > 65536) { 301 wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size" 302 " over 64 kB)"); 303 return -1; 304 } 305 306 if (len > message_length) { 307 wpa_printf(MSG_INFO, "SSL: Too much data (%d bytes) in " 308 "first fragment of frame (TLS Message " 309 "Length %d bytes)", 310 (int) len, (int) message_length); 311 return -1; 312 } 313 314 data->tls_in = wpabuf_alloc(message_length); 315 if (data->tls_in == NULL) { 316 wpa_printf(MSG_DEBUG, "SSL: No memory for message"); 317 return -1; 318 } 319 wpabuf_put_data(data->tls_in, buf, len); 320 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes in first " 321 "fragment, waiting for %lu bytes more", 322 (unsigned long) len, 323 (unsigned long) wpabuf_tailroom(data->tls_in)); 324 } 325 326 return 0; 327 } 328 329 330 int eap_server_tls_phase1(struct eap_sm *sm, struct eap_ssl_data *data) 331 { 332 char buf[20]; 333 334 if (data->tls_out) { 335 /* This should not happen.. */ 336 wpa_printf(MSG_INFO, "SSL: pending tls_out data when " 337 "processing new message"); 338 wpabuf_free(data->tls_out); 339 WPA_ASSERT(data->tls_out == NULL); 340 } 341 342 data->tls_out = tls_connection_server_handshake(sm->ssl_ctx, 343 data->conn, 344 data->tls_in, NULL); 345 if (data->tls_out == NULL) { 346 wpa_printf(MSG_INFO, "SSL: TLS processing failed"); 347 return -1; 348 } 349 if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) { 350 /* TLS processing has failed - return error */ 351 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to " 352 "report error"); 353 return -1; 354 } 355 356 if (tls_get_version(sm->ssl_ctx, data->conn, buf, sizeof(buf)) == 0) { 357 wpa_printf(MSG_DEBUG, "SSL: Using TLS version %s", buf); 358 data->tls_v13 = os_strcmp(buf, "TLSv1.3") == 0; 359 } 360 361 if (!sm->serial_num && 362 tls_connection_established(sm->ssl_ctx, data->conn)) 363 sm->serial_num = tls_connection_peer_serial_num(sm->ssl_ctx, 364 data->conn); 365 366 return 0; 367 } 368 369 370 static int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags, 371 const u8 **pos, size_t *left) 372 { 373 unsigned int tls_msg_len = 0; 374 const u8 *end = *pos + *left; 375 376 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 377 if (*left < 4) { 378 wpa_printf(MSG_INFO, "SSL: Short frame with TLS " 379 "length"); 380 return -1; 381 } 382 tls_msg_len = WPA_GET_BE32(*pos); 383 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d", 384 tls_msg_len); 385 *pos += 4; 386 *left -= 4; 387 388 if (*left > tls_msg_len) { 389 wpa_printf(MSG_INFO, "SSL: TLS Message Length (%d " 390 "bytes) smaller than this fragment (%d " 391 "bytes)", (int) tls_msg_len, (int) *left); 392 return -1; 393 } 394 } 395 396 wpa_printf(MSG_DEBUG, "SSL: Received packet: Flags 0x%x " 397 "Message Length %u", flags, tls_msg_len); 398 399 if (data->state == WAIT_FRAG_ACK) { 400 if (*left != 0) { 401 wpa_printf(MSG_DEBUG, "SSL: Unexpected payload in " 402 "WAIT_FRAG_ACK state"); 403 return -1; 404 } 405 wpa_printf(MSG_DEBUG, "SSL: Fragment acknowledged"); 406 return 1; 407 } 408 409 if (data->tls_in && 410 eap_server_tls_process_cont(data, *pos, end - *pos) < 0) 411 return -1; 412 413 if (flags & EAP_TLS_FLAGS_MORE_FRAGMENTS) { 414 if (eap_server_tls_process_fragment(data, flags, tls_msg_len, 415 *pos, end - *pos) < 0) 416 return -1; 417 418 data->state = FRAG_ACK; 419 return 1; 420 } 421 422 if (data->state == FRAG_ACK) { 423 wpa_printf(MSG_DEBUG, "SSL: All fragments received"); 424 data->state = MSG; 425 } 426 427 if (data->tls_in == NULL) { 428 /* Wrap unfragmented messages as wpabuf without extra copy */ 429 wpabuf_set(&data->tmpbuf, *pos, end - *pos); 430 data->tls_in = &data->tmpbuf; 431 } 432 433 return 0; 434 } 435 436 437 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data) 438 { 439 if (data->tls_in != &data->tmpbuf) 440 wpabuf_free(data->tls_in); 441 data->tls_in = NULL; 442 } 443 444 445 struct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm, 446 struct eap_ssl_data *data, 447 const struct wpabuf *plain) 448 { 449 struct wpabuf *buf; 450 451 buf = tls_connection_encrypt(sm->ssl_ctx, data->conn, 452 plain); 453 if (buf == NULL) { 454 wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 data"); 455 return NULL; 456 } 457 458 return buf; 459 } 460 461 462 int eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data, 463 struct wpabuf *respData, void *priv, int eap_type, 464 int (*proc_version)(struct eap_sm *sm, void *priv, 465 int peer_version), 466 void (*proc_msg)(struct eap_sm *sm, void *priv, 467 const struct wpabuf *respData)) 468 { 469 const u8 *pos; 470 u8 flags; 471 size_t left; 472 int ret, res = 0; 473 474 if (eap_type == EAP_UNAUTH_TLS_TYPE) 475 pos = eap_hdr_validate(EAP_VENDOR_UNAUTH_TLS, 476 EAP_VENDOR_TYPE_UNAUTH_TLS, respData, 477 &left); 478 else if (eap_type == EAP_WFA_UNAUTH_TLS_TYPE) 479 pos = eap_hdr_validate(EAP_VENDOR_WFA_NEW, 480 EAP_VENDOR_WFA_UNAUTH_TLS, respData, 481 &left); 482 else 483 pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, 484 &left); 485 if (pos == NULL || left < 1) 486 return 0; /* Should not happen - frame already validated */ 487 flags = *pos++; 488 left--; 489 wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - Flags 0x%02x", 490 (unsigned long) wpabuf_len(respData), flags); 491 492 if (proc_version && 493 proc_version(sm, priv, flags & EAP_TLS_VERSION_MASK) < 0) 494 return -1; 495 496 ret = eap_server_tls_reassemble(data, flags, &pos, &left); 497 if (ret < 0) { 498 res = -1; 499 goto done; 500 } else if (ret == 1) 501 return 0; 502 503 if (proc_msg) 504 proc_msg(sm, priv, respData); 505 506 if (tls_connection_get_write_alerts(sm->ssl_ctx, data->conn) > 1) { 507 wpa_printf(MSG_INFO, "SSL: Locally detected fatal error in " 508 "TLS processing"); 509 res = -1; 510 } 511 512 done: 513 eap_server_tls_free_in_buf(data); 514 515 return res; 516 } 517