- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试构建通过 Indy SSL TCP 组件 (C++ Builder 2010) 进行通信的服务器和客户端应用程序。我使用以下命令生成了证书和私钥:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -config C:\openssl.cnf
服务器代码:
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
#pragma argsused
#include <idglobal.hpp>
#include <IdTcpServer.hpp>
#include <IdSSLOpenSSL.hpp>
#include <vector>
#include <string>
#include <memory>
#include <iostream>
#include <windows.h>
#include "comm.h"
#pragma link "IndyCore140.lib"
#pragma link "IndyProtocols140.lib"
#pragma link "IndySystem140.lib"
/////////////////////////////////////////////////////////////////////////////
// Server
/////////////////////////////////////////////////////////////////////////////
class TServer
{
public:
TServer(int Port, const std::string& cert, const std::string& key,
const std::string& password )
: FPassword(password),
FServer(new TIdTCPServer(NULL))
{
FServer->OnConnect = ServerOnConnect;
FServer->OnExecute = ServerOnExecute;
FServer->DefaultPort = Port;
TIdServerIOHandlerSSLOpenSSL* ioHandler =
new TIdServerIOHandlerSSLOpenSSL(NULL);
ioHandler->OnGetPassword = SetPassword;
ioHandler->OnVerifyPeer = VerifyPeer;
ioHandler->SSLOptions->Mode = sslmServer;
ioHandler->SSLOptions->VerifyDepth = 0;
ioHandler->SSLOptions->CertFile = cert.c_str();
ioHandler->SSLOptions->KeyFile = key.c_str();
ioHandler->SSLOptions->SSLVersions << sslvSSLv23;
ioHandler->SSLOptions->VerifyMode.Clear();
FServer->IOHandler = ioHandler;
}
~TServer()
{
}
public:
void Start()
{
FServer->Active = true;
std::cout << "Listening on port " << FServer->DefaultPort << std::endl;
}
void Stop()
{
FServer->Active = false;
}
private:
void __fastcall ServerOnExecute(TIdContext* ctx)
{
TIdTCPConnection* conn = ctx->Connection;
try
{
std::string command = Recv(conn);
std::cout << command << std::endl;
if( strnicmp(command.c_str(), "HELLO", 5) == 0 ) // Start session
{
Send(conn, "HELLO");
}
}
catch(Exception& e)
{
std::cout << AnsiString(e.Message).c_str() << std::endl;
}
conn->Disconnect();
}
void __fastcall ServerOnConnect(TIdContext* context)
{
std::cout << "Client connected" << std::endl;
}
bool __fastcall VerifyPeer(TIdX509* Certificate, bool AOk, int ADepth)
{
return AOk;
}
void __fastcall SetPassword(AnsiString& Password)
{
Password = FPassword.c_str();
}
private:
std::auto_ptr<TIdTCPServer> FServer;
const std::string FPassword;
};
///
// Press Ctrl+C to close application
///
HANDLE hExitEvent = NULL;
BOOL CtrlHandler( DWORD ctl )
{
if( ctl == CTRL_C_EVENT)
{
if( hExitEvent != NULL )
{
std::cout << "Closing application..." << std::endl;
SetEvent(hExitEvent);
}
return TRUE;
}
return FALSE;
}
///
int _tmain(int argc, _TCHAR* argv[])
{
std::auto_ptr<TServer> server(new TServer(50136,
"c:\\cert.pem",
"c:\\key.pem",
"MyPassword"));
hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) )
{
try
{
server->Start();
WaitForSingleObject(hExitEvent, INFINITE);
server->Stop();
Sleep(1000);
}
catch(Exception& e)
{
std::cout << AnsiString(e.Message).c_str() << std::endl;
}
}
CloseHandle(hExitEvent);
return 0;
}
客户端代码:
#include <vcl.h>
#pragma hdrstop
#include <idglobal.hpp>
#include <IdTCPClient.hpp>
#include <IdSSLOpenSSL.hpp>
#include <vector>
#include <string>
#include <memory>
#include <iostream>
#include <tchar.h>
#include "comm.h"
//---------------------------------------------------------------------------
#pragma argsused
#pragma link "IndyCore140.lib"
#pragma link "IndyProtocols140.lib"
#pragma link "IndySystem140.lib"
void TestConnection()
{
std::auto_ptr<TIdTCPClient> client(new TIdTCPClient(NULL));
try
{
client->Host = "192.168.1.3";
client->Port = 50136;
client->ConnectTimeout = 10000;
client->ReadTimeout = 10000;
// SSL
TIdSSLIOHandlerSocketOpenSSL* ioHandler = new TIdSSLIOHandlerSocketOpenSSL(NULL);
ioHandler->SSLOptions->Mode = sslmClient;
ioHandler->SSLOptions->VerifyDepth = 0;
// ioHandler->SSLOptions->CertFile = "c:\\cert.pem";
ioHandler->SSLOptions->SSLVersions << sslvSSLv23;
// ioHandler->SSLOptions->VerifyMode.Clear();
client->IOHandler = ioHandler;
client->Connect();
///
// Test session start
///
Send(client.get(), "HELLO");
std::string response = Recv(client.get());
std::cout << response << std::endl;
}
catch(Exception& e)
{
std::cout << AnsiString(e.Message).c_str() << std::endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
TestConnection();
return 0;
}
comm.h
#ifndef COMM_H
#define COMM_H
#include <idglobal.hpp>
#include <IdTcpServer.hpp>
#include <IdSSLOpenSSL.hpp>
#include <vector>
#include <string>
//---------------------------------------------------------------------------
typedef std::vector<unsigned char> TBuffer;
void SendByteArray(TIdTCPConnection* Connection,
const TBuffer& array)
{
TIdBytes src;
src = Idglobal::RawToBytes(&array[0], array.size());
Connection->IOHandler->Write(src);
}
//---------------------------------------------------------------------------
void ReceiveByteArray(TIdTCPConnection* Connection,
TBuffer& array, unsigned int size)
{
TIdBytes dest;
Connection->IOHandler->ReadBytes(dest, size);
array.resize(size);
Idglobal::BytesToRaw(dest, &array[0], size);
}
void Send(TIdTCPConnection* Connection, const std::string& cmd)
{
TBuffer buffer(cmd.begin(), cmd.end());
SendByteArray(Connection, buffer);
}
std::string Recv(TIdTCPConnection* Connection)
{
TBuffer buffer;
ReceiveByteArray(Connection, buffer, 5);
std::string cmd(buffer.begin(), buffer.end());
return cmd;
}
#endif //COMM_H
服务器启动没有任何错误。当我尝试连接到服务器时,客户端抛出异常
Project sslclient.exe raised exception class EIdOSSLConnectError with message 'Error connecting with SSL.
EOF was observed that violates the protocol'.
并且服务器进入无限循环,并在每次迭代时出现异常 Connection Closed.
。我使用 OpenSSL 库 v.1.0.1.3 在 Windows 7 上运行测试。请帮助让它发挥作用。
最佳答案
客户端错误是因为当TIdServerIOHandlerSSLOpenSSL
接受一个新的客户端连接,PassThrough
客户端 IOHandler 的属性默认设置为 true,因此 SSL/TLS 尚未激活。这允许服务器在每个连接的基础上动态决定是否激活 SSL/TLS。例如,如果您的服务器正在监听多个端口并且仅在某些端口上使用 SSL。或者,如果您的协议(protocol)实现了 STARTTLS
样式命令。所以你需要设置 PassThrough
当您准备好接受 SSL/TLS 握手时属性设置为 false,例如:
void __fastcall ServerOnConnect(TIdContext* context)
{
std::cout << "Client connected" << std::endl;
static_cast<TIdSSLIOHandlerSocketOpenSSL*>(context->Connection->IOHandler)->PassThrough = false;
}
在客户端,设置PassThrough
当您准备好启动 SSL/TLS 握手时设置为 false:
ioHandler->PassThrough = false;
如果PassThrough
Connect()
时为假被调用时,一旦套接字成功连接到服务器,握手将立即执行。
话虽如此,Indy 依赖于异常,所以你不应该使用 try/catch
block 在 OnExecute
事件处理程序。您可以使用 OnException
记录未捕获异常的事件,例如:
void __fastcall ServerOnExecute(TIdContext* ctx)
{
TIdTCPConnection* conn = ctx->Connection;
std::string command = Recv(conn);
std::cout << command << std::endl;
if( strnicmp(command.c_str(), "HELLO", 5) == 0 ) // Start session
{
Send(conn, "HELLO");
}
conn->Disconnect();
}
void __fastcall ServerOnException(TIdContext* ctx, Exception *excpt)
{
std::cout << AnsiString(excpt->Message).c_str() << std::endl;
}
但是,如果您必须使用 try/catch
然后一定要重新抛出任何 EIdException
基于你捕获的异常。让TIdTCPServer
处理它们,例如:
void __fastcall ServerOnExecute(TIdContext* ctx)
{
TIdTCPConnection* conn = ctx->Connection;
try
{
std::string command = Recv(conn);
std::cout << command << std::endl;
if( strnicmp(command.c_str(), "HELLO", 5) == 0 ) // Start session
{
Send(conn, "HELLO");
}
}
catch(const Exception& e)
{
std::cout << AnsiString(e.Message).c_str() << std::endl;
if (dynamic_cast<const EIdException*>(&e))
throw;
}
conn->Disconnect();
}
或者:
void __fastcall ServerOnExecute(TIdContext* ctx)
{
TIdTCPConnection* conn = ctx->Connection;
try
{
std::string command = Recv(conn);
std::cout << command << std::endl;
if( strnicmp(command.c_str(), "HELLO", 5) == 0 ) // Start session
{
Send(conn, "HELLO");
}
}
catch(const EIdException&)
{
throw;
}
catch(const Exception& e)
{
std::cout << AnsiString(e.Message).c_str() << std::endl;
}
conn->Disconnect();
}
此外,这些行也是错误的:
ioHandler->SSLOptions->SSLVersions << sslvSSLv23;
ioHandler->SSLOptions->VerifyMode.Clear();
您不能使用 <<
属性上的运算符,并调用 Clear()
是一个空操作。原因是因为这两行都在调用属性 getter,然后操作之后未分配回属性的临时对象。您必须手动执行此操作:
ioHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvSSLv23;
ioHandler->SSLOptions->VerifyMode = TIdSSLVerifyModeSet();
最后:
#pragma link "IndyCore140.lib"
#pragma link "IndyProtocols140.lib"
#pragma link "IndySystem140.lib"
您不应该直接链接到 Indy 的 .lib 文件。您项目的 .bpr/.cproj 文件(而不是您的代码)应该包含对 Indy 运行时包的引用。
关于openssl - 无法连接到 Indy SSL TCP 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21768381/
如果我使用open ssl命令 sudo openssl genrsa -out privkey.pem 2048 要生成rsa key ,它仅生成1个文件。这是私钥。我如何获得公钥。 最佳答案 回答
三个不同版本的 openssl 正在同时更新 openssl.org : 0.98, 1.0.0, 1.0.1?它们之间有什么区别,我该如何选择要使用的版本? 最佳答案 https://en.wiki
我有以下命令用于 OpenSSL 生成私钥和公钥: openssl genrsa –aes-128-cbc –out priv.pem –passout pass:[privateKeyPass] 2
我正在尝试使用对应的 gcc (arm-none-eabi-5_4-2016q2) 为 cortex m3 机器交叉编译 openssl。机器应该有能力做 TCP 请求,我们希望在一天结束时做 HTT
我正在尝试使用 openssl dsa 实现,但我对以下细节感到非常困惑: 命令 openssl dsa .... 的选项“-text”:输出中的十六进制数字,我是否正确地假设这些是字节,因此它们是按
我正在尝试制作一个假 CA 并用它签署一个证书以与 stunnel 一起使用(这似乎只是调用 OpenSSL 例程,因此您可能不需要了解该程序来提供帮助:)。然而,stunnel 一直拒绝我的证书,说
不幸的是,Perl 在尝试安装 OpenSSL 的手册页(例如 OpenSSL_1_0_1g)时不知何故遇到了错误。因为我不需要它们 - 我只想使用 OpenSSL 作为 C 库,我想我可以通过完全跳
OpenSSL 中的 BIO 对到底是什么?它的用途是什么?我已经检查过 OpenSSL 文档,但任何细节都很少。 最佳答案 OpenSSL 中的 BIO 类似于文件句柄。您可以使用一对它们来安全地相
openssl ca 和 openssl x509 命令有什么区别?我正在使用它来创建和签署我的 root-ca、intermed-ca 和客户端证书,但是 openssl ca 命令不会在证书上注册
如何(如果有的话)为 OpenSSL 定义一个单一的可信证书文件在 Windows(Win-7,OpenSSL 1.0.1c)上使用 SSL_CERT_FILE 环境变量? 各种研究促使我下载了 Mo
我有一个自签名证书,其中显示了列出的基本约束,但从中生成的签名请求不显示这些属性,例如 [v3_req]。我怎样才能让它可见?我正在使用 openssl 生成证书。 场景: 我使用以下方法创建自签名证
这个问题在这里已经有了答案: Check if a connection is TLSv1 vs SSLv3 (SSL_CIPHER_description/SSL_CIPHER_get_name)
是否有更简单的方法来确定在构建 openssl 期间指定的选项,例如当时是否定义了 OPENSSL_NO_SRTP? 我只能从以下方面获得有限的信息: openssl 版本 -a 命令。但是,如果我只
我们正在与 AWS Nitro 合作,仅提供 3 小时的证书。 我们正在寻找一种可以跳过验证中的过期部分并仍然确认证书链有效的方法。 最佳答案 根据 openssl-verify 文档
嗨,我如何在 Easyphp 中启用 openssl,因为我收到错误消息无法发送。Mailer 错误:缺少扩展:opensslTime:使用 phpmailer 时。谢谢 最佳答案 在您的 php.i
我正在尝试以编程方式读取 OpenSSL 警报消息,但无法找到执行此操作的方法。 OpenSSL API 提供如下功能: const char *SSL_alert_type_string(int v
我跑了openssl speed在我的 Ubuntu 计算机上。一些结果: Doing md4 for 3s on 16 size blocks: 9063888 md4's in 3.00s Doi
我编译了带有cryptodev支持(即硬件加速)的OpenSSL,但不幸的是默认引擎仍然是软件。 time openssl speed -evp aes-128-cbc -engine cryptod
我需要从 RedHat Linux 服务器连接到 Microsoft Dynamics CRM 服务器。地址是xxx.api.crm4.dynamics.com。服务器接受 TLSv1 但不接受 1.
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 上个月关闭。 Improve thi
我是一名优秀的程序员,十分优秀!