我正在尝试使用 protobuf 有效负载为客户端-服务器通信的传输层安全性实现 SSL。我查看了 nanopb 的 network_server 示例以及 openssl / wolfssl C 示例客户端(例如https://aticleworld.com/ssl-server-client-using-openssl-in-c/ 和 https://www.wolfssl.com/文档/快速入门/ )。然而,SSL 库提供了 SSL_set_fd_ctx、SSL_connect、SSL_read、SSL_write 等函数,用于套接字客户端代码。如何将 SSL library 与 nanopb network_server 示例集成,该示例使用 pb_encode_delimited 和 pb_decode_delimited 等功能进行发送和接收?任何帮助表示赞赏。
3 回答
按照 jpa 的建议,在 common.c 中添加了 ssl 读写回调。
static bool ssl_write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count)
{
WOLFSSL * sslfd = (WOLFSSL *) stream->state;
int ret = wolfSSL_write(sslfd, buf, count);
return (ret == count) ; // true if success or false
}
pb_ostream_t pb_ostream_from_ssl_socket(WOLFSSL * ssl)
{
pb_ostream_t stream = {&ssl_write_callback, (void *) (WOLFSSL *)ssl, SIZE_MAX, 0};
return stream;
}
从客户端主
//initialize WOLFSSL and associate socket fd
pb_ostream_t output = pb_ostream_from_ssl_socket(ssl); // WOLFSSL * ssl;
这是工作。感谢所有帮助过的人
wolfSSL 支持自定义输入/输出 (I/O),并允许用户插入自己的回调以进行发送和接收。
这意味着 wolfSSL 与底层传输层无关。默认情况下,wolfSSL 假定 BSD 套接字和 TCP/IP 堆栈,但用户可以简单地编写自己的发送和接收函数并在设置期间注册它们以删除 TCP/IP 或 BSD 套接字默认依赖项。
下面我包含了一些关于如何设置自定义发送和接收的基本文档,我还包含了一个示例链接,其中我们使用同一台 PC 上的两个文件使用该文件在客户端和服务器之间交换 TLS 数据包系统作为传输层(无套接字、端口、TCP/IP 等!)
int myReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
{
// ssl = the current SSL object, cast to void if unused
// buf = the buffer to receive the message, always used
// sz = the size in bytes to receive, always used
// ctx = a custom user context, can be anything, a structure, char buf, variable, cast to the correct type and use as needed, cast to void if unused.
// RULE1: Only return the amount received.
// RULE2: In the case of a failed receive return one of the following errors as appropriate, returning 0 will
// trigger an automatic re-receive attempt without returning control to the calling application.
// WOLFSSL_CBIO_ERR_GENERAL = -1, /* general unexpected err */
// WOLFSSL_CBIO_ERR_WANT_READ = -2, /* need to call read again */
// WOLFSSL_CBIO_ERR_WANT_WRITE = -2, /* need to call write again */
// WOLFSSL_CBIO_ERR_CONN_RST = -3, /* connection reset */
// WOLFSSL_CBIO_ERR_ISR = -4, /* interrupt */
// WOLFSSL_CBIO_ERR_CONN_CLOSE = -5, /* connection closed or epipe */
// WOLFSSL_CBIO_ERR_TIMEOUT = -6 /* socket timeout */
// RULE3: In the case of a partial receive, only return the amount read, call wolfSSL_read again
// with the exact same parameters (including sz), the state machine will internally keep
// track of received vs remainder and will handle the remainder appropriately.
}
int mySend(WOLFSSL *ssl, char *buf, int sz, void *ctx)
{
// ssl = the current SSL object, cast to void if unused
// buf = the message to send, always used
// sz = the size in bytes to send, always used
// ctx = a custom user context, can be anything, a structure, char buf, variable, cast to the correct type and use as needed, cast to void if unused.
// RULE1: Only return the amount sent.
// RULE2: In the case of a failed send return one of the following errors as appropriate, returning 0 will
// trigger an automatic re-send attempt without returning control to the calling application.
// WOLFSSL_CBIO_ERR_GENERAL = -1, /* general unexpected err */
// WOLFSSL_CBIO_ERR_WANT_READ = -2, /* need to call read again */
// WOLFSSL_CBIO_ERR_WANT_WRITE = -2, /* need to call write again */
// WOLFSSL_CBIO_ERR_CONN_RST = -3, /* connection reset */
// WOLFSSL_CBIO_ERR_ISR = -4, /* interrupt */
// WOLFSSL_CBIO_ERR_CONN_CLOSE = -5, /* connection closed or epipe */
// WOLFSSL_CBIO_ERR_TIMEOUT = -6 /* socket timeout */
// RULE3: In the case of a partial send, only return the amount written, call wolfSSL_write again
// with the exact same parameters (including sz), the state machine will internally keep
// track of send vs remainder and will handle the remainder appropriately.
}
// Register your callbacks in place of the defaults:
wolfSSL_CTX_SetIORecv(ctx, mySend);
wolfSSL_CTX_SetIOSend(ctx, myReceive);
https://github.com/wolfSSL/wolfssl-examples/tree/master/custom-io-callbacks
我包含此链接的原因是您可以在https://github.com/wolfSSL/wolfssl-examples/blob/master/custom-io-callbacks/file-client/file查看客户端的自定义 I/O 回调-client.c#L73-L119并了解如何简单地将使用文件系统的 read() 和 write() 调用替换为使用 pb_encode_delimited() 和 pb_decode_delimited()。
如果您对如何使用 wolfSSL 设置自定义 I/O 有任何后续问题,或者正在努力使用 nanopb 实现它,请随时向 wolfSSL 支持团队发送电子邮件:
“支持 [at] wolfssl [dot] com”
谢谢!
- KH
SSL_write
并且SSL_read
是您用于通过 SSL 传输数据的功能。在network_server
示例中,libcsend()
和recv()
用于examples/network_server/common.c。
您可以替换那里的函数以使 nanopb 直接写入 SSL 管道。或者,您始终可以从内存缓冲区进行编码和解码(例如在examples/simple/simple.c 中),然后分别发送和接收该内存缓冲区。