2021SC@SDUSC openssl-gpu 抽象IO

OpenSSL的BIO(I/O抽象)提供了一种统一的接口,用于处理各种类型的IO操作,包括内存、文件、日志、标准输入输出、网络、加解密和SSL。BIO通过回调函数隐藏底层实现,支持数据在BIO之间或与应用程序之间的传递。BIO分为source/sink和filter两种类型,前者作为数据源,后者用于数据转换。BIO链允许数据从一个BIO读写到另一个,常用于构建复杂的IO流程,如加密、解密和SSL处理。编程示例展示了如何使用mem BIO、file BIO、md BIO和cipher BIO进行实际操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2021SC@SDUSC
7 抽象IO
7.1 openssl 抽象 IO

openssl 抽象 IO(I/O abstraction,即 BIO)是 openssl 对于 io 类型的抽象封装,
包括:内存、 文件、日志、标准输入输出、socket(TCP/UDP)、加/解密、摘要和 ssl 通道等。
Openssl BIO 通过回调函数为用户隐藏了底层实现细节,所有类型的 bio 的调用大体上是类似的。
Bio 中的数据能从一个 BIO 传送到另外一个 BIO 或者是应用程序。

其实包含了很多种接口,用通用的函数接口,主要控制在BIO_METHOD中的不同实现函数控制,
包括6种filter型和8种source/sink型。

source/sink类型的BIO是数据源,
例如,sokect BIO 和 文件BIO。
而filter BIO就是把数据从一个BIO转换到另外一个BIO或应用接口,
在转换过程中,些数据可以不修改(如信息摘要BIO),也可以进行转换.
例如在加密BIO中,如果写操作,数据就会被加密,如果是读操作,数据就会被解密。

BIO是封装了许多类型I/O接口细节的一种应用接口,
可以和SSL连接、 非加密的网络连接以及文件IO进行透明的连接。
BIO可以连接在一起成为一个BIO链(单个的BIO就是一个环节的BIO链的特例),

如下是BIO的结构定义,可以看到它有上下环节。

一个BIO链通常包括一个source BIO和一个或多个filter BIO,数据从第一个BIO读出或写入,
然后经过一系列BIO变化到输出(通常是一个source/sink BIO)。

BIO目录文件的简要说明:

bio.h: 主定义的头文件,包括了很多通用的宏的定义。
bio_lib.c: 主要的BIO操作定义文件,是比较上层的函数了。
bss_*系列:是soruce/sink型BIO具体的操作实现文件
bf_*系列: 是filter型BIO具体的操作实现文件
bio_err.c: 是错误信息处理文件
bio_cb.c: 是callback函数的相关文件
b_print.c: 是信息输出的处理函数文件
b_socket.c: 是Socket连接的一些相关信息处理文件
b_dump.c: 是对内存内容的存储操作处理

7.2 数据结构

BIO 数据结构主要有 2 个,在 crypto/bio.h 中定义如下:

    BIO_METHOD
typedef struct bio_method_st {
   
        int type;
        const char *name;
        int (*bwrite)(BIO *, const char *, int);
        int (*bread)(BIO *, char *, int);
        int (*bputs)(BIO *, const char *);
        int (*bgets)(BIO *, char *, int);
        long (*ctrl)(BIO *, int, long, void *);
        int  (*create)(BIO *);
        int  (*destroy)(BIO *);
        long (*callback_ctrl)(BIO *, int, bio_info_cb *);
} BIO_METHOD;

该结构定义了 IO 操作的各种回调函数,根据需要,具体的 bio 类型必须实现其中的一种或多种回调函数,各项意义如下:

type: 具体 BIO 类型;
name: 具体 BIO 的名字;
bwrite: 具体 BIO 写操作回调函数;
bread: 具体 BIO 读操作回调函数;
bputs: 具体 BIO 中写入字符串回调函数;
bgets: 具体 BIO 中读取字符串函数;
ctrl: 具体 BIO 的控制回调函数;
create: 生成具体 BIO 回调函数;
destroy: 销毁具体 BIO 回调函数;
callback_ctrl: 具体 BIO 控制回调函数,与 ctrl 回调函数不一样,
该函数可由调用者(而不是实现者)来实现,然后通过
BIO_set_callback 等函数来设置。

    BIO
truct bio_st {
   
    BIO_METHOD *method;
    /* bio, mode, argp, argi, argl, ret */
    long (*callback)(struct bio_st *,int,const char *,int, long,long);
    char *cb_arg;   /* first argument for the callback */
    int  init;
    int  shutdown;
    int  flags;      /* extra storage */
    int  retry_reason;
    int  num;
    void *ptr;
    structbio_st *next_bio;   /*usedbyfilterBIOs*/
    struct bio_st *prev_bio; /* used by filter BIOs */
    int references;
    nsigned long  num_read;
    unsigned long num_write;
    CRYPTO_EX_DATA ex_data;
};

/*
主要项含义:

init: 具体句柄初始化标记,初始化后为1。
比如:文件 BIO 中,通过 BIO_set_fp 关联一个文件指针时,该标记则置 1 ;
socket BIO中,通过 BIO_set_fd 关联一个链接时,设置该标记为 1。

shutdown: BIO 关闭标记,当该值不为 0 时,释放资源; 该值可以通过控制函 数来设置。

flags: 有些 BIO 实现需要它来控制各个函数的行为。
比如文件 BIO 默认该值为 BIO_FLAGS_UPLINK,
这时文件读操作调用UP_fread 函数而不是调用fread 函数。

retry_reason: 重试原因,主要用在 socket 和 ssl BIO 的异步阻塞。
比如 socket bio 中,遇到 WSAEWOULDBLOCK 错误时,
openssl 告诉用户的操作需要重试。

num: 该值因具体 BIO 而异,比如 socket BIO 中 num 用来存放链接字。

ptr: 指针,体 bio 有不同含义。比如:
文件 BIO 中它用来存放文件句柄;
mem BIO 中它用来存放内存地址;
connect BIO 中它用来存放 BIO_CONNECT 数据,
accept BIO 中它用来存放 BIO_ACCEPT 数据。

next_bio: 下一个 BIO 地址,BIO 数据可以从一个BIO传送到另一个BIO,
该值指明了下一个 BIO 的地址。

references: 被引用数量。
num_read: BIO 中已读取的字节数。
num_write: BIO 中已写入的字节数。
ex_data: 用于存放额外数据。
*/

typedef struct bio_st BIO;

struct bio_st
{
   
     BIO_METHOD *method; //BIO方法结构,是决定BIO类型和行为的重要参数,各种BIO的不同之处主要也正在于此项。

     long (*callback)(struct
<think>好的,我现在需要解决用户在QT的.pro文件中配置OpenSSL路径的问题。用户希望将路径指向/usr/bin/openssl。首先,我需要回忆一下Qt项目中如何配置第三方库的路径。根据之前的引用内容,尤其是引用3和引用4,用户在.pro文件中通常使用INCLUDEPATH和LIBS来指定头文件和库文件的路径。 首先,检查用户提供的OpenSSL路径是否正确。/usr/bin/openssl通常是可执行文件的路径,而头文件和库文件可能在另外的目录中,比如/usr/include/openssl或者/usr/local/ssl/include,库文件可能在/usr/lib或/usr/local/lib等位置。用户可能混淆了openssl可执行文件和开发库的位置。需要提醒用户确认开发库的安装路径。 接下来,参考引用3中的例子,当添加多个库时,INCLUDEPATH和LIBS只能写一次,后面跟多个路径或库。因此,正确的做法是在.pro文件中添加类似: INCLUDEPATH += /usr/include/openssl LIBS += -L/usr/lib -lssl -lcrypto 但用户指定的是/usr/bin/openssl,这可能不正确。这时候可能需要指导用户使用正确的头文件和库路径。如果用户确实将OpenSSL安装在自定义路径下,比如/usr/local/opt/openssl@1.1,那么需要根据实际路径调整,如引用1中提到的CPPFLAGS设置。 另外,引用4中提到可以通过--prefix指定安装路径,或者在.pro文件中直接指定INCLUDEPATH和LIBS。因此,正确的方法应该是让用户确认他们的OpenSSL开发文件的安装位置,然后在.pro文件中正确指向这些路径。 可能还需要考虑不同平台下的兼容性,比如Windows和Linux的区别,但用户的问题似乎是针对Linux系统的,因为路径是/usr/bin/openssl。此外,需要注意库文件的名字是否正确,例如libssl.so和libcrypto.so,可能需要使用-lssl -lcrypto来链接。 总结步骤:1.确认OpenSSL的头文件和库文件路径;2.在.pro文件中使用INCLUDEPATH添加头文件路径;3.使用LIBS添加库路径和链接库;4.验证路径是否存在,以及库是否正确安装。同时,提醒用户如果使用自定义安装路径,可能需要设置环境变量或者修改.pro文件中的路径。</think>在Qt项目的`.pro`文件中配置OpenSSL路径需要明确指定头文件路径和库文件路径。以下是具体步骤: --- ### **步骤1:确认OpenSSL开发文件的安装路径** - **头文件路径**(如`openssl/ssl.h`):通常在`/usr/include/openssl`或`/usr/local/opt/openssl/include`(macOS通过Homebrew安装时)[^1][^2]。 - **库文件路径**(如`libssl.so`或`libcrypto.dylib`):通常在`/usr/lib`或`/usr/local/opt/openssl/lib`[^1]。 若您的OpenSSL安装在自定义路径(例如`/myroot/openssl`),需确保路径中包含`include`和`lib`子目录。 --- ### **步骤2:在.pro文件中配置路径** 在`.pro`文件中添加以下内容(根据实际路径调整): ```qmake # 添加OpenSSL头文件路径 INCLUDEPATH += /usr/local/opt/openssl/include # 添加OpenSSL库文件路径及链接库 LIBS += -L/usr/local/opt/openssl/lib -lssl -lcrypto ``` --- ### **步骤3:验证路径有效性** - 检查头文件是否存在:`ls /usr/local/opt/openssl/include/openssl/ssl.h` - 检查库文件是否存在:`ls /usr/local/opt/openssl/lib/libssl.*` --- ### **跨平台兼容性配置** 若需支持Windows和Linux,可结合条件判断: ```qmake win32 { # Windows下配置示例(需替换实际路径) INCLUDEPATH += C:/OpenSSL-Win64/include LIBS += -LC:/OpenSSL-Win64/lib -llibssl -llibcrypto } else:unix { # Linux/macOS配置 INCLUDEPATH += /usr/local/opt/openssl/include LIBS += -L/usr/local/opt/openssl/lib -lssl -lcrypto } ``` --- ### **注意事项** 1. **路径分隔符**:Linux/macOS用`/`,Windows用`\`。 2. **动态库与静态库**:若需静态链接,Windows下使用`.lib`文件,Linux下使用`.a`文件。 3. **环境变量**:若OpenSSL通过包管理器安装(如macOS的Homebrew),可能需要设置`CPPFLAGS`或`LDFLAGS`。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值