Loading src/ssl.cpp +89 −88 Original line number Diff line number Diff line Loading @@ -445,7 +445,7 @@ namespace netplus { static inline std::string hexDump(const std::vector<uint8_t>& v, size_t max = 64) { std::ostringstream oss; size_t n = std::min(v.size(), max); size_t n = (std::min)(v.size(), max); for (size_t i = 0; i < n; ++i) { oss << std::hex << std::setw(2) << std::setfill('0') << int(v[i]); } Loading Loading @@ -1488,16 +1488,16 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) throw e; }; // ============================================================ // 0) TCP CONNECT // this = real IO socket // srvsock = config/target socket (host/port) // ============================================================ // ------------------------------------------------------------ // 0) Establish underlying TCP connection // ------------------------------------------------------------ // "this" is the real IO socket (the one the caller uses for send/recv). // srvsock holds the target config (addr/port/opts). tcp::connect(srvsock); // ============================================================ // 1) RESET TLS STATE (MUST RESET THIS OBJECT) // ============================================================ // ------------------------------------------------------------ // 1) Reset TLS state on THIS object // ------------------------------------------------------------ _send_seq = 0; _recv_seq = 0; _handshakeDone = false; Loading @@ -1514,20 +1514,21 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) _rx_netbuf.clear(); _rx_handshake_buffer.clear(); _recv_record.clear(); _recv_off = 0; _send_record.clear(); _send_off = 0; // ============================================================ // 2) HANDSHAKE REASSEMBLY HELPER // ============================================================ // ------------------------------------------------------------ // Helper: read & reassemble handshake messages // ------------------------------------------------------------ std::vector<uint8_t> hs_buf; auto readHandshakeMessage = [&]() -> std::vector<uint8_t> { for (;;) { auto readHandshakeMessage = [&]() -> std::vector<uint8_t> { for (;;) { if (hs_buf.size() >= 4) { uint32_t mlen = (uint32_t(hs_buf[1]) << 16) | Loading @@ -1538,7 +1539,7 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) std::vector<uint8_t> msg(hs_buf.begin(), hs_buf.begin() + 4 + mlen); hs_buf.erase(hs_buf.begin(), hs_buf.begin() + 4 + mlen); // transcript contains handshake messages only (type+len+body) // transcript contains handshake msg bytes only _handshake_transcript.insert(_handshake_transcript.end(), msg.begin(), msg.end()); return msg; Loading @@ -1546,31 +1547,34 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) } std::vector<uint8_t> rec = readTlsRecord(this); if (rec.size() < 5) throwSSL(netplus::NetException::Error, "TLS record too short"); if (rec.size() < 5) throwSSL(netplus::NetException::Error, "TLS record too short"); uint8_t ct = rec[0]; if (ct == 0x16) { // Handshake record // handshake record fragment hs_buf.insert(hs_buf.end(), rec.begin() + 5, rec.end()); continue; } if (ct == 0x14) { // CCS not in transcript // CCS not in transcript, just ignore here continue; } if (ct == 0x15) { throwSSL(netplus::NetException::Error, "TLS Alert during handshake"); } throwSSL(netplus::NetException::Error, "Unexpected TLS record type during handshake: " + std::to_string(int(ct))); "Unexpected TLS record during handshake type=" + std::to_string(int(ct))); } }; // ============================================================ // 3) SEND CLIENTHELLO // ============================================================ // ------------------------------------------------------------ // 2) Send ClientHello // ------------------------------------------------------------ { std::vector<uint8_t> ch; Loading @@ -1585,25 +1589,25 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) } ch.insert(ch.end(), _clientRandom.begin(), _clientRandom.end()); // session id length // session id len ch.push_back(0x00); // cipher suites (include SCSV + RSA AES128/256 SHA1) // cipher suites: SCSV + AES128-SHA + AES256-SHA std::vector<uint8_t> suites = { 0x00, 0xFF, // renegotiation SCSV 0x00, 0x2F, // TLS_RSA_WITH_AES_128_CBC_SHA 0x00, 0x35 // TLS_RSA_WITH_AES_256_CBC_SHA 0x00, 0xFF, 0x00, 0x2F, 0x00, 0x35 }; ch.push_back(uint8_t((suites.size() >> 8) & 0xFF)); ch.push_back(uint8_t(suites.size() & 0xFF)); ch.insert(ch.end(), suites.begin(), suites.end()); // compression: null // compression null ch.push_back(0x01); ch.push_back(0x00); // extensions: renegotiation_info // extension renegotiation_info (RFC 5746) { std::vector<uint8_t> exts; exts.push_back(0xFF); exts.push_back(0x01); Loading @@ -1618,9 +1622,9 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) _sendHandshake(0x01, ch, this); } // ============================================================ // 4) READ SERVERHELLO // ============================================================ // ------------------------------------------------------------ // 3) Read ServerHello // ------------------------------------------------------------ std::vector<uint8_t> sh = readHandshakeMessage(); if (sh.empty() || sh[0] != 0x02) throwSSL(netplus::NetException::Error, "Expected ServerHello"); Loading @@ -1628,12 +1632,11 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) if (sh.size() < 4 + 2 + 32 + 1) throwSSL(netplus::NetException::Error, "ServerHello too short"); _serverRandom.assign(sh.begin() + 4 + 2, sh.begin() + 4 + 2 + 32); _serverRandom.assign(sh.begin() + 4 + 2, sh.begin() + 4 + 2 + 32); // ============================================================ // 5) READ CERTIFICATE (LEAF) // ============================================================ // ------------------------------------------------------------ // 4) Read Certificate // ------------------------------------------------------------ std::vector<uint8_t> certMsg = readHandshakeMessage(); if (certMsg.empty() || certMsg[0] != 0x0b) throwSSL(netplus::NetException::Error, "Expected Certificate"); Loading @@ -1649,7 +1652,7 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) p += 3; if (p + listLen > certMsg.size()) throwSSL(netplus::NetException::Error, "Malformed certificate list"); throwSSL(netplus::NetException::Error, "Malformed certificate_list"); uint32_t cLen = (uint32_t(certMsg[p]) << 16) | Loading @@ -1666,36 +1669,36 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) serverCert.loadFromBuffer(rawCert); _peer_cert = serverCert; // ============================================================ // 6) READ UNTIL SERVERHELLODONE // ============================================================ // ------------------------------------------------------------ // 5) Read until ServerHelloDone // ------------------------------------------------------------ for (;;) { std::vector<uint8_t> msg = readHandshakeMessage(); if (msg.empty()) throwSSL(netplus::NetException::Error, "Empty handshake message"); if (msg.empty()) throwSSL(netplus::NetException::Error, "Unexpected empty handshake msg"); uint8_t t = msg[0]; if (t == 0x0e) break; // ServerHelloDone if (t == 0x0c) throwSSL(netplus::NetException::Error, "ServerKeyExchange received: server requires (EC)DHE; RSA not supported"); "ServerKeyExchange received: server uses (EC)DHE; RSA only client"); if (t == 0x0d) throwSSL(netplus::NetException::Error, "CertificateRequest received: client auth not supported"); throwSSL(netplus::NetException::Error, "Unexpected handshake msg type: " + std::to_string(int(t))); "Unexpected handshake msg type=" + std::to_string(int(t))); } // ============================================================ // 7) CLIENTKEYEXCHANGE (RSA PKCS#1 v1.5) // ============================================================ // ------------------------------------------------------------ // 6) ClientKeyExchange (RSA) // ------------------------------------------------------------ netplus::rsa serverPubKey; serverCert.extractPublicKey(serverPubKey); std::vector<uint8_t> preMaster(48); preMaster[0] = 0x03; preMaster[1] = 0x03; preMaster[0] = 0x03; preMaster[1] = 0x03; // TLS 1.2 { std::random_device rd; for (size_t i = 2; i < preMaster.size(); ++i) Loading @@ -1706,10 +1709,8 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) if (kBytes < 11 + preMaster.size()) throwSSL(netplus::NetException::Error, "server RSA key too small"); // PKCS#1 v1.5: 0x00 0x02 PS 0x00 PMS std::vector<uint8_t> em(kBytes, 0x00); em[0] = 0x00; em[1] = 0x02; em[0] = 0x00; em[1] = 0x02; { std::random_device rd; Loading @@ -1734,11 +1735,10 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) _sendHandshake(0x10, cke, this); // ============================================================ // 8) KEY DERIVATION (TLS_RSA_WITH_AES_128_CBC_SHA) // ============================================================ // ------------------------------------------------------------ // 7) Key Derivation // ------------------------------------------------------------ std::vector<uint8_t> masterSecret; { std::vector<uint8_t> seed = _clientRandom; seed.insert(seed.end(), _serverRandom.begin(), _serverRandom.end()); Loading @@ -1758,24 +1758,26 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) _aes_recv = std::make_unique<aes>(serverKey); } if (!_aes || !_aes_recv) throwSSL(netplus::NetException::Error, "AES contexts not initialized"); // ============================================================ // 9) SEND CHANGE CIPHER SPEC (raw) // ============================================================ // ------------------------------------------------------------ // 8) Send ChangeCipherSpec (portable send) // ------------------------------------------------------------ { static const uint8_t ccs[6] = { 0x14, 0x03, 0x03, 0x00, 0x01, 0x01 }; ssize_t w = ::send(fd(), ccs, sizeof(ccs), MSG_NOSIGNAL); if (w != (ssize_t)sizeof(ccs)) #ifdef _WIN32 int w = ::send((SOCKET)fd(), (const char*)ccs, (int)sizeof(ccs), 0); #else int w = (int)::send(fd(), ccs, sizeof(ccs), MSG_NOSIGNAL); #endif if (w != (int)sizeof(ccs)) throwSSL(netplus::NetException::Error, "CCS send failed"); _send_seq = 0; } // ============================================================ // 10) SEND FINISHED (encrypted handshake record) // ============================================================ // ------------------------------------------------------------ // 9) Send Finished (encrypted) // ------------------------------------------------------------ { std::vector<uint8_t> th = _sha256_hash(_handshake_transcript); std::vector<uint8_t> verify = _prf(masterSecret, "client finished", th, 12); Loading @@ -1783,18 +1785,19 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) std::vector<uint8_t> fin = { 0x14, 0x00, 0x00, 0x0c }; fin.insert(fin.end(), verify.begin(), verify.end()); // Finished is a handshake message: add to transcript BEFORE verifying server finished // Finished is part of transcript BEFORE verifying server finished _handshake_transcript.insert(_handshake_transcript.end(), fin.begin(), fin.end()); _sendEncryptedRecord(this, 0x16, fin); } // ============================================================ // 11) RECEIVE SERVER CCS // ============================================================ // ------------------------------------------------------------ // 10) Wait for Server CCS // ------------------------------------------------------------ for (;;) { std::vector<uint8_t> rec = readTlsRecord(this); if (rec.empty()) throwSSL(netplus::NetException::Error, "EOF waiting for server CCS"); if (rec.empty()) throwSSL(netplus::NetException::Error, "EOF waiting server CCS"); if (rec[0] == 0x14) { if (rec.size() < 6 || rec[5] != 0x01) Loading @@ -1802,13 +1805,14 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) break; } if (rec[0] == 0x15) throwSSL(netplus::NetException::Error, "Alert while waiting for server CCS"); throwSSL(netplus::NetException::Error, "Server Alert waiting CCS"); } _recv_seq = 0; // ============================================================ // 12) RECEIVE + VERIFY SERVER FINISHED // ============================================================ // ------------------------------------------------------------ // 11) Receive + verify Server Finished // ------------------------------------------------------------ { std::vector<uint8_t> sfinRec = readTlsRecord(this); if (sfinRec.size() < 5 || sfinRec[0] != 0x16) Loading @@ -1829,9 +1833,6 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) throwSSL(netplus::NetException::Error, "Server Finished verify_data mismatch"); } // ============================================================ // 13) DONE // ============================================================ _handshakeDone = true; } Loading Loading @@ -2936,7 +2937,7 @@ bool netplus::ssl::handshakeStepIOCP() std::vector<uint8_t> frag(rec.begin() + 5, rec.end()); // Your decrypt increments _recv_seq after verifying MAC std::vector<uint8_t> finPT = _decryptRecordCBC(this, 0x16, 0x0303, frag); std::vector<uint8_t> finPT = _decryptRecordCBC(0x16, 0x0303, frag); // Structure: 0x14 00 00 0C + 12 bytes if (finPT.size() != 4 + 12 || finPT[0] != 0x14 || finPT[1] != 0x00 || finPT[2] != 0x00 || finPT[3] != 0x0c) { Loading Loading
src/ssl.cpp +89 −88 Original line number Diff line number Diff line Loading @@ -445,7 +445,7 @@ namespace netplus { static inline std::string hexDump(const std::vector<uint8_t>& v, size_t max = 64) { std::ostringstream oss; size_t n = std::min(v.size(), max); size_t n = (std::min)(v.size(), max); for (size_t i = 0; i < n; ++i) { oss << std::hex << std::setw(2) << std::setfill('0') << int(v[i]); } Loading Loading @@ -1488,16 +1488,16 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) throw e; }; // ============================================================ // 0) TCP CONNECT // this = real IO socket // srvsock = config/target socket (host/port) // ============================================================ // ------------------------------------------------------------ // 0) Establish underlying TCP connection // ------------------------------------------------------------ // "this" is the real IO socket (the one the caller uses for send/recv). // srvsock holds the target config (addr/port/opts). tcp::connect(srvsock); // ============================================================ // 1) RESET TLS STATE (MUST RESET THIS OBJECT) // ============================================================ // ------------------------------------------------------------ // 1) Reset TLS state on THIS object // ------------------------------------------------------------ _send_seq = 0; _recv_seq = 0; _handshakeDone = false; Loading @@ -1514,20 +1514,21 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) _rx_netbuf.clear(); _rx_handshake_buffer.clear(); _recv_record.clear(); _recv_off = 0; _send_record.clear(); _send_off = 0; // ============================================================ // 2) HANDSHAKE REASSEMBLY HELPER // ============================================================ // ------------------------------------------------------------ // Helper: read & reassemble handshake messages // ------------------------------------------------------------ std::vector<uint8_t> hs_buf; auto readHandshakeMessage = [&]() -> std::vector<uint8_t> { for (;;) { auto readHandshakeMessage = [&]() -> std::vector<uint8_t> { for (;;) { if (hs_buf.size() >= 4) { uint32_t mlen = (uint32_t(hs_buf[1]) << 16) | Loading @@ -1538,7 +1539,7 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) std::vector<uint8_t> msg(hs_buf.begin(), hs_buf.begin() + 4 + mlen); hs_buf.erase(hs_buf.begin(), hs_buf.begin() + 4 + mlen); // transcript contains handshake messages only (type+len+body) // transcript contains handshake msg bytes only _handshake_transcript.insert(_handshake_transcript.end(), msg.begin(), msg.end()); return msg; Loading @@ -1546,31 +1547,34 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) } std::vector<uint8_t> rec = readTlsRecord(this); if (rec.size() < 5) throwSSL(netplus::NetException::Error, "TLS record too short"); if (rec.size() < 5) throwSSL(netplus::NetException::Error, "TLS record too short"); uint8_t ct = rec[0]; if (ct == 0x16) { // Handshake record // handshake record fragment hs_buf.insert(hs_buf.end(), rec.begin() + 5, rec.end()); continue; } if (ct == 0x14) { // CCS not in transcript // CCS not in transcript, just ignore here continue; } if (ct == 0x15) { throwSSL(netplus::NetException::Error, "TLS Alert during handshake"); } throwSSL(netplus::NetException::Error, "Unexpected TLS record type during handshake: " + std::to_string(int(ct))); "Unexpected TLS record during handshake type=" + std::to_string(int(ct))); } }; // ============================================================ // 3) SEND CLIENTHELLO // ============================================================ // ------------------------------------------------------------ // 2) Send ClientHello // ------------------------------------------------------------ { std::vector<uint8_t> ch; Loading @@ -1585,25 +1589,25 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) } ch.insert(ch.end(), _clientRandom.begin(), _clientRandom.end()); // session id length // session id len ch.push_back(0x00); // cipher suites (include SCSV + RSA AES128/256 SHA1) // cipher suites: SCSV + AES128-SHA + AES256-SHA std::vector<uint8_t> suites = { 0x00, 0xFF, // renegotiation SCSV 0x00, 0x2F, // TLS_RSA_WITH_AES_128_CBC_SHA 0x00, 0x35 // TLS_RSA_WITH_AES_256_CBC_SHA 0x00, 0xFF, 0x00, 0x2F, 0x00, 0x35 }; ch.push_back(uint8_t((suites.size() >> 8) & 0xFF)); ch.push_back(uint8_t(suites.size() & 0xFF)); ch.insert(ch.end(), suites.begin(), suites.end()); // compression: null // compression null ch.push_back(0x01); ch.push_back(0x00); // extensions: renegotiation_info // extension renegotiation_info (RFC 5746) { std::vector<uint8_t> exts; exts.push_back(0xFF); exts.push_back(0x01); Loading @@ -1618,9 +1622,9 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) _sendHandshake(0x01, ch, this); } // ============================================================ // 4) READ SERVERHELLO // ============================================================ // ------------------------------------------------------------ // 3) Read ServerHello // ------------------------------------------------------------ std::vector<uint8_t> sh = readHandshakeMessage(); if (sh.empty() || sh[0] != 0x02) throwSSL(netplus::NetException::Error, "Expected ServerHello"); Loading @@ -1628,12 +1632,11 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) if (sh.size() < 4 + 2 + 32 + 1) throwSSL(netplus::NetException::Error, "ServerHello too short"); _serverRandom.assign(sh.begin() + 4 + 2, sh.begin() + 4 + 2 + 32); _serverRandom.assign(sh.begin() + 4 + 2, sh.begin() + 4 + 2 + 32); // ============================================================ // 5) READ CERTIFICATE (LEAF) // ============================================================ // ------------------------------------------------------------ // 4) Read Certificate // ------------------------------------------------------------ std::vector<uint8_t> certMsg = readHandshakeMessage(); if (certMsg.empty() || certMsg[0] != 0x0b) throwSSL(netplus::NetException::Error, "Expected Certificate"); Loading @@ -1649,7 +1652,7 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) p += 3; if (p + listLen > certMsg.size()) throwSSL(netplus::NetException::Error, "Malformed certificate list"); throwSSL(netplus::NetException::Error, "Malformed certificate_list"); uint32_t cLen = (uint32_t(certMsg[p]) << 16) | Loading @@ -1666,36 +1669,36 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) serverCert.loadFromBuffer(rawCert); _peer_cert = serverCert; // ============================================================ // 6) READ UNTIL SERVERHELLODONE // ============================================================ // ------------------------------------------------------------ // 5) Read until ServerHelloDone // ------------------------------------------------------------ for (;;) { std::vector<uint8_t> msg = readHandshakeMessage(); if (msg.empty()) throwSSL(netplus::NetException::Error, "Empty handshake message"); if (msg.empty()) throwSSL(netplus::NetException::Error, "Unexpected empty handshake msg"); uint8_t t = msg[0]; if (t == 0x0e) break; // ServerHelloDone if (t == 0x0c) throwSSL(netplus::NetException::Error, "ServerKeyExchange received: server requires (EC)DHE; RSA not supported"); "ServerKeyExchange received: server uses (EC)DHE; RSA only client"); if (t == 0x0d) throwSSL(netplus::NetException::Error, "CertificateRequest received: client auth not supported"); throwSSL(netplus::NetException::Error, "Unexpected handshake msg type: " + std::to_string(int(t))); "Unexpected handshake msg type=" + std::to_string(int(t))); } // ============================================================ // 7) CLIENTKEYEXCHANGE (RSA PKCS#1 v1.5) // ============================================================ // ------------------------------------------------------------ // 6) ClientKeyExchange (RSA) // ------------------------------------------------------------ netplus::rsa serverPubKey; serverCert.extractPublicKey(serverPubKey); std::vector<uint8_t> preMaster(48); preMaster[0] = 0x03; preMaster[1] = 0x03; preMaster[0] = 0x03; preMaster[1] = 0x03; // TLS 1.2 { std::random_device rd; for (size_t i = 2; i < preMaster.size(); ++i) Loading @@ -1706,10 +1709,8 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) if (kBytes < 11 + preMaster.size()) throwSSL(netplus::NetException::Error, "server RSA key too small"); // PKCS#1 v1.5: 0x00 0x02 PS 0x00 PMS std::vector<uint8_t> em(kBytes, 0x00); em[0] = 0x00; em[1] = 0x02; em[0] = 0x00; em[1] = 0x02; { std::random_device rd; Loading @@ -1734,11 +1735,10 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) _sendHandshake(0x10, cke, this); // ============================================================ // 8) KEY DERIVATION (TLS_RSA_WITH_AES_128_CBC_SHA) // ============================================================ // ------------------------------------------------------------ // 7) Key Derivation // ------------------------------------------------------------ std::vector<uint8_t> masterSecret; { std::vector<uint8_t> seed = _clientRandom; seed.insert(seed.end(), _serverRandom.begin(), _serverRandom.end()); Loading @@ -1758,24 +1758,26 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) _aes_recv = std::make_unique<aes>(serverKey); } if (!_aes || !_aes_recv) throwSSL(netplus::NetException::Error, "AES contexts not initialized"); // ============================================================ // 9) SEND CHANGE CIPHER SPEC (raw) // ============================================================ // ------------------------------------------------------------ // 8) Send ChangeCipherSpec (portable send) // ------------------------------------------------------------ { static const uint8_t ccs[6] = { 0x14, 0x03, 0x03, 0x00, 0x01, 0x01 }; ssize_t w = ::send(fd(), ccs, sizeof(ccs), MSG_NOSIGNAL); if (w != (ssize_t)sizeof(ccs)) #ifdef _WIN32 int w = ::send((SOCKET)fd(), (const char*)ccs, (int)sizeof(ccs), 0); #else int w = (int)::send(fd(), ccs, sizeof(ccs), MSG_NOSIGNAL); #endif if (w != (int)sizeof(ccs)) throwSSL(netplus::NetException::Error, "CCS send failed"); _send_seq = 0; } // ============================================================ // 10) SEND FINISHED (encrypted handshake record) // ============================================================ // ------------------------------------------------------------ // 9) Send Finished (encrypted) // ------------------------------------------------------------ { std::vector<uint8_t> th = _sha256_hash(_handshake_transcript); std::vector<uint8_t> verify = _prf(masterSecret, "client finished", th, 12); Loading @@ -1783,18 +1785,19 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) std::vector<uint8_t> fin = { 0x14, 0x00, 0x00, 0x0c }; fin.insert(fin.end(), verify.begin(), verify.end()); // Finished is a handshake message: add to transcript BEFORE verifying server finished // Finished is part of transcript BEFORE verifying server finished _handshake_transcript.insert(_handshake_transcript.end(), fin.begin(), fin.end()); _sendEncryptedRecord(this, 0x16, fin); } // ============================================================ // 11) RECEIVE SERVER CCS // ============================================================ // ------------------------------------------------------------ // 10) Wait for Server CCS // ------------------------------------------------------------ for (;;) { std::vector<uint8_t> rec = readTlsRecord(this); if (rec.empty()) throwSSL(netplus::NetException::Error, "EOF waiting for server CCS"); if (rec.empty()) throwSSL(netplus::NetException::Error, "EOF waiting server CCS"); if (rec[0] == 0x14) { if (rec.size() < 6 || rec[5] != 0x01) Loading @@ -1802,13 +1805,14 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) break; } if (rec[0] == 0x15) throwSSL(netplus::NetException::Error, "Alert while waiting for server CCS"); throwSSL(netplus::NetException::Error, "Server Alert waiting CCS"); } _recv_seq = 0; // ============================================================ // 12) RECEIVE + VERIFY SERVER FINISHED // ============================================================ // ------------------------------------------------------------ // 11) Receive + verify Server Finished // ------------------------------------------------------------ { std::vector<uint8_t> sfinRec = readTlsRecord(this); if (sfinRec.size() < 5 || sfinRec[0] != 0x16) Loading @@ -1829,9 +1833,6 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) throwSSL(netplus::NetException::Error, "Server Finished verify_data mismatch"); } // ============================================================ // 13) DONE // ============================================================ _handshakeDone = true; } Loading Loading @@ -2936,7 +2937,7 @@ bool netplus::ssl::handshakeStepIOCP() std::vector<uint8_t> frag(rec.begin() + 5, rec.end()); // Your decrypt increments _recv_seq after verifying MAC std::vector<uint8_t> finPT = _decryptRecordCBC(this, 0x16, 0x0303, frag); std::vector<uint8_t> finPT = _decryptRecordCBC(0x16, 0x0303, frag); // Structure: 0x14 00 00 0C + 12 bytes if (finPT.size() != 4 + 12 || finPT[0] != 0x14 || finPT[1] != 0x00 || finPT[2] != 0x00 || finPT[3] != 0x0c) { Loading