我正在开发一个 C++ 项目,该项目需要同时使用和提供 RESTful HTTPS Web 服务(这不是一个可爱的组合!)并选择了 POCO 库使其工作(为了许可证、平台支持和易于使用)使用/适应性原因我不会在这里讨论)。我是 POCO 和 OpenSSL 的新手,它用于提供 HTTPS 功能。
我遇到的问题是 SSLManager 和 Context 类(来自 POCO 的 NetSSL_OpenSSL 库)似乎只支持客户端或服务器上下文,但不能同时支持两者。我已经测试过一个简单的 HTTPS 客户端和服务器就是这种情况。所以我对 POCO 代码进行了一些挖掘,对于 SSLManager 的部分,服务器功能似乎是客户端功能的超集(所以我可以在它上面调用 initializeServer()
方法,它应该可以工作)。我似乎遇到麻烦的地方是 Context,它似乎作为 OpenSSL 上下文结构的包装器(请保持 Heartbleed 笑话!:))。
现在,经过更多的搜索,我遇到了 this page,它有一个漂亮的小表,它向我解释,OpenSSL 新手,我需要填写 SSL_METHOD 结构以创建 OpenSSL 上下文,这里有一些 OpenSSL 提供的 jar 头对于客户端、服务器和组合使用(对于那些遵循该链接的人,不,我没有做任何与 OpenVMS 相关的事情,我在 Windows 和 Linux 上就这个问题而言)。确实在 POCO Context createSSLContext()
方法中使用了表中的几个 SSL_METHODs,尽管不是用于组合客户端和服务器的那些。
我尝试修改 POCO 代码以添加“MIXED_USE”用法并适当更新上下文代码,从我的玩具示例来看,它似乎有效。这让我想到了我的问题。如果我沿着这条路线走,我是否遗漏了任何会或可能会导致我在路上出现问题的东西?除了明显的“好吧 POCO 还引用了这里的使用类型,你这个白痴”问题之外,我是否可能会因为基本上采用一组 OpenSSL(包装器)代码并简单地更改 SSL 上下文中的 SSL 方法而遇到任何不良影响我的网络服务?任何帮助/指针/想法表示赞赏。
TL;DR 版本:POCO HTTPS 库希望您使用客户端或服务器 OpenSSL 上下文,但我想调整它们并更改 SSL_METHOD 以支持组合的客户端和服务器 OpenSSL 上下文?我有多烂?
2014 年 4 月 24 日编辑:因此,为了回应 jww 的回答,让我稍微勾勒一下 Context 类。它基本上包装了一个指向 OpenSSL 上下文结构的指针,名为 _pSSLContext
。构造函数有一个 Usage
枚举参数(它设置一个成员 _usage
),它有几个可能的值。作为 Context 对象初始化的一部分,它调用一个名为 createSSLContext()
的内部方法,如下所示:
void Context::createSSLContext()
{
if (SSLManager::isFIPSEnabled())
{
_pSSLContext = SSL_CTX_new(TLSv1_method());
}
else
{
switch (_usage)
{
case CLIENT_USE:
_pSSLContext = SSL_CTX_new(SSLv23_client_method());
break;
case SERVER_USE:
_pSSLContext = SSL_CTX_new(SSLv23_server_method());
break;
case TLSV1_CLIENT_USE:
_pSSLContext = SSL_CTX_new(TLSv1_client_method());
break;
case TLSV1_SERVER_USE:
_pSSLContext = SSL_CTX_new(TLSv1_server_method());
break;
default:
throw Poco::InvalidArgumentException("Invalid usage");
}
}
if (!_pSSLContext)
{
unsigned long err = ERR_get_error();
throw SSLException("Cannot create SSL_CTX object", ERR_error_string(err, 0));
}
SSL_CTX_set_default_passwd_cb(_pSSLContext, &SSLManager::privateKeyPassphraseCallback);
Utility::clearErrorStack();
SSL_CTX_set_options(_pSSLContext, SSL_OP_ALL);
}
我想我应该能够向
Usage
枚举添加另一个值,这将导致上面的 switch 语句使调用初始化上下文,SSL_METHOD
为 SSLv23_method()
。我已经在一个玩具示例中对此进行了测试,它似乎有效。我的担忧导致了我的问题,即进行这样的更改可能会产生副作用。我对 POCO 或 OpenSSL 的了解还不够多,无法知道是否还需要其他杠杆才能使其发挥作用。例如,如果有关于
SSLv23_server/client_method()
的某些内容,其中只是在其位置插入 SSLv23_method()
而不更改其他地方的某些内容,则也可能会破坏某些内容(可能很巧妙)。 最佳答案
为了稍后回答我自己的问题,我能够编辑 POCO 代码以允许我指定“Both”上下文。那就是我更新了我最初发布的代码,如下所示:
void Context::createSSLContext()
{
if (SSLManager::isFIPSEnabled())
{
_pSSLContext = SSL_CTX_new(TLSv1_method());
}
else
{
switch (_usage)
{
case CLIENT_USE:
_pSSLContext = SSL_CTX_new(SSLv23_client_method());
break;
case SERVER_USE:
_pSSLContext = SSL_CTX_new(SSLv23_server_method());
break;
case BOTH_USE:
_pSSLContext = SSL_CTX_new(SSLv23_method());
break;
case TLSV1_CLIENT_USE:
_pSSLContext = SSL_CTX_new(TLSv1_client_method());
break;
case TLSV1_SERVER_USE:
_pSSLContext = SSL_CTX_new(TLSv1_server_method());
break;
case TLSV1_BOTH_USE:
_pSSLContext = SSL_CTX_new(TLSv1_method());
break;
default:
throw Poco::InvalidArgumentException("Invalid usage");
}
}
if (!_pSSLContext)
{
unsigned long err = ERR_get_error();
throw SSLException("Cannot create SSL_CTX object", ERR_error_string(err, 0));
}
SSL_CTX_set_default_passwd_cb(_pSSLContext, &SSLManager::privateKeyPassphraseCallback);
Utility::clearErrorStack();
SSL_CTX_set_options(_pSSLContext, SSL_OP_ALL);
}
像这样修改代码允许我的应用程序同时充当 HTTPS 服务器和客户端。如果有人在同一条船上,我希望这能让你放心。
关于c++ - HTTPS 客户端和服务器一起使用 C++ 和 POCO 库(SSL 上下文问题)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23257923/