BIO
https://www.openssl.org/docs/man1.0.2/man3/bio.html
openssl抽象IO(I/O abstraction,即BIO)是openssl对于io类型的抽象封装,包括:内存、文件、日志、标准输入输出、socket(TCP/UDP)、加/解密、摘要和ssl通道等。Openssl BIO通过回调函数为用户隐藏了底层实现细节,所有类型的bio的调用大体上是类似的。Bio中的数据能从一个BIO传送到另外一个BIO或者是应用程序。
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_s_*()
BIO_s_file()
返回BIO文件方法。顾名思义,它是stdio FILE结构的包装,并且是源/接收BIO。
https://www.openssl.org/docs/man1.0.2/man3/BIO_s_file.htmlBIO_s_mem()
返回内存BIO方法函数。
https://www.openssl.org/docs/man1.0.2/man3/BIO_s_mem.html
此外还有BIO_s_bio(3), BIO_s_connect(3), BIO_s_fd(3), BIO_s_null(3), BIO_s_socket(3),但是和asn1关系不大,不做赘述
BIO_f_*()
包括BIO_f_base64(3), BIO_f_buffer(3), BIO_f_cipher(3), BIO_f_md(3), BIO_f_null(3), BIO_f_ssl(3),因为和本次课设关系不大,所以不做赘述
BIO allocation and freeing functions
原型
https://www.openssl.org/docs/man1.0.2/man3/BIO_new.html
#include <openssl/bio.h>
BIO * BIO_new(BIO_METHOD *type);
int BIO_set(BIO *a,BIO_METHOD *type);
int BIO_free(BIO *a);
void BIO_vfree(BIO *a);
void BIO_free_all(BIO *a);
描述
BIO_new()
函数使用方法type返回一个新的BIO。BIO_set()
设置现有BIO的方法。BIO_free()
释放单个BIO,BIO_vfree()
也释放单个BIO,但不返回值。调用BIO_free()
可能还会对基础I/O结构产生某些影响,例如,在某些情况下,它可能会关闭正在引用的文件。有关更多详细信息,请参见各个BIO_METHOD描述。BIO_free_all()
释放了整个BIO链,如果在释放链中的单个BIO时发生错误,它不会停止。
返回值
- 如果调用失败,则
BIO_new()
返回新创建的BIO或NULL。 BIO_set()
,BIO_free()
对于成功返回1,对于失败返回0。BIO_free_all()
和BIO_vfree()
不返回值。
note
通常,type
实参由函数提供,该函数返回指向BIO_METHOD
的指针。这些功能有一个命名约定:源/接收器BIO通常命名为为BIO_s_*()
而过滤器BIO命名为BIO_f_*()
例子
BIO* bp = BIO_new(BIO_s_file());
当然openssl也提供了高级的封装接口
BIO *BIO_new_file(const char *filename, const char *mode);
BIO *BIO_new_fp(FILE *stream, int flags);
BIO I/O functions
原型
https://www.openssl.org/docs/man1.0.2/man3/BIO_read.html
#include <openssl/bio.h>
int BIO_read(BIO *b, void *buf, int len);
int BIO_gets(BIO *b, char *buf, int size);
int BIO_write(BIO *b, const void *buf, int len);
int BIO_puts(BIO *b, const char *buf);
描述
BIO_read()
尝试从BIO b读取len个字节,并将数据放入buf中。BIO_gets()
执行BIO的“获取”操作,并将数据放置在buf中。通常,此操作将尝试从最大长度为len的BIO读取一行数据。但是有一些例外,例如摘要上的BIO_gets()
BIO将计算并返回摘要,而其他BIO可能根本不支持BIO_gets()
。BIO_write()
尝试将len个字节从buf写入BIO b。BIO_puts()
尝试将以null终止的字符串buf写入BIO b
返回值
所有这些函数都返回成功读取或写入的数据量(如果返回值为正),或者如果结果为0或-1,则没有成功读取或写入数据。如果返回值为-2,则不会以特定的BIO类型实现该操作。
formatted output to a BIO
原型
https://www.openssl.org/docs/man1.1.0/man3/BIO_snprintf.html
#include <openssl/bio.h>
int BIO_printf(BIO *bio, const char *format, ...)
int BIO_vprintf(BIO *bio, const char *format, va_list args)
int BIO_snprintf(char *buf, size_t n, const char *format, ...)
int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
描述
BIO_printf()
与标准Cprintf()
函数类似,除了输出发送到指定的BIO bio而不是标准输出。支持所有通用格式说明符。BIO_vprintf()
与许多平台上的vprintf()
函数相似,输出被发送到指定的BIO bio,而不是标准输出。支持所有通用格式说明符。参数列表args是stdarg参数列表。BIO_snprintf()
用于没有通用snprintf()
函数的平台。类似于sprintf()
,不同之处在于size参数n指定输出缓冲区的大小。BIO_vsnprintf()
指向BIO_snprintf()
,就像BIO_vprintf()
指向BIO_printf()
一样。
返回值
所有函数都返回写入的字节数,如果出错则返回-1。对于BIO_snprintf()
和BIO_vsnprintf()
,这包括输出缓冲区太小时。