【问题标题】:Client returns -1 on BIO_do_connect客户端在 BIO_do_connect 上返回 -1
【发布时间】:2016-09-09 10:37:37
【问题描述】:

我正在尝试使用 OpenSSL 及其 BIO 创建基本服务器和客户端,但 BIO_do_connect 返回 -1。 ERR_get_error 之后返回 0。 我试图通过编写 // check [condition] 来最小化下面的代码。在我的真实代码中,我用 if 检查做同样的事情,然后我打印出 ERR_get_error 返回的错误。 (所以如果条件为真,我将打印错误消息)

这是我的服务器代码:

// init OpenSSL
SSL_load_error_strings();
ERR_load_BIO_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();

SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
SSL_CTX_set_default_passwd_cb(ctx, &myPasswordCallback);

int certState = SSL_CTX_use_certificate_file(ctx, "../certs/cert.pem", SSL_FILETYPE_PEM);
// check certState < 0

int keyState = SSL_CTX_use_PrivateKey_file(ctx, "../certs/key.pem", SSL_FILETYPE_PEM);
// check keyState < 0

BIO *serverBio = BIO_new_ssl(ctx, 0);
// check serverBio == nullptr

SSL *serverSsl = nullptr;
BIO_get_ssl(serverBio, &serverSsl);
// check serverSsl == nullptr

SSL_set_mode(serverSsl, SSL_MODE_AUTO_RETRY);

BIO *acceptBio = BIO_new_accept("6672");
// check acceptBio == nullptr

int setupAcceptResult = BIO_do_accept(acceptBio);
// check setupAcceptResult <= 0

int acceptResult = BIO_do_accept(acceptBio);
// check acceptResult <= 0

BIO *clientBio = BIO_pop(acceptBio);
// check clientBio == nullptr

BIO_free_all(clientBio);

BIO_free_all(acceptBio);
BIO_free_all(serverBio);

// cleanup OpenSSL
SSL_CTX_free(ctx);
EVP_cleanup();
ERR_free_strings();

此服务器运行良好,但我的客户端无法连接到它:

// init OpenSSL
SSL_load_error_strings();
ERR_load_BIO_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();

SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
SSL_CTX_set_default_passwd_cb(ctx, &myPasswordCallback);

int certState = SSL_CTX_use_certificate_file(ctx, "../certs/cert.pem", SSL_FILETYPE_PEM);
// check certState < 0

int keyState = SSL_CTX_use_PrivateKey_file(ctx, "../certs/key.pem", SSL_FILETYPE_PEM);
// check keyState < 0

BIO *clientBio = BIO_new_ssl_connect(ctx);
SSL *clientSsl = nullptr;
BIO_get_ssl(clientBio, &clientSsl);
// check clientSsl == nullptr

SSL_set_mode(clientSsl, SSL_MODE_AUTO_RETRY);

BIO_set_conn_hostname(clientBio, "localhost:6672");

long connectionState = BIO_do_connect(clientBio);
// check connectionState <= 0
// here it fails; connectionState is -1

long sslState = SSL_get_verify_result(clientSsl);
// check sslState != X509_V_OK

BIO_free_all(clientBio);

SSL_CTX_free(ctx);

EVP_cleanup();
ERR_free_strings();

很抱歉发布了这么多代码。我并没有真正找到使用 BIO 的 OpenSSL 服务器/客户端的完整示例。

【问题讨论】:

标签: c++ c sockets ssl openssl


【解决方案1】:

你的服务器代码本质上是这样的:

  1. 将 serverBio 设置为 SSL
  2. 创建一个没有 SSL 的新 BIO acceptBio
  3. 接受连接连接->clientBio
  4. 释放一切

服务器没有在此处进行任何 SSL 握手,因为 serverBio 没有用于新创建的 TCP 连接 clientBio。

除此之外,我建议您首先针对已知良好的客户端和服务器测试您的服务器和客户端,以便您可以更快地找出问题所在。 openssl s_clientopenssl s_server 提供这样的测试客户端和服务器。数据包捕获(wireshark)也有助于找出服务器和客户端之间发生的事情。

【讨论】:

  • 感谢您的回答!所以我必须第三次做 BIO_do_handshake 吗?因为我已经调用了两次(BIO_do_accept 被定义为 BIO_do_handshake)。
  • 我试过了,但它没有完成,s_client 只是连接,但它没有从我的服务器获取任何证书。
  • @User9182736455:BIO_do_accept 未定义为 BIO_do_handshake。您在服务器中仅使用 TCP BIO。没有使用 BIO_set_ssl 或基于 BIO_s_accept 或类似方法创建 BIO 的关联。
  • @User9182736455:我建议您从 工作 示例代码(只是 google)开始,然后根据需要对其进行调整,而不是尝试从头开始做所有事情。 OpenSSL 不是一个易于使用的库。
  • 谢谢,我会试试的
猜你喜欢
  • 2018-11-18
  • 1970-01-01
  • 2020-09-13
  • 2021-11-22
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
  • 2020-08-27
  • 1970-01-01
相关资源
最近更新 更多