将字节直接写入OpenSSL Connection,不使用TCP

Ser*_* A. 5 c ssl openssl radius

我正在实现支持EAP(PEAP)身份验证的RADIUS服务器.RADIUS依赖于UDP,每个数据包将包含带有身份验证数据的EAP消息.为简化起见,每个EAP(PEAP)消息都包含TLS数据包,因此客户端将首先发送包含服务器将处理的TLS客户端握手的EAP数据包,然后返回TLS服务器握手,依此类推以下包.

我已经能够通过TCP实现一个简单的TLS服务器,但我需要的是直接在SSL连接中写入TLS字节.

SSLConn_init_thread();
SSL_load_error_strings();
ERR_load_crypto_strings();
SSL_library_init();

SSL_CTX *ctx;
...
ctx = SSL_CTX_new(SSLv23_server_method());
SSL_CTX_use_PrivateKey(...);
SSL_CTX_use_certificate(...);

ssl = SSL_new(ctx); // I want to read/write TLS packets directly with this object
Run Code Online (Sandbox Code Playgroud)

我已经研究过OpenSSL 文档,但它没有很好的文档记录.在指南中说,可以使用SSL_set_accept_state()with SSL_read和SSL_write "手动"进行握手,但我不明白如何做到这一点.

任何有关此或关于在不依赖TCP的情况下处理OpenSSL连接的建议都将非常感激.

Ser*_* A. 5

我最终阅读了OpenSSL 网络安全这本书,发现内存 BIO正是我所需要的。

使用 OpenSSL 的网络安全

内存 BIO 将内存段视为文件或套接字,可以通过使用 BIO_s_mem 创建以获得适合与 BIO_new 和 BIO_set 一起使用的 BIO_METHOD 对象

BIO_s_mem()

BIO_s_mem() 返回内存 BIO 方法函数。

内存 BIO 是一个源/汇 BIO,它使用内存进行 I/O。写入内存 BIO 的数据存储在 BUF_MEM 结构中,该结构适当扩展以容纳存储的数据。

任何写入内存 BIO 的数据都可以通过读取来调用。除非只读取内存 BIO,否则从它读取的任何数据都会从 BIO 中删除。

基本上,您可以使用内存 BIO 将加密数据直接读/写到 SSL 连接:

// setup SSL_context...
ssl = SSL_new(ctx);

// Create read/write BIOs 
rbio = BIO_new(BIO_s_mem());
wbio = BIO_new(BIO_s_mem());

SSL_set_bio(ssl, rbio, wbio);

if (/* Server */) {
  SSL_set_accept_state(ssl); 
} else {
  SSL_set_connect_state(ssl);
}
Run Code Online (Sandbox Code Playgroud)

写入/读取从BIOS:

BIO_read(wbio, buffer, strlen(buffer));
BIO_write(wbio, buffer, strlen(buffer));
Run Code Online (Sandbox Code Playgroud)


Dar*_*ith 5

用 ascii 图表术语来说,这就是字节流循环的样子。SSL_read/SSL_write 用于将未加密的字节传入/传出 SSL 对象,BIO_read/BIO_write 用于将相应的加密字节传入/传出 SSL 对象。然后由您决定通过网络连接传输加密字节。

非阻塞套接字/SSL 的 Git 集线器示例

( https://gist.github.com/darrenjs/4645f115d10aa4b5cebf57483ec82eca )

  +------+                                    +-----+
  |......|--> read(fd) --> BIO_write(rbio) -->|.....|--> SSL_read(ssl)  --> IN
  |......|                                    |.....|
  |.sock.|                                    |.SSL.|
  |......|                                    |.....|
  |......|<-- write(fd) <-- BIO_read(wbio) <--|.....|<-- SSL_write(ssl) <-- OUT
  +------+                                    +-----+
          |                                  |       |                     |
          |<-------------------------------->|       |<------------------->|
          |         encrypted bytes          |       |  unencrypted bytes  |
Run Code Online (Sandbox Code Playgroud)