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