首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用nanopb over SSL的客户端服务器

使用nanopb over SSL的客户端服务器
EN

Stack Overflow用户
提问于 2020-09-15 02:09:08
回答 3查看 129关注 0票数 0

我正在尝试为使用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示例集成?感谢您的帮助。

EN

回答 3

Stack Overflow用户

发布于 2020-09-15 14:15:09

SSL_writeSSL_read是用于通过SSL传输数据的函数。在network_server示例中,examples/network_server/common.c中使用了libc send()recv()

您可以替换那里的函数,使nanopb直接写入SSL管道。或者,您可以始终从内存缓冲区进行编码和解码(如在examples/simple/simple.c中),然后分别发送和接收该内存缓冲区。

票数 0
EN

Stack Overflow用户

发布于 2020-09-16 21:35:25

wolfSSL支持自定义输入/输出(I/O),并允许用户插入自己的回调来发送和接收。

这意味着wolfSSL对底层传输层是不可知的。默认情况下,wolfSSL采用BSD套接字和TCP/IP堆栈,但是用户可以简单地编写自己的发送和接收函数,并在安装过程中注册它们,以删除TCP/IP或BSD套接字默认依赖项。

下面我已经包含了一些关于如何设置自定义发送和接收的基本文档,还包含了一个指向一个示例的链接,在这个示例中,我们使用同一台PC上的两个文件在使用文件系统作为传输层的客户端和服务器之间交换TLS数据包(没有套接字、端口、TCP/IP等!)

代码语言:javascript
复制
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上的支持”

谢谢!

  • KH
票数 0
EN

Stack Overflow用户

发布于 2020-10-12 16:39:26

遵循jpa的建议,在common.c中添加了ssl读写回调。

代码语言:javascript
复制
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

代码语言:javascript
复制
//initialize WOLFSSL and associate socket fd
pb_ostream_t output = pb_ostream_from_ssl_socket(ssl); // WOLFSSL * ssl;

它起作用了。感谢所有帮助我们的人

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63889662

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档