#include "pch.h" #include "SSLClientConnection.h" namespace SSLClient { SSLClientConnection::SSLClientConnection() : m_sslContext(nullptr) , m_ssl(nullptr) , m_socket(INVALID_SOCKET) , m_isConnected(false) { } SSLClientConnection::~SSLClientConnection() { Cleanup(); } bool SSLClientConnection::InitializeWinsock() { WSADATA wsaData; int result = WSAStartup(MAKEWORD(2, 2), &wsaData); if (result != 0) { std::cerr << "[错误] WSAStartup失败,错误码: " << result << std::endl; return false; } return true; } bool SSLClientConnection::Initialize(const char* clientCert, const char* clientKey, const char* caCert, const char* keyPassword) { // 初始化Winsock if (!InitializeWinsock()) { return false; } std::cout << "[客户端] 正在初始化SSL环境..." << std::endl; // 创建SSL上下文 m_sslContext = SSL_CTX_new(TLS_client_method()); if (!m_sslContext) { CertificateManager::PrintSSLError("创建SSL上下文失败"); return false; } // 设置验证模式:验证服务器证书 SSL_CTX_set_verify(m_sslContext, SSL_VERIFY_PEER, nullptr); // 加载CA证书 X509* ca = m_certManager.LoadCertificateFromMemory(caCert); if (!ca) { return false; } X509_STORE* store = SSL_CTX_get_cert_store(m_sslContext); if (X509_STORE_add_cert(store, ca) != 1) { CertificateManager::PrintSSLError("添加CA证书失败"); X509_free(ca); return false; } X509_free(ca); // 加载客户端证书 X509* cert = m_certManager.LoadCertificateFromMemory(clientCert); if (!cert) { return false; } if (SSL_CTX_use_certificate(m_sslContext, cert) != 1) { CertificateManager::PrintSSLError("使用客户端证书失败"); X509_free(cert); return false; } X509_free(cert); // 加载客户端私钥 EVP_PKEY* pkey = m_certManager.LoadPrivateKeyFromMemory(clientKey, keyPassword); if (!pkey) { return false; } if (SSL_CTX_use_PrivateKey(m_sslContext, pkey) != 1) { CertificateManager::PrintSSLError("使用客户端私钥失败"); EVP_PKEY_free(pkey); return false; } EVP_PKEY_free(pkey); // 验证私钥和证书是否匹配 if (SSL_CTX_check_private_key(m_sslContext) != 1) { std::cerr << "[错误] 客户端私钥和证书不匹配" << std::endl; return false; } std::cout << "[客户端] SSL环境初始化成功" << std::endl; return true; } bool SSLClientConnection::Connect(const char* address, int port) { // 创建socket m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_socket == INVALID_SOCKET) { std::cerr << "[错误] 创建socket失败,错误码: " << WSAGetLastError() << std::endl; return false; } // 设置服务器地址 sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(static_cast(port)); inet_pton(AF_INET, address, &serverAddr.sin_addr); // 连接到服务器 std::cout << "[客户端] 正在连接服务器 " << address << ":" << port << " ..." << std::endl; if (connect(m_socket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { std::cerr << "[错误] 连接失败,错误码: " << WSAGetLastError() << std::endl; closesocket(m_socket); m_socket = INVALID_SOCKET; return false; } std::cout << "[客户端] TCP连接成功" << std::endl; // 创建SSL对象 m_ssl = SSL_new(m_sslContext); if (!m_ssl) { CertificateManager::PrintSSLError("创建SSL对象失败"); closesocket(m_socket); m_socket = INVALID_SOCKET; return false; } // 将SSL绑定到socket if (SSL_set_fd(m_ssl, static_cast(m_socket)) != 1) { CertificateManager::PrintSSLError("绑定SSL到socket失败"); SSL_free(m_ssl); m_ssl = nullptr; closesocket(m_socket); m_socket = INVALID_SOCKET; return false; } // 执行SSL握手 std::cout << "[客户端] 正在进行SSL握手..." << std::endl; int ret = SSL_connect(m_ssl); if (ret != 1) { int err = SSL_get_error(m_ssl, ret); std::cerr << "[错误] SSL握手失败,错误码: " << err << std::endl; CertificateManager::PrintSSLError("SSL_connect"); SSL_free(m_ssl); m_ssl = nullptr; closesocket(m_socket); m_socket = INVALID_SOCKET; return false; } m_isConnected = true; std::cout << "[客户端] SSL握手完成!" << std::endl; std::cout << "[客户端] 使用的加密套件: " << GetCipherSuite() << std::endl; return true; } bool SSLClientConnection::Send(const std::string& data) { if (!m_isConnected || !m_ssl) { std::cerr << "[错误] 未连接到服务器" << std::endl; return false; } int sent = SSL_write(m_ssl, data.c_str(), static_cast(data.length())); if (sent <= 0) { int err = SSL_get_error(m_ssl, sent); std::cerr << "[错误] 发送失败,错误码: " << err << std::endl; CertificateManager::PrintSSLError("SSL_write"); return false; } std::cout << "[客户端] 发送数据: \"" << data << "\" (" << sent << " 字节)" << std::endl; return true; } int SSLClientConnection::Receive(char* buffer, int bufferSize) { if (!m_isConnected || !m_ssl || !buffer || bufferSize <= 0) { return -1; } // 设置socket为非阻塞模式 u_long mode = 1; ioctlsocket(m_socket, FIONBIO, &mode); int received = SSL_read(m_ssl, buffer, bufferSize - 1); // 恢复为阻塞模式 mode = 0; ioctlsocket(m_socket, FIONBIO, &mode); if (received > 0) { buffer[received] = '\0'; std::cout << "[客户端] 收到数据: \"" << buffer << "\" (" << received << " 字节)" << std::endl; return received; } else if (received < 0) { int err = SSL_get_error(m_ssl, received); // SSL_ERROR_WANT_READ 和 SSL_ERROR_WANT_WRITE 表示没有数据,不是错误 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { if (err != SSL_ERROR_ZERO_RETURN) { // 忽略正常关闭 std::cerr << "[错误] 接收失败,错误码: " << err << std::endl; } return -1; } } return 0; // 没有数据 } void SSLClientConnection::Disconnect() { std::cout << "[客户端] 正在断开连接..." << std::endl; Cleanup(); m_isConnected = false; std::cout << "[客户端] 已断开连接" << std::endl; } const char* SSLClientConnection::GetCipherSuite() const { if (m_ssl) { return SSL_get_cipher(m_ssl); } return "未知"; } void SSLClientConnection::Cleanup() { if (m_ssl) { SSL_shutdown(m_ssl); SSL_free(m_ssl); m_ssl = nullptr; } if (m_socket != INVALID_SOCKET) { closesocket(m_socket); m_socket = INVALID_SOCKET; } if (m_sslContext) { SSL_CTX_free(m_sslContext); m_sslContext = nullptr; } WSACleanup(); } } // namespace SSLClient