我正在尝试为使用protobuf有效负载的客户端-服务器通信的传输层安全实现SSL。我查看了nanopb的network_server示例以及openssl / wolfssl C客户端示例(如https://aticleworld.com/ssl-server-client-using-openssl-in-c/和https://www.wolfssl.com/docs/quickstart/ )。然而,SSL库提供了像SSL_set_fd_ctx,SSL_connect,SSL_read,SSL_write这样的函数供套接字客户端代码使用。如何将SSL与使用pb_encode_delimited和pb_decode_delimited等函数进行发送和接收的nanopb network_server示例集成?感谢您的帮助。
发布于 2020-09-15 14:15:09
SSL_write和SSL_read是用于通过SSL传输数据的函数。在network_server示例中,examples/network_server/common.c中使用了libc send()和recv()。
您可以替换那里的函数,使nanopb直接写入SSL管道。或者,您可以始终从内存缓冲区进行编码和解码(如在examples/simple/simple.c中),然后分别发送和接收该内存缓冲区。
发布于 2020-09-16 21:35:25
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-client.c#L73-L119上查看客户机的自定义I/O回调,看看如何简单地替换使用文件系统的read()和write()调用,而使用pb_encode_delimited()和pb_decode_delimited()。
如果您对如何使用wolfSSL设置自定义I/O有任何后续问题,或者正在努力使用nanopb实现它,请随时向wolfSSL支持团队发送电子邮件,地址为:
“wolfssl .com上的支持”
谢谢!
发布于 2020-10-12 16:39:26
遵循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;
}从client main
//initialize WOLFSSL and associate socket fd
pb_ostream_t output = pb_ostream_from_ssl_socket(ssl); // WOLFSSL * ssl;它起作用了。感谢所有帮助我们的人
https://stackoverflow.com/questions/63889662
复制相似问题