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{ 45d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt u8 *pos, *rhdr, *hs_start, *hs_length, *ext_start; 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 100d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* Extension */ 101d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt ext_start = pos; 102d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += 2; 103d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 104d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (conn->status_request) { 105d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* Add a status_request extension with empty extension_data */ 106d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* ExtensionsType extension_type = status_request(5) */ 107d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt WPA_PUT_BE16(pos, TLS_EXT_STATUS_REQUEST); 108d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += 2; 109d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* opaque extension_data<0..2^16-1> length */ 110d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt WPA_PUT_BE16(pos, 0); 111d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += 2; 112d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 113d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 114d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (conn->status_request_v2) { 115d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* 116d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt Add a status_request_v2 extension with empty extension_data 117d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt */ 118d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* ExtensionsType extension_type = status_request_v2(17) */ 119d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt WPA_PUT_BE16(pos, TLS_EXT_STATUS_REQUEST_V2); 120d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += 2; 121d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* opaque extension_data<0..2^16-1> length */ 122d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt WPA_PUT_BE16(pos, 0); 123d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += 2; 124d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 125d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket && conn->session_ticket_cb) { 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = conn->session_ticket_cb( 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx, 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket, conn->session_ticket_len, 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_random, conn->server_random, 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->master_secret); 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 133818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "SessionTicket callback indicated failure"); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_HANDSHAKE_FAILURE); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->use_session_ticket = res; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_server_derive_keys(conn, NULL, 0) < 0) { 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to " 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "derive keys"); 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4507 specifies that server would include an empty 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SessionTicket extension in ServerHello and a 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NewSessionTicket message after the ServerHello. However, 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-FAST (RFC 4851), i.e., the only user of SessionTicket 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * extension at the moment, does not use such extensions. 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: Add support for configuring RFC 4507 behavior and make 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-FAST disable it. 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 162d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (pos == ext_start + 2) 163d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos -= 2; /* no extensions */ 164d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt else 165d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt WPA_PUT_BE16(ext_start, pos - ext_start - 2); 166d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(hs_length, pos - hs_length - 3); 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rhdr, end - rhdr, hs_start, pos - hs_start, 1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record"); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = rhdr + rlen; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msgpos = pos; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_certificate(struct tlsv1_server *conn, 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *rhdr, *hs_start, *hs_length, *cert_start; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct x509_certificate *cert; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) { 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Do not send Certificate when " 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "using anonymous DH"); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = *msgpos; 202d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (TLS_RECORD_HEADER_LEN + 1 + 3 + 3 > end - pos) { 203d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 204d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 205d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 206d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send Certificate"); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rhdr = pos; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RECORD_HEADER_LEN; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_start = pos; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length (to be filled) */ 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_length = pos; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - Certificate */ 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length (to be filled) */ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert_start = pos; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = conn->cred->cert; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (cert) { 227d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (3 + cert->cert_len > (size_t) (end - pos)) { 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space " 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for Certificate (cert_len=%lu left=%lu)", 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) cert->cert_len, 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(pos, cert->cert_len); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, cert->cert_start, cert->cert_len); 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += cert->cert_len; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509_certificate_self_signed(cert)) 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = x509_certificate_get_subject(conn->cred->trusted_certs, 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &cert->issuer); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == conn->cred->cert || cert == NULL) { 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Server was not configured with all the needed certificates 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to form a full certificate chain. The client may fail to 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * validate the chain unless it is configured with all the 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * missing CA certificates. 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Full server certificate chain " 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not configured - validation may fail"); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(cert_start, pos - cert_start - 3); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(hs_length, pos - hs_length - 3); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 2611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rhdr, end - rhdr, hs_start, pos - hs_start, 2621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = rhdr + rlen; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msgpos = pos; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidtstatic int tls_write_server_certificate_status(struct tlsv1_server *conn, 279d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt u8 **msgpos, u8 *end, 280d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt int ocsp_multi, 281d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt char *ocsp_resp, 282d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt size_t ocsp_resp_len) 283d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt{ 284d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt u8 *pos, *rhdr, *hs_start, *hs_length; 285d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt size_t rlen; 286d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 287d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (!ocsp_resp) { 288d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* 289d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * Client did not request certificate status or there is no 290d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * matching response cached. 291d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt */ 292d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return 0; 293d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 294d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 295d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos = *msgpos; 296d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (TLS_RECORD_HEADER_LEN + 1 + 3 + 1 + 3 + ocsp_resp_len > 297d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt (unsigned int) (end - pos)) { 298d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 299d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 300d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return -1; 301d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 302d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 303d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt tlsv1_server_log(conn, "Send CertificateStatus (multi=%d)", ocsp_multi); 304d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt rhdr = pos; 305d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += TLS_RECORD_HEADER_LEN; 306d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 307d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 308d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 309d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* Handshake */ 310d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt hs_start = pos; 311d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* HandshakeType msg_type */ 312d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE_STATUS; 313d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* uint24 length (to be filled) */ 314d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt hs_length = pos; 315d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += 3; 316d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 317d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* body - CertificateStatus 318d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * 319d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * struct { 320d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * CertificateStatusType status_type; 321d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * select (status_type) { 322d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * case ocsp: OCSPResponse; 323d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * case ocsp_multi: OCSPResponseList; 324d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * } response; 325d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * } CertificateStatus; 326d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * 327d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * opaque OCSPResponse<1..2^24-1>; 328d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * 329d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * struct { 330d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * OCSPResponse ocsp_response_list<1..2^24-1>; 331d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * } OCSPResponseList; 332d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt */ 333d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 334d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* CertificateStatusType status_type */ 335d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (ocsp_multi) 336d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt *pos++ = 2; /* ocsp_multi(2) */ 337d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt else 338d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt *pos++ = 1; /* ocsp(1) */ 339d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* uint24 length of OCSPResponse */ 340d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt WPA_PUT_BE24(pos, ocsp_resp_len); 341d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += 3; 342d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_memcpy(pos, ocsp_resp, ocsp_resp_len); 343d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += ocsp_resp_len; 344d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 345d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt WPA_PUT_BE24(hs_length, pos - hs_length - 3); 346d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 347d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 348d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt rhdr, end - rhdr, hs_start, pos - hs_start, 349d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt &rlen) < 0) { 350d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 351d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 352d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 353d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return -1; 354d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 355d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos = rhdr + rlen; 356d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 357d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 358d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 359d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt *msgpos = pos; 360d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 361d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return 0; 362d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt} 363d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 364d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_key_exchange(struct tlsv1_server *conn, 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_key_exchange keyx; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 370818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 *pos, *rhdr, *hs_start, *hs_length, *server_params; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *dh_ys; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t dh_ys_len; 374b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt const u8 *dh_p; 375b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t dh_p_len; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite == NULL) 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = TLS_KEY_X_NULL; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = suite->key_exchange; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) { 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No ServerKeyExchange needed"); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (keyx != TLS_KEY_X_DH_anon && keyx != TLS_KEY_X_DHE_RSA) { 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not yet " 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "supported with key exchange type %d", keyx); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cred == NULL || conn->cred->dh_p == NULL || 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cred->dh_g == NULL) { 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available for " 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerKeyExhcange"); 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 401b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tlsv1_server_get_dh_p(conn, &dh_p, &dh_p_len); 402b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->dh_secret); 404b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt conn->dh_secret_len = dh_p_len; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret = os_malloc(conn->dh_secret_len); 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_secret == NULL) { 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate " 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "memory for secret (Diffie-Hellman)"); 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(conn->dh_secret, conn->dh_secret_len)) { 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random " 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data for Diffie-Hellman"); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->dh_secret); 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret = NULL; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 423b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (os_memcmp(conn->dh_secret, dh_p, conn->dh_secret_len) > 0) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret[0] = 0; /* make sure secret < p */ 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = conn->dh_secret; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < conn->dh_secret + conn->dh_secret_len && *pos == 0) 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos != conn->dh_secret) { 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memmove(conn->dh_secret, pos, 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret_len - (pos - conn->dh_secret)); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret_len -= pos - conn->dh_secret; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: DH server's secret value", 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret, conn->dh_secret_len); 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ys = g^secret mod p */ 438b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt dh_ys_len = dh_p_len; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_ys = os_malloc(dh_ys_len); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_ys == NULL) { 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate memory for " 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Diffie-Hellman"); 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_mod_exp(conn->cred->dh_g, conn->cred->dh_g_len, 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret, conn->dh_secret_len, 449b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt dh_p, dh_p_len, dh_ys, &dh_ys_len)) { 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)", 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_ys, dh_ys_len); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * select (KeyExchangeAlgorithm) { 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case diffie_hellman: 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ServerDHParams params; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Signature signed_params; 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case rsa: 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ServerRSAParams params; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Signature signed_params; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * }; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } ServerKeyExchange; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque dh_p<1..2^16-1>; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque dh_g<1..2^16-1>; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque dh_Ys<1..2^16-1>; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } ServerDHParams; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = *msgpos; 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 480818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send ServerKeyExchange"); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rhdr = pos; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RECORD_HEADER_LEN; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_start = pos; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length (to be filled) */ 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_length = pos; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ServerDHParams */ 495818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params = pos; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dh_p */ 497d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (2 + dh_p_len > (size_t) (end - pos)) { 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for " 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_p"); 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 505b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt WPA_PUT_BE16(pos, dh_p_len); 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 507b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt os_memcpy(pos, dh_p, dh_p_len); 508b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt pos += dh_p_len; 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dh_g */ 511d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (2 + conn->cred->dh_g_len > (size_t) (end - pos)) { 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for " 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_g"); 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(pos, conn->cred->dh_g_len); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, conn->cred->dh_g, conn->cred->dh_g_len); 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->cred->dh_g_len; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dh_Ys */ 525d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (2 + dh_ys_len > (size_t) (end - pos)) { 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for " 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_Ys"); 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(pos, dh_ys_len); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, dh_ys, dh_ys_len); 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += dh_ys_len; 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dh_ys); 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 539818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 540818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * select (SignatureAlgorithm) 541818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * { case anonymous: struct { }; 542818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * case rsa: 543818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * digitally-signed struct { 544818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * opaque md5_hash[16]; 545818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * opaque sha_hash[20]; 546818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * }; 547818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * case dsa: 548818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * digitally-signed struct { 549818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * opaque sha_hash[20]; 550818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * }; 551818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * } Signature; 552818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 553818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * md5_hash 554818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * MD5(ClientHello.random + ServerHello.random + ServerParams); 555818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 556818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * sha_hash 557818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * SHA(ClientHello.random + ServerHello.random + ServerParams); 558818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 559818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 560818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (keyx == TLS_KEY_X_DHE_RSA) { 561818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 hash[100]; 562818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 *signed_start; 563818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt size_t clen; 564818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt int hlen; 565818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 566818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 567818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TLSV12 568818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen = tlsv12_key_x_server_params_hash( 569d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt conn->rl.tls_version, TLS_HASH_ALG_SHA256, 570d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt conn->client_random, 571818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_random, server_params, 572818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos - server_params, hash + 19); 573818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 574818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 575818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * RFC 5246, 4.7: 576818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * TLS v1.2 adds explicit indication of the used 577818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * signature and hash algorithms. 578818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 579818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * struct { 580818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * HashAlgorithm hash; 581818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * SignatureAlgorithm signature; 582818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * } SignatureAndHashAlgorithm; 583818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 584d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (hlen < 0 || end - pos < 2) { 585818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 586818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 587818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return -1; 588818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 589818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt *pos++ = TLS_HASH_ALG_SHA256; 590818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt *pos++ = TLS_SIGN_ALG_RSA; 591818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 592818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 593818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * RFC 3447, A.2.4 RSASSA-PKCS1-v1_5 594818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 595818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * DigestInfo ::= SEQUENCE { 596818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * digestAlgorithm DigestAlgorithm, 597818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * digest OCTET STRING 598818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * } 599818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 600818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * SHA-256 OID: sha256WithRSAEncryption ::= {pkcs-1 11} 601818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 602818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * DER encoded DigestInfo for SHA256 per RFC 3447: 603818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 604818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 04 20 || H 605818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 606818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen += 19; 607818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_memcpy(hash, 608818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65" 609818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "\x03\x04\x02\x01\x05\x00\x04\x20", 19); 610818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 611818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#else /* CONFIG_TLSV12 */ 612818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 613818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 614818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return -1; 615818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TLSV12 */ 616818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } else { 617818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen = tls_key_x_server_params_hash( 618818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->rl.tls_version, conn->client_random, 619818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_random, server_params, 620818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos - server_params, hash); 621818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 622818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 623818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (hlen < 0) { 624818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 625818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 626818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return -1; 627818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 628818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 629818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLS: ServerKeyExchange signed_params hash", 630818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hash, hlen); 631818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 632818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->test_flags & TLS_BREAK_SRV_KEY_X_HASH) { 633818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "TESTING: Break ServerKeyExchange signed params hash"); 634818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hash[hlen - 1] ^= 0x80; 635818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 636818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 637818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 638818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 639818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * RFC 2246, 4.7: 640818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * In digital signing, one-way hash functions are used as input 641818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * for a signing algorithm. A digitally-signed element is 642818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * encoded as an opaque vector <0..2^16-1>, where the length is 643818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * specified by the signing algorithm and key. 644818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 645818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * In RSA signing, a 36-byte structure of two hashes (one SHA 646818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * and one MD5) is signed (encrypted with the private key). It 647818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * is encoded with PKCS #1 block type 0 or type 1 as described 648818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * in [PKCS1]. 649818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 650818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt signed_start = pos; /* length to be filled */ 651818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos += 2; 652818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt clen = end - pos; 653818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->cred == NULL || 654818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt crypto_private_key_sign_pkcs1(conn->cred->key, hash, hlen, 655818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos, &clen) < 0) { 656818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to sign hash (PKCS #1)"); 657818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 658818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 659818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return -1; 660818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 661818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt WPA_PUT_BE16(signed_start, clen); 662818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 663818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->test_flags & TLS_BREAK_SRV_KEY_X_SIGNATURE) { 664818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "TESTING: Break ServerKeyExchange signed params signature"); 665818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos[clen - 1] ^= 0x80; 666818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 667818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 668818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 669818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos += clen; 670818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 671818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(hs_length, pos - hs_length - 3); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 6751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rhdr, end - rhdr, hs_start, pos - hs_start, 6761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = rhdr + rlen; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msgpos = pos; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_certificate_request(struct tlsv1_server *conn, 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *rhdr, *hs_start, *hs_length; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->verify_peer) { 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No CertificateRequest needed"); 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = *msgpos; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 705818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send CertificateRequest"); 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rhdr = pos; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RECORD_HEADER_LEN; 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_start = pos; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length (to be filled) */ 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hs_length = pos; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - CertificateRequest */ 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * enum { 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4), 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (255) 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } ClientCertificateType; 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ClientCertificateType certificate_types<1..2^8-1> 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 1; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 1; /* rsa_sign */ 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque DistinguishedName<1..2^16-1> 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * DistinguishedName certificate_authorities<3..2^16-1> 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for listing DNs for trusted CAs */ 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(pos, 0); 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(hs_length, pos - hs_length - 3); 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 7411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rhdr, end - rhdr, hs_start, pos - hs_start, 7421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = rhdr + rlen; 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msgpos = pos; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_hello_done(struct tlsv1_server *conn, 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *pos; 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 7631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 payload[4]; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 765818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send ServerHelloDone"); 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 7701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos = payload; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE; 7731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* uint24 length */ 7741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_PUT_BE24(pos, 0); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ServerHelloDone (empty) */ 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 7791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos, end - *msgpos, payload, pos - payload, 7801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record"); 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_verify_hash_add(&conn->verify, payload, pos - payload); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos += rlen; 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_change_cipher_spec(struct tlsv1_server *conn, 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 7991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 payload[1]; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 801818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send ChangeCipherSpec"); 8021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt payload[0] = TLS_CHANGE_CIPHER_SPEC; 8041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC, 8061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos, end - *msgpos, payload, sizeof(payload), 8071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record"); 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_change_write_cipher(&conn->rl) < 0) { 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to set write cipher for " 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "record layer"); 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos += rlen; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_write_server_finished(struct tlsv1_server *conn, 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **msgpos, u8 *end) 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *pos, *hs_start; 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen, hlen; 8331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 verify_data[1 + 3 + TLS_VERIFY_DATA_LEN]; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = *msgpos; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send Finished"); 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Encrypted Handshake Message: Finished */ 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 8431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 8441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = SHA256_MAC_LEN; 8451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->verify.sha256_server == NULL || 8461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_finish(conn->verify.sha256_server, hash, &hlen) 8471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt < 0) { 8481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 8491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 8521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 8541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 8551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 8561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_server == NULL || 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) { 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, NULL, NULL); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_server == NULL || 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN, 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hlen) < 0) { 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 8781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = MD5_MAC_LEN + SHA1_MAC_LEN; 8791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 8811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf(conn->rl.tls_version, 8851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN, 8861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "server finished", hash, hlen, 8871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt verify_data + 1 + 3, TLS_VERIFY_DATA_LEN)) { 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data"); 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)", 8941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt verify_data + 1 + 3, TLS_VERIFY_DATA_LEN); 895818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 896818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->test_flags & TLS_BREAK_VERIFY_DATA) { 897818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "TESTING: Break verify_data (server)"); 898818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt verify_data[1 + 3 + 1] ^= 0x80; 899818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 900818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Handshake */ 9031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos = hs_start = verify_data; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_HANDSHAKE_TYPE_FINISHED; 9061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* uint24 length */ 9071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_PUT_BE24(pos, TLS_VERIFY_DATA_LEN); 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_VERIFY_DATA_LEN; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, 9131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos, end - *msgpos, hs_start, pos - hs_start, 9141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &rlen) < 0) { 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record"); 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *msgpos += rlen; 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * tls_send_server_hello(struct tlsv1_server *conn, size_t *out_len) 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msg, *end, *pos; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t msglen; 931d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt int ocsp_multi = 0; 932d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt char *ocsp_resp = NULL; 933d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt size_t ocsp_resp_len = 0; 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = 0; 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 937d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (conn->status_request_multi && 938d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt conn->cred->ocsp_stapling_response_multi) { 939d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt ocsp_resp = os_readfile( 940d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt conn->cred->ocsp_stapling_response_multi, 941d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt &ocsp_resp_len); 942d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt ocsp_multi = 1; 943d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } else if ((conn->status_request || conn->status_request_v2) && 944d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt conn->cred->ocsp_stapling_response) { 945d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt ocsp_resp = os_readfile(conn->cred->ocsp_stapling_response, 946d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt &ocsp_resp_len); 947d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 948d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (!ocsp_resp) 949d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt ocsp_resp_len = 0; 950d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 951d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt msglen = 1000 + tls_server_cert_chain_der_len(conn) + ocsp_resp_len; 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = os_malloc(msglen); 954d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (msg == NULL) { 955d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_free(ocsp_resp); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 957d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = msg; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = msg + msglen; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_write_server_hello(conn, &pos, end) < 0) { 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 964d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_free(ocsp_resp); 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 969d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_free(ocsp_resp); 970d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Abbreviated handshake using session ticket; RFC 4507 */ 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_write_server_change_cipher_spec(conn, &pos, end) < 0 || 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_finished(conn, &pos, end) < 0) { 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = pos - msg; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CHANGE_CIPHER_SPEC; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Full handshake */ 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_write_server_certificate(conn, &pos, end) < 0 || 987d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt tls_write_server_certificate_status(conn, &pos, end, ocsp_multi, 988d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt ocsp_resp, ocsp_resp_len) < 0 || 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_key_exchange(conn, &pos, end) < 0 || 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_certificate_request(conn, &pos, end) < 0 || 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_hello_done(conn, &pos, end) < 0) { 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 993d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_free(ocsp_resp); 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 996d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_free(ocsp_resp); 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = pos - msg; 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_CERTIFICATE; 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * tls_send_change_cipher_spec(struct tlsv1_server *conn, 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *out_len) 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msg, *end, *pos; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = 0; 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = os_malloc(1000); 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = msg; 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = msg + 1000; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_write_server_change_cipher_spec(conn, &pos, end) < 0 || 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_write_server_finished(conn, &pos, end) < 0) { 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = pos - msg; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Handshake completed successfully"); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = ESTABLISHED; 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * tlsv1_server_handshake_write(struct tlsv1_server *conn, size_t *out_len) 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (conn->state) { 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_HELLO: 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_send_server_hello(conn, out_len); 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CHANGE_CIPHER_SPEC: 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_send_change_cipher_spec(conn, out_len); 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->state == ESTABLISHED && conn->use_session_ticket) { 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Abbreviated handshake was already completed. */ 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1047818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected state %d while generating reply", 1048818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->state); 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * tlsv1_server_send_alert(struct tlsv1_server *conn, u8 level, 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 description, size_t *out_len) 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *alert, *pos, *length; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1059818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Send Alert(%d:%d)", level, description); 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = 0; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt alert = os_malloc(10); 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alert == NULL) 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = alert; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TLSPlaintext */ 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ContentType type */ 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = TLS_CONTENT_TYPE_ALERT; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ProtocolVersion version */ 10721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_PUT_BE16(pos, conn->rl.tls_version ? conn->rl.tls_version : 10731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_VERSION); 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint16 length (to be filled) */ 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt length = pos; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* opaque fragment[TLSPlaintext.length] */ 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Alert */ 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* AlertLevel level */ 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = level; 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* AlertDescription description */ 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = description; 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(length, pos - length - 2); 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = pos - alert; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return alert; 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1091