Commit d52f8bae authored by jan.koester's avatar jan.koester
Browse files

test

parent 271004ae
Loading
Loading
Loading
Loading
+111 −157
Original line number Diff line number Diff line
@@ -1654,10 +1654,6 @@ void netplus::ssl::handshake_after_accept(){
            if (ch.size() < 4) throwSSL(NetException::Error, "ClientHello too short");
            if (ch[0] != 0x01) throwSSL(NetException::Error, "Expected ClientHello");

            // ✅ CRITICAL FIX: Save raw ClientHello bytes (including handshake header) for transcript hash
            // This must be done BEFORE parsing to preserve exact bytes for TLS 1.3 handshake verification
            _clientHelloRawBytes = ch;

            auto readU16 = [&](size_t& p) -> uint16_t {
                if (p + 2 > ch.size()) throwSSL(NetException::Error, "parse underrun u16");
                uint16_t x = (uint16_t(ch[p]) << 8) | ch[p+1];
@@ -2361,68 +2357,34 @@ void netplus::ssl::handshake_after_accept(){

        case HsState::TLS13_WAIT_CLIENT_FINISHED: {

            // Safety check: handshake keys must be initialized
            if (!_aes13_hs_recv) {
                NetException n;
                n[NetException::Note] << "TLS1.3: waiting for handshake keys to be initialized";
                throw n;
            }

            // ⚠️ Save transcript hash BEFORE fetching client Finished
            // The client computes its Finished over CH..server_Finished (not including client Finished)
            std::vector<uint8_t> th_before_client_finished = sha256_hash(_handshake_transcript);

            // ✅ Read ENCRYPTED handshake record (one at a time)
            // ✅ FIXED: Read ENCRYPTED handshake record (not plaintext!)
            // After ServerHello, all handshake messages are encrypted with handshake keys
            std::vector<uint8_t> msg = _tls13_read_record_handshake();
            if (msg.empty()) {
                // Need more data - throw Note so event loop waits
                // Must throw Note so event loop waits for more data
                NetException n;
                n[NetException::Note] << "TLS1.3: waiting for client Finished";
                throw n;
            }

            // Append to handshake buffer
            _rx_handshake_buf.insert(_rx_handshake_buf.end(), msg.begin(), msg.end());
            
            // Check if we have a complete Finished message (4-byte header + 32-byte body)
            if (_rx_handshake_buf.size() < 4) {
                // Incomplete header - need more data
                NetException n;
                n[NetException::Note] << "TLS1.3: incomplete Finished header";
                throw n;
            }
            
            uint32_t len = (uint32_t(_rx_handshake_buf[1]) << 16) | 
                           (uint32_t(_rx_handshake_buf[2]) <<  8) | 
                           (uint32_t(_rx_handshake_buf[3]) <<  0);
            
            if (_rx_handshake_buf.size() < 4 + len) {
                // Incomplete body - need more data
                NetException n;
                n[NetException::Note] << "TLS1.3: incomplete Finished body, have " 
                                       << _rx_handshake_buf.size() << " need " << (4 + len);
                throw n;
            }
            
            std::vector<uint8_t> finished_msg(_rx_handshake_buf.begin(),
                                              _rx_handshake_buf.begin() + 4 + len);
            _rx_handshake_buf.erase(_rx_handshake_buf.begin(),
                                    _rx_handshake_buf.begin() + 4 + len);

            // Validate message
            if (finished_msg.size() < 4)
            // msg enthält Handshake Msg (type+len24+body)
            if (msg.size() < 4)
                throwSSL(NetException::Error, "TLS1.3 client Finished too short");

            uint8_t ht = finished_msg[0];
            uint8_t ht = msg[0];
            uint32_t len = (uint32_t(msg[1]) << 16) | (uint32_t(msg[2]) << 8) | uint32_t(msg[3]);

            if (ht != 0x14)
                throwSSL(NetException::Error, "TLS1.3 expected Finished from client");

            if (len != 32 || finished_msg.size() != 4 + 32)
            if (len != 32 || msg.size() != 4 + 32)
                throwSSL(NetException::Error, "TLS1.3 Finished verify_data wrong size");

            std::vector<uint8_t> client_verify(finished_msg.begin() + 4, finished_msg.end());
            std::vector<uint8_t> client_verify(msg.begin() + 4, msg.end());

            // finished_key = HKDF-Expand-Label(c_hs_secret, "finished", "", 32)
            std::vector<uint8_t> finished_key = _hkdf_expand_label(
@@ -2460,22 +2422,19 @@ void netplus::ssl::handshake_after_accept(){
            // Calling it again here would use wrong transcript (includes client Finished).

            _handshakeDone = true;
            _hs_state = HsState::DONE;
            _hs_state = HsState::ESTABLISHED;
            return;
        }

        case HsState::TLS13_SEND_ENCRYPTED_FLIGHT: {

            if (!_tls13_encflight_queued) {
                _tls13_encflight_queued = true;  // Set flag FIRST to prevent re-entry if exception occurs

                if (!_aes13_hs_send || !_aes13_hs_recv)
                    throwSSL(NetException::Error, "TLS1.3 missing handshake keys");

                // 1) EncryptedExtensions (extensions = 2-byte length of 0 = 0x0000)
                std::vector<uint8_t> ee;
                ee.push_back(0x00);  // extensions length high byte
                ee.push_back(0x00);  // extensions length low byte (length = 0)
                // 1) EncryptedExtensions (body = extension list length = 0)
                std::vector<uint8_t> ee = {0x00, 0x00};
                _tls13_send_handshake(0x08, ee, true);

                // 2) Certificate
@@ -2493,6 +2452,8 @@ void netplus::ssl::handshake_after_accept(){

                // 5) Derive application keys AFTER transcript contains server Finished
                _tls13_derive_application_keys();

                _tls13_encflight_queued = true;
            }

            try {
@@ -2509,6 +2470,16 @@ void netplus::ssl::handshake_after_accept(){
            return;
        }

        case HsState::FAIL:{
            NetException e;
            e[NetException::Error] << "Handshake Failed";
            throw e;
        }

       case HsState::DONE:
            _handshakeDone = true;
            return;

        case HsState::TLS13_SEND_SERVER_HELLO: {

            // Reset per-handshake shared secrets
@@ -2605,16 +2576,6 @@ void netplus::ssl::handshake_after_accept(){
            continue;
        }

        case HsState::FAIL:{
            NetException e;
            e[NetException::Error] << "Handshake Failed";
            throw e;
        }

       case HsState::DONE:
            _handshakeDone = true;
            return;

        default:
            throwSSL(netplus::NetException::Error, "invalid handshake state");
        }
@@ -2897,13 +2858,6 @@ void netplus::ssl::_tls13_derive_handshake_keys(const std::vector<uint8_t>& ecdh
    if (th.size() != 32)
        throwSSL(NetException::Error, "TLS1.3: transcript hash wrong size");

    // ✅ DEBUG: Log transcript hash for verification
    std::cerr << "[TLS] _tls13_derive_handshake_keys: transcript size=" << _handshake_transcript.size() 
              << " hash(first 16 bytes): ";
    for (int i = 0; i < 16 && i < (int)th.size(); i++) 
        std::cerr << std::hex << std::setw(2) << std::setfill('0') << (int)th[i] << " ";
    std::cerr << std::dec << std::endl;

    std::vector<uint8_t> zeros(32, 0x00);

    // SHA-256 hash of empty string - needed for "derived" context per RFC 8446