$search
00001 /* 00002 * TLSv1 server - write handshake message 00003 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "crypto/md5.h" 00019 #include "crypto/sha1.h" 00020 #include "crypto/tls.h" 00021 #include "x509v3.h" 00022 #include "tlsv1_common.h" 00023 #include "tlsv1_record.h" 00024 #include "tlsv1_server.h" 00025 #include "tlsv1_server_i.h" 00026 00027 00028 static size_t tls_server_cert_chain_der_len(struct tlsv1_server *conn) 00029 { 00030 size_t len = 0; 00031 struct x509_certificate *cert; 00032 00033 cert = conn->cred->cert; 00034 while (cert) { 00035 len += 3 + cert->cert_len; 00036 if (x509_certificate_self_signed(cert)) 00037 break; 00038 cert = x509_certificate_get_subject(conn->cred->trusted_certs, 00039 &cert->issuer); 00040 } 00041 00042 return len; 00043 } 00044 00045 00046 static int tls_write_server_hello(struct tlsv1_server *conn, 00047 u8 **msgpos, u8 *end) 00048 { 00049 u8 *pos, *rhdr, *hs_start, *hs_length; 00050 struct os_time now; 00051 size_t rlen; 00052 00053 pos = *msgpos; 00054 00055 wpa_printf(MSG_DEBUG, "TLSv1: Send ServerHello"); 00056 rhdr = pos; 00057 pos += TLS_RECORD_HEADER_LEN; 00058 00059 os_get_time(&now); 00060 WPA_PUT_BE32(conn->server_random, now.sec); 00061 if (os_get_random(conn->server_random + 4, TLS_RANDOM_LEN - 4)) { 00062 wpa_printf(MSG_ERROR, "TLSv1: Could not generate " 00063 "server_random"); 00064 return -1; 00065 } 00066 wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random", 00067 conn->server_random, TLS_RANDOM_LEN); 00068 00069 conn->session_id_len = TLS_SESSION_ID_MAX_LEN; 00070 if (os_get_random(conn->session_id, conn->session_id_len)) { 00071 wpa_printf(MSG_ERROR, "TLSv1: Could not generate " 00072 "session_id"); 00073 return -1; 00074 } 00075 wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id", 00076 conn->session_id, conn->session_id_len); 00077 00078 /* opaque fragment[TLSPlaintext.length] */ 00079 00080 /* Handshake */ 00081 hs_start = pos; 00082 /* HandshakeType msg_type */ 00083 *pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO; 00084 /* uint24 length (to be filled) */ 00085 hs_length = pos; 00086 pos += 3; 00087 /* body - ServerHello */ 00088 /* ProtocolVersion server_version */ 00089 WPA_PUT_BE16(pos, TLS_VERSION); 00090 pos += 2; 00091 /* Random random: uint32 gmt_unix_time, opaque random_bytes */ 00092 os_memcpy(pos, conn->server_random, TLS_RANDOM_LEN); 00093 pos += TLS_RANDOM_LEN; 00094 /* SessionID session_id */ 00095 *pos++ = conn->session_id_len; 00096 os_memcpy(pos, conn->session_id, conn->session_id_len); 00097 pos += conn->session_id_len; 00098 /* CipherSuite cipher_suite */ 00099 WPA_PUT_BE16(pos, conn->cipher_suite); 00100 pos += 2; 00101 /* CompressionMethod compression_method */ 00102 *pos++ = TLS_COMPRESSION_NULL; 00103 00104 if (conn->session_ticket && conn->session_ticket_cb) { 00105 int res = conn->session_ticket_cb( 00106 conn->session_ticket_cb_ctx, 00107 conn->session_ticket, conn->session_ticket_len, 00108 conn->client_random, conn->server_random, 00109 conn->master_secret); 00110 if (res < 0) { 00111 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback " 00112 "indicated failure"); 00113 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00114 TLS_ALERT_HANDSHAKE_FAILURE); 00115 return -1; 00116 } 00117 conn->use_session_ticket = res; 00118 00119 if (conn->use_session_ticket) { 00120 if (tlsv1_server_derive_keys(conn, NULL, 0) < 0) { 00121 wpa_printf(MSG_DEBUG, "TLSv1: Failed to " 00122 "derive keys"); 00123 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00124 TLS_ALERT_INTERNAL_ERROR); 00125 return -1; 00126 } 00127 } 00128 00129 /* 00130 * RFC 4507 specifies that server would include an empty 00131 * SessionTicket extension in ServerHello and a 00132 * NewSessionTicket message after the ServerHello. However, 00133 * EAP-FAST (RFC 4851), i.e., the only user of SessionTicket 00134 * extension at the moment, does not use such extensions. 00135 * 00136 * TODO: Add support for configuring RFC 4507 behavior and make 00137 * EAP-FAST disable it. 00138 */ 00139 } 00140 00141 WPA_PUT_BE24(hs_length, pos - hs_length - 3); 00142 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 00143 00144 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 00145 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) { 00146 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record"); 00147 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00148 TLS_ALERT_INTERNAL_ERROR); 00149 return -1; 00150 } 00151 pos = rhdr + rlen; 00152 00153 *msgpos = pos; 00154 00155 return 0; 00156 } 00157 00158 00159 static int tls_write_server_certificate(struct tlsv1_server *conn, 00160 u8 **msgpos, u8 *end) 00161 { 00162 u8 *pos, *rhdr, *hs_start, *hs_length, *cert_start; 00163 size_t rlen; 00164 struct x509_certificate *cert; 00165 const struct tls_cipher_suite *suite; 00166 00167 suite = tls_get_cipher_suite(conn->rl.cipher_suite); 00168 if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) { 00169 wpa_printf(MSG_DEBUG, "TLSv1: Do not send Certificate when " 00170 "using anonymous DH"); 00171 return 0; 00172 } 00173 00174 pos = *msgpos; 00175 00176 wpa_printf(MSG_DEBUG, "TLSv1: Send Certificate"); 00177 rhdr = pos; 00178 pos += TLS_RECORD_HEADER_LEN; 00179 00180 /* opaque fragment[TLSPlaintext.length] */ 00181 00182 /* Handshake */ 00183 hs_start = pos; 00184 /* HandshakeType msg_type */ 00185 *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE; 00186 /* uint24 length (to be filled) */ 00187 hs_length = pos; 00188 pos += 3; 00189 /* body - Certificate */ 00190 /* uint24 length (to be filled) */ 00191 cert_start = pos; 00192 pos += 3; 00193 cert = conn->cred->cert; 00194 while (cert) { 00195 if (pos + 3 + cert->cert_len > end) { 00196 wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space " 00197 "for Certificate (cert_len=%lu left=%lu)", 00198 (unsigned long) cert->cert_len, 00199 (unsigned long) (end - pos)); 00200 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00201 TLS_ALERT_INTERNAL_ERROR); 00202 return -1; 00203 } 00204 WPA_PUT_BE24(pos, cert->cert_len); 00205 pos += 3; 00206 os_memcpy(pos, cert->cert_start, cert->cert_len); 00207 pos += cert->cert_len; 00208 00209 if (x509_certificate_self_signed(cert)) 00210 break; 00211 cert = x509_certificate_get_subject(conn->cred->trusted_certs, 00212 &cert->issuer); 00213 } 00214 if (cert == conn->cred->cert || cert == NULL) { 00215 /* 00216 * Server was not configured with all the needed certificates 00217 * to form a full certificate chain. The client may fail to 00218 * validate the chain unless it is configured with all the 00219 * missing CA certificates. 00220 */ 00221 wpa_printf(MSG_DEBUG, "TLSv1: Full server certificate chain " 00222 "not configured - validation may fail"); 00223 } 00224 WPA_PUT_BE24(cert_start, pos - cert_start - 3); 00225 00226 WPA_PUT_BE24(hs_length, pos - hs_length - 3); 00227 00228 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 00229 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) { 00230 wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 00231 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00232 TLS_ALERT_INTERNAL_ERROR); 00233 return -1; 00234 } 00235 pos = rhdr + rlen; 00236 00237 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 00238 00239 *msgpos = pos; 00240 00241 return 0; 00242 } 00243 00244 00245 static int tls_write_server_key_exchange(struct tlsv1_server *conn, 00246 u8 **msgpos, u8 *end) 00247 { 00248 tls_key_exchange keyx; 00249 const struct tls_cipher_suite *suite; 00250 u8 *pos, *rhdr, *hs_start, *hs_length; 00251 size_t rlen; 00252 u8 *dh_ys; 00253 size_t dh_ys_len; 00254 00255 suite = tls_get_cipher_suite(conn->rl.cipher_suite); 00256 if (suite == NULL) 00257 keyx = TLS_KEY_X_NULL; 00258 else 00259 keyx = suite->key_exchange; 00260 00261 if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) { 00262 wpa_printf(MSG_DEBUG, "TLSv1: No ServerKeyExchange needed"); 00263 return 0; 00264 } 00265 00266 if (keyx != TLS_KEY_X_DH_anon) { 00267 /* TODO? */ 00268 wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not yet " 00269 "supported with key exchange type %d", keyx); 00270 return -1; 00271 } 00272 00273 if (conn->cred == NULL || conn->cred->dh_p == NULL || 00274 conn->cred->dh_g == NULL) { 00275 wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available for " 00276 "ServerKeyExhcange"); 00277 return -1; 00278 } 00279 00280 os_free(conn->dh_secret); 00281 conn->dh_secret_len = conn->cred->dh_p_len; 00282 conn->dh_secret = os_malloc(conn->dh_secret_len); 00283 if (conn->dh_secret == NULL) { 00284 wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate " 00285 "memory for secret (Diffie-Hellman)"); 00286 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00287 TLS_ALERT_INTERNAL_ERROR); 00288 return -1; 00289 } 00290 if (os_get_random(conn->dh_secret, conn->dh_secret_len)) { 00291 wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random " 00292 "data for Diffie-Hellman"); 00293 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00294 TLS_ALERT_INTERNAL_ERROR); 00295 os_free(conn->dh_secret); 00296 conn->dh_secret = NULL; 00297 return -1; 00298 } 00299 00300 if (os_memcmp(conn->dh_secret, conn->cred->dh_p, conn->dh_secret_len) > 00301 0) 00302 conn->dh_secret[0] = 0; /* make sure secret < p */ 00303 00304 pos = conn->dh_secret; 00305 while (pos + 1 < conn->dh_secret + conn->dh_secret_len && *pos == 0) 00306 pos++; 00307 if (pos != conn->dh_secret) { 00308 os_memmove(conn->dh_secret, pos, 00309 conn->dh_secret_len - (pos - conn->dh_secret)); 00310 conn->dh_secret_len -= pos - conn->dh_secret; 00311 } 00312 wpa_hexdump_key(MSG_DEBUG, "TLSv1: DH server's secret value", 00313 conn->dh_secret, conn->dh_secret_len); 00314 00315 /* Ys = g^secret mod p */ 00316 dh_ys_len = conn->cred->dh_p_len; 00317 dh_ys = os_malloc(dh_ys_len); 00318 if (dh_ys == NULL) { 00319 wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate memory for " 00320 "Diffie-Hellman"); 00321 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00322 TLS_ALERT_INTERNAL_ERROR); 00323 return -1; 00324 } 00325 if (crypto_mod_exp(conn->cred->dh_g, conn->cred->dh_g_len, 00326 conn->dh_secret, conn->dh_secret_len, 00327 conn->cred->dh_p, conn->cred->dh_p_len, 00328 dh_ys, &dh_ys_len)) { 00329 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00330 TLS_ALERT_INTERNAL_ERROR); 00331 os_free(dh_ys); 00332 return -1; 00333 } 00334 00335 wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)", 00336 dh_ys, dh_ys_len); 00337 00338 /* 00339 * struct { 00340 * select (KeyExchangeAlgorithm) { 00341 * case diffie_hellman: 00342 * ServerDHParams params; 00343 * Signature signed_params; 00344 * case rsa: 00345 * ServerRSAParams params; 00346 * Signature signed_params; 00347 * }; 00348 * } ServerKeyExchange; 00349 * 00350 * struct { 00351 * opaque dh_p<1..2^16-1>; 00352 * opaque dh_g<1..2^16-1>; 00353 * opaque dh_Ys<1..2^16-1>; 00354 * } ServerDHParams; 00355 */ 00356 00357 pos = *msgpos; 00358 00359 wpa_printf(MSG_DEBUG, "TLSv1: Send ServerKeyExchange"); 00360 rhdr = pos; 00361 pos += TLS_RECORD_HEADER_LEN; 00362 00363 /* opaque fragment[TLSPlaintext.length] */ 00364 00365 /* Handshake */ 00366 hs_start = pos; 00367 /* HandshakeType msg_type */ 00368 *pos++ = TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE; 00369 /* uint24 length (to be filled) */ 00370 hs_length = pos; 00371 pos += 3; 00372 00373 /* body - ServerDHParams */ 00374 /* dh_p */ 00375 if (pos + 2 + conn->cred->dh_p_len > end) { 00376 wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for " 00377 "dh_p"); 00378 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00379 TLS_ALERT_INTERNAL_ERROR); 00380 os_free(dh_ys); 00381 return -1; 00382 } 00383 WPA_PUT_BE16(pos, conn->cred->dh_p_len); 00384 pos += 2; 00385 os_memcpy(pos, conn->cred->dh_p, conn->cred->dh_p_len); 00386 pos += conn->cred->dh_p_len; 00387 00388 /* dh_g */ 00389 if (pos + 2 + conn->cred->dh_g_len > end) { 00390 wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for " 00391 "dh_g"); 00392 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00393 TLS_ALERT_INTERNAL_ERROR); 00394 os_free(dh_ys); 00395 return -1; 00396 } 00397 WPA_PUT_BE16(pos, conn->cred->dh_g_len); 00398 pos += 2; 00399 os_memcpy(pos, conn->cred->dh_g, conn->cred->dh_g_len); 00400 pos += conn->cred->dh_g_len; 00401 00402 /* dh_Ys */ 00403 if (pos + 2 + dh_ys_len > end) { 00404 wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for " 00405 "dh_Ys"); 00406 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00407 TLS_ALERT_INTERNAL_ERROR); 00408 os_free(dh_ys); 00409 return -1; 00410 } 00411 WPA_PUT_BE16(pos, dh_ys_len); 00412 pos += 2; 00413 os_memcpy(pos, dh_ys, dh_ys_len); 00414 pos += dh_ys_len; 00415 os_free(dh_ys); 00416 00417 WPA_PUT_BE24(hs_length, pos - hs_length - 3); 00418 00419 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 00420 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) { 00421 wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 00422 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00423 TLS_ALERT_INTERNAL_ERROR); 00424 return -1; 00425 } 00426 pos = rhdr + rlen; 00427 00428 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 00429 00430 *msgpos = pos; 00431 00432 return 0; 00433 } 00434 00435 00436 static int tls_write_server_certificate_request(struct tlsv1_server *conn, 00437 u8 **msgpos, u8 *end) 00438 { 00439 u8 *pos, *rhdr, *hs_start, *hs_length; 00440 size_t rlen; 00441 00442 if (!conn->verify_peer) { 00443 wpa_printf(MSG_DEBUG, "TLSv1: No CertificateRequest needed"); 00444 return 0; 00445 } 00446 00447 pos = *msgpos; 00448 00449 wpa_printf(MSG_DEBUG, "TLSv1: Send CertificateRequest"); 00450 rhdr = pos; 00451 pos += TLS_RECORD_HEADER_LEN; 00452 00453 /* opaque fragment[TLSPlaintext.length] */ 00454 00455 /* Handshake */ 00456 hs_start = pos; 00457 /* HandshakeType msg_type */ 00458 *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST; 00459 /* uint24 length (to be filled) */ 00460 hs_length = pos; 00461 pos += 3; 00462 /* body - CertificateRequest */ 00463 00464 /* 00465 * enum { 00466 * rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4), 00467 * (255) 00468 * } ClientCertificateType; 00469 * ClientCertificateType certificate_types<1..2^8-1> 00470 */ 00471 *pos++ = 1; 00472 *pos++ = 1; /* rsa_sign */ 00473 00474 /* 00475 * opaque DistinguishedName<1..2^16-1> 00476 * DistinguishedName certificate_authorities<3..2^16-1> 00477 */ 00478 /* TODO: add support for listing DNs for trusted CAs */ 00479 WPA_PUT_BE16(pos, 0); 00480 pos += 2; 00481 00482 WPA_PUT_BE24(hs_length, pos - hs_length - 3); 00483 00484 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 00485 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) { 00486 wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 00487 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00488 TLS_ALERT_INTERNAL_ERROR); 00489 return -1; 00490 } 00491 pos = rhdr + rlen; 00492 00493 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 00494 00495 *msgpos = pos; 00496 00497 return 0; 00498 } 00499 00500 00501 static int tls_write_server_hello_done(struct tlsv1_server *conn, 00502 u8 **msgpos, u8 *end) 00503 { 00504 u8 *pos, *rhdr, *hs_start, *hs_length; 00505 size_t rlen; 00506 00507 pos = *msgpos; 00508 00509 wpa_printf(MSG_DEBUG, "TLSv1: Send ServerHelloDone"); 00510 rhdr = pos; 00511 pos += TLS_RECORD_HEADER_LEN; 00512 00513 /* opaque fragment[TLSPlaintext.length] */ 00514 00515 /* Handshake */ 00516 hs_start = pos; 00517 /* HandshakeType msg_type */ 00518 *pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE; 00519 /* uint24 length (to be filled) */ 00520 hs_length = pos; 00521 pos += 3; 00522 /* body - ServerHelloDone (empty) */ 00523 00524 WPA_PUT_BE24(hs_length, pos - hs_length - 3); 00525 00526 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 00527 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) { 00528 wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 00529 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00530 TLS_ALERT_INTERNAL_ERROR); 00531 return -1; 00532 } 00533 pos = rhdr + rlen; 00534 00535 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 00536 00537 *msgpos = pos; 00538 00539 return 0; 00540 } 00541 00542 00543 static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn, 00544 u8 **msgpos, u8 *end) 00545 { 00546 u8 *pos, *rhdr; 00547 size_t rlen; 00548 00549 pos = *msgpos; 00550 00551 wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec"); 00552 rhdr = pos; 00553 pos += TLS_RECORD_HEADER_LEN; 00554 *pos = TLS_CHANGE_CIPHER_SPEC; 00555 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC, 00556 rhdr, end - rhdr, 1, &rlen) < 0) { 00557 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record"); 00558 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00559 TLS_ALERT_INTERNAL_ERROR); 00560 return -1; 00561 } 00562 00563 if (tlsv1_record_change_write_cipher(&conn->rl) < 0) { 00564 wpa_printf(MSG_DEBUG, "TLSv1: Failed to set write cipher for " 00565 "record layer"); 00566 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00567 TLS_ALERT_INTERNAL_ERROR); 00568 return -1; 00569 } 00570 00571 *msgpos = rhdr + rlen; 00572 00573 return 0; 00574 } 00575 00576 00577 static int tls_write_server_finished(struct tlsv1_server *conn, 00578 u8 **msgpos, u8 *end) 00579 { 00580 u8 *pos, *rhdr, *hs_start, *hs_length; 00581 size_t rlen, hlen; 00582 u8 verify_data[TLS_VERIFY_DATA_LEN]; 00583 u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 00584 00585 pos = *msgpos; 00586 00587 wpa_printf(MSG_DEBUG, "TLSv1: Send Finished"); 00588 00589 /* Encrypted Handshake Message: Finished */ 00590 00591 hlen = MD5_MAC_LEN; 00592 if (conn->verify.md5_server == NULL || 00593 crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) { 00594 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00595 TLS_ALERT_INTERNAL_ERROR); 00596 conn->verify.md5_server = NULL; 00597 crypto_hash_finish(conn->verify.sha1_server, NULL, NULL); 00598 conn->verify.sha1_server = NULL; 00599 return -1; 00600 } 00601 conn->verify.md5_server = NULL; 00602 hlen = SHA1_MAC_LEN; 00603 if (conn->verify.sha1_server == NULL || 00604 crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN, 00605 &hlen) < 0) { 00606 conn->verify.sha1_server = NULL; 00607 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00608 TLS_ALERT_INTERNAL_ERROR); 00609 return -1; 00610 } 00611 conn->verify.sha1_server = NULL; 00612 00613 if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN, 00614 "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN, 00615 verify_data, TLS_VERIFY_DATA_LEN)) { 00616 wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data"); 00617 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00618 TLS_ALERT_INTERNAL_ERROR); 00619 return -1; 00620 } 00621 wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)", 00622 verify_data, TLS_VERIFY_DATA_LEN); 00623 00624 rhdr = pos; 00625 pos += TLS_RECORD_HEADER_LEN; 00626 /* Handshake */ 00627 hs_start = pos; 00628 /* HandshakeType msg_type */ 00629 *pos++ = TLS_HANDSHAKE_TYPE_FINISHED; 00630 /* uint24 length (to be filled) */ 00631 hs_length = pos; 00632 pos += 3; 00633 os_memcpy(pos, verify_data, TLS_VERIFY_DATA_LEN); 00634 pos += TLS_VERIFY_DATA_LEN; 00635 WPA_PUT_BE24(hs_length, pos - hs_length - 3); 00636 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 00637 00638 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 00639 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) { 00640 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record"); 00641 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 00642 TLS_ALERT_INTERNAL_ERROR); 00643 return -1; 00644 } 00645 00646 pos = rhdr + rlen; 00647 00648 *msgpos = pos; 00649 00650 return 0; 00651 } 00652 00653 00654 static u8 * tls_send_server_hello(struct tlsv1_server *conn, size_t *out_len) 00655 { 00656 u8 *msg, *end, *pos; 00657 size_t msglen; 00658 00659 *out_len = 0; 00660 00661 msglen = 1000 + tls_server_cert_chain_der_len(conn); 00662 00663 msg = os_malloc(msglen); 00664 if (msg == NULL) 00665 return NULL; 00666 00667 pos = msg; 00668 end = msg + msglen; 00669 00670 if (tls_write_server_hello(conn, &pos, end) < 0) { 00671 os_free(msg); 00672 return NULL; 00673 } 00674 00675 if (conn->use_session_ticket) { 00676 /* Abbreviated handshake using session ticket; RFC 4507 */ 00677 if (tls_write_server_change_cipher_spec(conn, &pos, end) < 0 || 00678 tls_write_server_finished(conn, &pos, end) < 0) { 00679 os_free(msg); 00680 return NULL; 00681 } 00682 00683 *out_len = pos - msg; 00684 00685 conn->state = CHANGE_CIPHER_SPEC; 00686 00687 return msg; 00688 } 00689 00690 /* Full handshake */ 00691 if (tls_write_server_certificate(conn, &pos, end) < 0 || 00692 tls_write_server_key_exchange(conn, &pos, end) < 0 || 00693 tls_write_server_certificate_request(conn, &pos, end) < 0 || 00694 tls_write_server_hello_done(conn, &pos, end) < 0) { 00695 os_free(msg); 00696 return NULL; 00697 } 00698 00699 *out_len = pos - msg; 00700 00701 conn->state = CLIENT_CERTIFICATE; 00702 00703 return msg; 00704 } 00705 00706 00707 static u8 * tls_send_change_cipher_spec(struct tlsv1_server *conn, 00708 size_t *out_len) 00709 { 00710 u8 *msg, *end, *pos; 00711 00712 *out_len = 0; 00713 00714 msg = os_malloc(1000); 00715 if (msg == NULL) 00716 return NULL; 00717 00718 pos = msg; 00719 end = msg + 1000; 00720 00721 if (tls_write_server_change_cipher_spec(conn, &pos, end) < 0 || 00722 tls_write_server_finished(conn, &pos, end) < 0) { 00723 os_free(msg); 00724 return NULL; 00725 } 00726 00727 *out_len = pos - msg; 00728 00729 wpa_printf(MSG_DEBUG, "TLSv1: Handshake completed successfully"); 00730 conn->state = ESTABLISHED; 00731 00732 return msg; 00733 } 00734 00735 00736 u8 * tlsv1_server_handshake_write(struct tlsv1_server *conn, size_t *out_len) 00737 { 00738 switch (conn->state) { 00739 case SERVER_HELLO: 00740 return tls_send_server_hello(conn, out_len); 00741 case SERVER_CHANGE_CIPHER_SPEC: 00742 return tls_send_change_cipher_spec(conn, out_len); 00743 default: 00744 if (conn->state == ESTABLISHED && conn->use_session_ticket) { 00745 /* Abbreviated handshake was already completed. */ 00746 return NULL; 00747 } 00748 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d while " 00749 "generating reply", conn->state); 00750 return NULL; 00751 } 00752 } 00753 00754 00755 u8 * tlsv1_server_send_alert(struct tlsv1_server *conn, u8 level, 00756 u8 description, size_t *out_len) 00757 { 00758 u8 *alert, *pos, *length; 00759 00760 wpa_printf(MSG_DEBUG, "TLSv1: Send Alert(%d:%d)", level, description); 00761 *out_len = 0; 00762 00763 alert = os_malloc(10); 00764 if (alert == NULL) 00765 return NULL; 00766 00767 pos = alert; 00768 00769 /* TLSPlaintext */ 00770 /* ContentType type */ 00771 *pos++ = TLS_CONTENT_TYPE_ALERT; 00772 /* ProtocolVersion version */ 00773 WPA_PUT_BE16(pos, TLS_VERSION); 00774 pos += 2; 00775 /* uint16 length (to be filled) */ 00776 length = pos; 00777 pos += 2; 00778 /* opaque fragment[TLSPlaintext.length] */ 00779 00780 /* Alert */ 00781 /* AlertLevel level */ 00782 *pos++ = level; 00783 /* AlertDescription description */ 00784 *pos++ = description; 00785 00786 WPA_PUT_BE16(length, pos - length - 2); 00787 *out_len = pos - alert; 00788 00789 return alert; 00790 }