18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLSv1 server - write handshake message 3818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/md5.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h" 141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "crypto/sha256.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "x509v3.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_common.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_record.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_server.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_server_i.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic size_t tls_server_cert_chain_der_len(struct tlsv1_server *conn) 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = 0; 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct x509_certificate *cert; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = conn->cred->cert; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (cert) { 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += 3 + cert->cert_len; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509_certificate_self_signed(cert)) 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = x509_certificate_get_subject(conn->cred->trusted_certs, 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &cert->issuer); 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_hello(struct tlsv1_server *conn, 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *rhdr, *hs_start, *hs_length; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = *msgpos; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send ServerHello"); 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rhdr = pos; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RECORD_HEADER_LEN; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE32(conn->server_random, now.sec); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(conn->server_random + 4, TLS_RANDOM_LEN - 4)) { 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLSv1: Could not generate " 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "server_random"); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random", 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->server_random, TLS_RANDOM_LEN); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_id_len = TLS_SESSION_ID_MAX_LEN; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(conn->session_id, conn->session_id_len)) { 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLSv1: Could not generate " 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "session_id"); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id", 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_id, conn->session_id_len); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_start = pos; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length (to be filled) */ 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_length = pos; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ServerHello */ 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ProtocolVersion server_version */ 851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_PUT_BE16(pos, conn->rl.tls_version); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Random random: uint32 gmt_unix_time, opaque random_bytes */ 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, conn->server_random, TLS_RANDOM_LEN); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RANDOM_LEN; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionID session_id */ 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = conn->session_id_len; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, conn->session_id, conn->session_id_len); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->session_id_len; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CipherSuite cipher_suite */ 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(pos, conn->cipher_suite); 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CompressionMethod compression_method */ 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_COMPRESSION_NULL; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket && conn->session_ticket_cb) { 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = conn->session_ticket_cb( 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx, 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket, conn->session_ticket_len, 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_random, conn->server_random, 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->master_secret); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 107818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "SessionTicket callback indicated failure"); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_HANDSHAKE_FAILURE); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->use_session_ticket = res; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_server_derive_keys(conn, NULL, 0) < 0) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to " 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "derive keys"); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4507 specifies that server would include an empty 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SessionTicket extension in ServerHello and a 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NewSessionTicket message after the ServerHello. However, 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-FAST (RFC 4851), i.e., the only user of SessionTicket 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * extension at the moment, does not use such extensions. 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: Add support for configuring RFC 4507 behavior and make 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-FAST disable it. 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(hs_length, pos - hs_length - 3); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 1401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rhdr, end - rhdr, hs_start, pos - hs_start, 1411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record"); 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = rhdr + rlen; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msgpos = pos; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_certificate(struct tlsv1_server *conn, 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *rhdr, *hs_start, *hs_length, *cert_start; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct x509_certificate *cert; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) { 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Do not send Certificate when " 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "using anonymous DH"); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = *msgpos; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 172818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send Certificate"); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rhdr = pos; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RECORD_HEADER_LEN; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_start = pos; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length (to be filled) */ 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_length = pos; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - Certificate */ 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length (to be filled) */ 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert_start = pos; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = conn->cred->cert; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (cert) { 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 3 + cert->cert_len > end) { 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space " 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for Certificate (cert_len=%lu left=%lu)", 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) cert->cert_len, 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(pos, cert->cert_len); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, cert->cert_start, cert->cert_len); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += cert->cert_len; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509_certificate_self_signed(cert)) 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = x509_certificate_get_subject(conn->cred->trusted_certs, 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &cert->issuer); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == conn->cred->cert || cert == NULL) { 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Server was not configured with all the needed certificates 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to form a full certificate chain. The client may fail to 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * validate the chain unless it is configured with all the 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * missing CA certificates. 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Full server certificate chain " 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not configured - validation may fail"); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(cert_start, pos - cert_start - 3); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(hs_length, pos - hs_length - 3); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 2251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rhdr, end - rhdr, hs_start, pos - hs_start, 2261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = rhdr + rlen; 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msgpos = pos; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_key_exchange(struct tlsv1_server *conn, 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_key_exchange keyx; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 247818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 *pos, *rhdr, *hs_start, *hs_length, *server_params; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *dh_ys; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t dh_ys_len; 251b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt const u8 *dh_p; 252b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t dh_p_len; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite == NULL) 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = TLS_KEY_X_NULL; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = suite->key_exchange; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) { 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No ServerKeyExchange needed"); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 265818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (keyx != TLS_KEY_X_DH_anon && keyx != TLS_KEY_X_DHE_RSA) { 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not yet " 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "supported with key exchange type %d", keyx); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cred == NULL || conn->cred->dh_p == NULL || 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cred->dh_g == NULL) { 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available for " 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerKeyExhcange"); 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tlsv1_server_get_dh_p(conn, &dh_p, &dh_p_len); 279b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->dh_secret); 281b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt conn->dh_secret_len = dh_p_len; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret = os_malloc(conn->dh_secret_len); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_secret == NULL) { 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate " 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "memory for secret (Diffie-Hellman)"); 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(conn->dh_secret, conn->dh_secret_len)) { 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random " 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data for Diffie-Hellman"); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->dh_secret); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret = NULL; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 300b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (os_memcmp(conn->dh_secret, dh_p, conn->dh_secret_len) > 0) 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret[0] = 0; /* make sure secret < p */ 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = conn->dh_secret; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < conn->dh_secret + conn->dh_secret_len && *pos == 0) 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos != conn->dh_secret) { 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memmove(conn->dh_secret, pos, 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret_len - (pos - conn->dh_secret)); 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret_len -= pos - conn->dh_secret; 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: DH server's secret value", 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret, conn->dh_secret_len); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ys = g^secret mod p */ 315b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt dh_ys_len = dh_p_len; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_ys = os_malloc(dh_ys_len); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_ys == NULL) { 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate memory for " 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Diffie-Hellman"); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_mod_exp(conn->cred->dh_g, conn->cred->dh_g_len, 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret, conn->dh_secret_len, 326b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt dh_p, dh_p_len, dh_ys, &dh_ys_len)) { 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)", 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_ys, dh_ys_len); 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * select (KeyExchangeAlgorithm) { 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case diffie_hellman: 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ServerDHParams params; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Signature signed_params; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case rsa: 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ServerRSAParams params; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Signature signed_params; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * }; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } ServerKeyExchange; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque dh_p<1..2^16-1>; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque dh_g<1..2^16-1>; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque dh_Ys<1..2^16-1>; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } ServerDHParams; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = *msgpos; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 357818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send ServerKeyExchange"); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rhdr = pos; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RECORD_HEADER_LEN; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_start = pos; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length (to be filled) */ 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_length = pos; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ServerDHParams */ 372818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params = pos; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dh_p */ 374b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (pos + 2 + dh_p_len > end) { 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for " 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_p"); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 382b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt WPA_PUT_BE16(pos, dh_p_len); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 384b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt os_memcpy(pos, dh_p, dh_p_len); 385b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt pos += dh_p_len; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dh_g */ 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + conn->cred->dh_g_len > end) { 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for " 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_g"); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(pos, conn->cred->dh_g_len); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, conn->cred->dh_g, conn->cred->dh_g_len); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->cred->dh_g_len; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dh_Ys */ 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + dh_ys_len > end) { 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for " 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_Ys"); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(pos, dh_ys_len); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, dh_ys, dh_ys_len); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += dh_ys_len; 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 416818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 417818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * select (SignatureAlgorithm) 418818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * { case anonymous: struct { }; 419818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * case rsa: 420818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * digitally-signed struct { 421818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * opaque md5_hash[16]; 422818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * opaque sha_hash[20]; 423818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * }; 424818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * case dsa: 425818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * digitally-signed struct { 426818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * opaque sha_hash[20]; 427818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * }; 428818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * } Signature; 429818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 430818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * md5_hash 431818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * MD5(ClientHello.random + ServerHello.random + ServerParams); 432818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 433818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * sha_hash 434818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * SHA(ClientHello.random + ServerHello.random + ServerParams); 435818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 436818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 437818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (keyx == TLS_KEY_X_DHE_RSA) { 438818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 hash[100]; 439818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 *signed_start; 440818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt size_t clen; 441818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt int hlen; 442818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 443818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 444818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TLSV12 445818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen = tlsv12_key_x_server_params_hash( 446818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->rl.tls_version, conn->client_random, 447818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_random, server_params, 448818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos - server_params, hash + 19); 449818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 450818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 451818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * RFC 5246, 4.7: 452818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * TLS v1.2 adds explicit indication of the used 453818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * signature and hash algorithms. 454818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 455818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * struct { 456818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * HashAlgorithm hash; 457818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * SignatureAlgorithm signature; 458818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * } SignatureAndHashAlgorithm; 459818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 460818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (hlen < 0 || pos + 2 > end) { 461818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 462818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 463818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return -1; 464818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 465818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt *pos++ = TLS_HASH_ALG_SHA256; 466818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt *pos++ = TLS_SIGN_ALG_RSA; 467818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 468818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 469818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * RFC 3447, A.2.4 RSASSA-PKCS1-v1_5 470818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 471818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * DigestInfo ::= SEQUENCE { 472818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * digestAlgorithm DigestAlgorithm, 473818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * digest OCTET STRING 474818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * } 475818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 476818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * SHA-256 OID: sha256WithRSAEncryption ::= {pkcs-1 11} 477818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 478818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * DER encoded DigestInfo for SHA256 per RFC 3447: 479818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 480818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 04 20 || H 481818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 482818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen += 19; 483818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_memcpy(hash, 484818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65" 485818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "\x03\x04\x02\x01\x05\x00\x04\x20", 19); 486818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 487818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#else /* CONFIG_TLSV12 */ 488818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 489818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 490818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return -1; 491818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TLSV12 */ 492818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } else { 493818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen = tls_key_x_server_params_hash( 494818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->rl.tls_version, conn->client_random, 495818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_random, server_params, 496818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos - server_params, hash); 497818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 498818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 499818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (hlen < 0) { 500818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 501818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 502818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return -1; 503818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 504818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 505818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLS: ServerKeyExchange signed_params hash", 506818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hash, hlen); 507818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 508818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->test_flags & TLS_BREAK_SRV_KEY_X_HASH) { 509818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "TESTING: Break ServerKeyExchange signed params hash"); 510818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hash[hlen - 1] ^= 0x80; 511818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 512818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 513818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 514818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 515818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * RFC 2246, 4.7: 516818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * In digital signing, one-way hash functions are used as input 517818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * for a signing algorithm. A digitally-signed element is 518818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * encoded as an opaque vector <0..2^16-1>, where the length is 519818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * specified by the signing algorithm and key. 520818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 521818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * In RSA signing, a 36-byte structure of two hashes (one SHA 522818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * and one MD5) is signed (encrypted with the private key). It 523818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * is encoded with PKCS #1 block type 0 or type 1 as described 524818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * in [PKCS1]. 525818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 526818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt signed_start = pos; /* length to be filled */ 527818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos += 2; 528818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt clen = end - pos; 529818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->cred == NULL || 530818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt crypto_private_key_sign_pkcs1(conn->cred->key, hash, hlen, 531818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos, &clen) < 0) { 532818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to sign hash (PKCS #1)"); 533818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 534818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 535818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return -1; 536818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 537818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt WPA_PUT_BE16(signed_start, clen); 538818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 539818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->test_flags & TLS_BREAK_SRV_KEY_X_SIGNATURE) { 540818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "TESTING: Break ServerKeyExchange signed params signature"); 541818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos[clen - 1] ^= 0x80; 542818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 543818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 544818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 545818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos += clen; 546818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 547818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(hs_length, pos - hs_length - 3); 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 5511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rhdr, end - rhdr, hs_start, pos - hs_start, 5521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = rhdr + rlen; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msgpos = pos; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_certificate_request(struct tlsv1_server *conn, 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *rhdr, *hs_start, *hs_length; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->verify_peer) { 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No CertificateRequest needed"); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = *msgpos; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 581818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send CertificateRequest"); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rhdr = pos; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RECORD_HEADER_LEN; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_start = pos; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length (to be filled) */ 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_length = pos; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - CertificateRequest */ 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * enum { 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4), 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (255) 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } ClientCertificateType; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ClientCertificateType certificate_types<1..2^8-1> 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 1; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 1; /* rsa_sign */ 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque DistinguishedName<1..2^16-1> 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * DistinguishedName certificate_authorities<3..2^16-1> 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for listing DNs for trusted CAs */ 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(pos, 0); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(hs_length, pos - hs_length - 3); 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 6171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rhdr, end - rhdr, hs_start, pos - hs_start, 6181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = rhdr + rlen; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msgpos = pos; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_hello_done(struct tlsv1_server *conn, 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *pos; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 6391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 payload[4]; 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 641818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send ServerHelloDone"); 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 6461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos = payload; 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE; 6491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* uint24 length */ 6501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_PUT_BE24(pos, 0); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ServerHelloDone (empty) */ 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 6551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos, end - *msgpos, payload, pos - payload, 6561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_verify_hash_add(&conn->verify, payload, pos - payload); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos += rlen; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_change_cipher_spec(struct tlsv1_server *conn, 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 6751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 payload[1]; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 677818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send ChangeCipherSpec"); 6781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt payload[0] = TLS_CHANGE_CIPHER_SPEC; 6801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC, 6821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos, end - *msgpos, payload, sizeof(payload), 6831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record"); 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_change_write_cipher(&conn->rl) < 0) { 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to set write cipher for " 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "record layer"); 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos += rlen; 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_finished(struct tlsv1_server *conn, 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *pos, *hs_start; 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen, hlen; 7091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 verify_data[1 + 3 + TLS_VERIFY_DATA_LEN]; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = *msgpos; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 714818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send Finished"); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Encrypted Handshake Message: Finished */ 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 7191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 7201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = SHA256_MAC_LEN; 7211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->verify.sha256_server == NULL || 7221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_finish(conn->verify.sha256_server, hash, &hlen) 7231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt < 0) { 7241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 7251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 7281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 7301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 7311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 7321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_server == NULL || 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) { 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, NULL, NULL); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_server == NULL || 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN, 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hlen) < 0) { 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 7541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = MD5_MAC_LEN + SHA1_MAC_LEN; 7551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 7571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf(conn->rl.tls_version, 7611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN, 7621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "server finished", hash, hlen, 7631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt verify_data + 1 + 3, TLS_VERIFY_DATA_LEN)) { 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data"); 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)", 7701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt verify_data + 1 + 3, TLS_VERIFY_DATA_LEN); 771818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 772818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->test_flags & TLS_BREAK_VERIFY_DATA) { 773818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "TESTING: Break verify_data (server)"); 774818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt verify_data[1 + 3 + 1] ^= 0x80; 775818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 776818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 7791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos = hs_start = verify_data; 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_FINISHED; 7821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* uint24 length */ 7831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_PUT_BE24(pos, TLS_VERIFY_DATA_LEN); 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_VERIFY_DATA_LEN; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 7891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos, end - *msgpos, hs_start, pos - hs_start, 7901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record"); 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos += rlen; 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * tls_send_server_hello(struct tlsv1_server *conn, size_t *out_len) 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msg, *end, *pos; 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t msglen; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = 0; 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msglen = 1000 + tls_server_cert_chain_der_len(conn); 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = os_malloc(msglen); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = msg; 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = msg + msglen; 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_write_server_hello(conn, &pos, end) < 0) { 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Abbreviated handshake using session ticket; RFC 4507 */ 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_write_server_change_cipher_spec(conn, &pos, end) < 0 || 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_finished(conn, &pos, end) < 0) { 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = pos - msg; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CHANGE_CIPHER_SPEC; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Full handshake */ 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_write_server_certificate(conn, &pos, end) < 0 || 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_key_exchange(conn, &pos, end) < 0 || 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_certificate_request(conn, &pos, end) < 0 || 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_hello_done(conn, &pos, end) < 0) { 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = pos - msg; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_CERTIFICATE; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * tls_send_change_cipher_spec(struct tlsv1_server *conn, 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *out_len) 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msg, *end, *pos; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = 0; 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = os_malloc(1000); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = msg; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = msg + 1000; 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_write_server_change_cipher_spec(conn, &pos, end) < 0 || 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_finished(conn, &pos, end) < 0) { 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = pos - msg; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Handshake completed successfully"); 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = ESTABLISHED; 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * tlsv1_server_handshake_write(struct tlsv1_server *conn, size_t *out_len) 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (conn->state) { 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_HELLO: 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_send_server_hello(conn, out_len); 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CHANGE_CIPHER_SPEC: 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_send_change_cipher_spec(conn, out_len); 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->state == ESTABLISHED && conn->use_session_ticket) { 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Abbreviated handshake was already completed. */ 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 897818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected state %d while generating reply", 898818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->state); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * tlsv1_server_send_alert(struct tlsv1_server *conn, u8 level, 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 description, size_t *out_len) 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *alert, *pos, *length; 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 909818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send Alert(%d:%d)", level, description); 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = 0; 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt alert = os_malloc(10); 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alert == NULL) 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = alert; 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TLSPlaintext */ 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ContentType type */ 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_CONTENT_TYPE_ALERT; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ProtocolVersion version */ 9221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_PUT_BE16(pos, conn->rl.tls_version ? conn->rl.tls_version : 9231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_VERSION); 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint16 length (to be filled) */ 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt length = pos; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Alert */ 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* AlertLevel level */ 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = level; 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* AlertDescription description */ 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = description; 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(length, pos - length - 2); 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = pos - alert; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return alert; 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 941