04.openssl支持底层api接口

OpenSSL库由许多不同的包组成。 一些较低级别的软件包可以独立使用,而较高级别的软件包可以使用几个较低级别的软件包。 要有效地使用OpenSSL库,重要的是要了解我们已经介绍的密码学的基本概念,并熟悉更重要的补充软件包产品.
 
4.1 Multithread Support(多线程支持)
大多数现代操作系统都支持多线程应用程序,并且应用程序利用这种支持变得越来越普遍。 OpenSSL当然可以在多线程环境中使用; 然而,它要求开发人员做一些工作,以使程序线程安全。 许多开发人员在OpenSSL中犯的常见错误是他们认为库是线程安全的,不需要在应用程序中做任何特殊的事情。 这当然是一个不正确的假设,并且在多线程环境中设置OpenSSL失败会导致不可预知的行为,并且看起来随机的崩溃是非常难以调试的。
 
应用程序有两种不同的回调方式可以在多线程环境中安全地运行。 静态锁提供了固定数量的可供OpenSSL使用的互斥锁。 动态锁定允许OpenSSL根据需要创建互斥锁。 OpenSSL目前不使用动态锁,但保留在将来这样做的权利。 如果您希望您的应用程序将来继续以最小的工作量继续工作,我们建议您现在实施静态和动态锁定。
 
4.1.1 Static Locking Callbacks (静态锁回调)
函数名称
void locking_function(int mode, int n, const char *file, int line);
功能
下一个回调函数用于获取调用线程的唯一标识符。
参数
意义
mode
确定锁定功能应采取的操作。
n
应该获得或释放的锁的数量。
file
请求锁定操作发生的源文件的名称。
line
请求锁定操作发生的源代码行号。
 
 
4.1.2 Dynamic Locking Callbacks(动态锁回调)
步骤:创建锁->添加或删除锁->释放锁
结构成员:
struct CRYPTO_dynlock_value
{
MUTEX_TYPE mutex;
};
 
 
函数名称
 
struct CRYPTO_dynlock_value *dyn_create_function(const char *file,int line);
功能
我们需要定义的第一个回调函数用于创建一个新的互斥体,OpenSSL将能够使用这个互斥体来保护数据结构
参数
意义
file
请求创建互斥锁的源文件的名称。
line
请求创建互斥锁的源代码行号。
 
 
函数名称
 
void dyn_lock_function(int mode, struct CRYPTO_dynlock_value*mutex, const char *file, int line);
功能
下一个回调函数用于获取或释放互斥锁。
参数
意义
mode
确定锁定功能应采取的操作。
mutex
应该被获得或释放的互斥体。
file
请求创建互斥锁的源文件的名称。
line
请求创建互斥锁的源代码行号。
 
 
函数名称
 
void dyn_destroy_function(struct CRYPTO_dynlock_value *mutex,const char *file, int line);
功能
销毁OpenSSL不再需要的互斥体。
参数
意义
mutex
应该销毁的互斥体
file
请求创建互斥锁的源文件的名称。
line
请求创建互斥锁的源代码行号。
 
 
4.2 Internal Error Handling
4.2.1 Manipulating Error Queues
当OpenSSL库发生错误时,会记录大量的信息。 有些信息可能会自动尝试从错误中恢复,但其中大部分信息用于调试错误并将错误报告给用户。
 
ERR包提供了六个基本功能,这些功能对于从错误队列中获取信息非常有用。 每个函数总是从队列中检索最旧的信息,以便按照生成的顺序返回错误。 记录的最基本的信息是错误代码,它描述发生的错误。 错误代码是一个32位整数,仅对OpenSSL有意义。 也就是说,OpenSSL为它可能遇到的任何错误条件定义了自己的唯一错误代码。 它不依赖于任何其他库(包括标准C运行库)定义的错误代码。 对于六个基本函数中的每一个,这个错误代码是函数的返回值。 如果队列中没有错误,则任何一个的返回都将是0,这也告诉我们0从来不是有效的错误代码。
 
 
函数名称
 
unsigned long ERR_get_error(void);
功能
错误码
 
 
函数名称
 
unsigned long ERR_peek_error(void);
功能
第二个函数也只从错误队列中检索错误代码,但是它不会被删除
来自队列的错误报告,所以下一次调用将检索到相同的错误:
参数
意义
mutex
应该销毁的互斥体
file
请求创建互斥锁的源文件的名称。
line
请求创建互斥锁的源代码行号。
 
 
 
函数名称
 
unsigned long ERR_get_error_line(const char **file, int *line);
功能
第三个函数建立在由ERR_get_error和ERR_peek_error返回的信息上。 除了返回错误代码之外,
它还会返回生成错误的源文件和源代码行的名称。 像ERR_get_error一样,它也从队列中删除错误报告.
参数
意义
file
接收生成错误的源文件的名称。
line
接收生成错误的源代码行号。
 
 
 
 
函数名称
 
unsigned long ERR_peek_error_line(const char **file, int *line);
功能
 
参数
意义
file
接收生成错误的源文件的名称。
line
接收生成错误的源代码行号。
 
 
函数名称
 
unsigned long ERR_get_error_line_data(const char **file, int *line,const char **data, int *flags);
功能
获取错误行号和错误数据,并从队列中删除
参数
意义
file
接收生成错误的源文件的名称。
line
接收生成错误的源代码行号。
 
data
接收指向错误报告中附带的额外数据的指针。
 
flags
接收一组定义额外数据属性的标志。
 
 
 
函数名称
 
unsigned long ERR_peek_error_line_data(const char **file, int *line,const char **data, int *flags);
功能
获取错误行号和错误数据
参数
意义
file
接收生成错误的源文件的名称。
line
接收生成错误的源代码行号。
 
data
接收指向错误报告中附带的额外数据的指针。
 
flags
接收一组定义额外数据属性的标志。
 
 
函数名称
void ERR_clear_error(void);
功能
还有最后一个队列操作函数,我们将在这里讨论:清除函数
错误队列。
参数
意义
 
 
最后还有一个队列操作函数,我们将在这里讨论:清除错误队列的函数。 它将删除当前队列中的所有错误。 一般情况下,除非我们试图重置当前线程的错误状态,而不关心队列中的其他错误,否则不需要调用这个函数。 一旦被调用,没有办法恢复以前的错误,所以明智地使用它.
 
4.3 Abstract Input/Output
OpenSSL库提供了多种功能,用于创建和销毁BIO,将它们链接在一起以及读取或写入数据。 需要注意的是,BIO包是一个低级包,因此您必须小心使用它。 许多功能将允许您执行操作,以后可能导致不可预知的行为甚至崩溃。
 
函数
功能
The BIO *BIO_new(BIO_METHOD *type);
初始化BIO
int BIO_set(BIO *bio, BIO_METHOD *type);
 
int BIO_free(BIO *bio);
当一个BIO不再需要时,它应该被销毁。
void BIO_vfree(BIO *bio);
BIO_vfree函数与BIO_free相同,只是它不返回值
void BIO_free_all(BIO *bio);
BIO_free_all函数可用于释放整个BIO链。
BIO *BIO_push(BIO *bio, BIO *append);
BIO_push函数会将BIO附加到BIO,从而创建或延长BIO链。
BIO *BIO_pop(BIO *bio);
BIO_pop函数将从指定的BIO链中删除指定的BIO并返回
链中的下一个BIO或者如果没有下一个BIO,则为NULL。
int BIO_read(BIO *bio, void *buf, int len);
BIO_read的行为与C运行时函数读取几乎完全相同。
int BIO_gets(BIO *bio, char *buf, int len);
为从源BIO读取数据提供的另一个函数是BIO_gets,通常与C运行库对应的fgets的行为几乎相同。
int BIO_write(BIO *bio, const void *buf, int len);
从BIO_write的行为写
int BIO_puts(BIO *bio, const char *buf);
BIO_puts将指定的缓冲区解释为C风格的字符串,并尝试将其全部写出。
 
我们提到,对于四个读写函数中的每一个,0或-1的返回值可能会或可能不一定表示发生错误。 提供了一套函数,可以让我们确定是否真的发生了错误,以及是否应该重试该操作。
 
4.4 Random Number Generation
整个OpenSSL库中的许多函数都需要随机数的可用性。 例如,创建会话密钥和生成公钥/私钥对都需要随机数字。 为了满足这个要求,RAND包提供了一个密码强的伪随机数发生器(PRNG)。 这意味着它产生的“随机”数据并不是真正的随机数,但在计算上难以预测。
 
对于所有其他的随机数要求,由PRNG产生的伪随机数是适合使用。
在许多Unix系统上,/ dev / random和/dev/urandom随机数产生器
参考代码:
int RAND_load_file(const char *filename, long bytes);
int RAND_write_file(const char *filename);
/* Read 1024 bytes from /dev/random and seed the PRNG with it */
RAND_load_file("/dev/random", 1024);
/* Write a seed file */
RAND_write_file("prngseed.dat");
/* Read the seed file in its entirety and print the number of bytes
obtained */
nb = RAND_load_file("prngseed.dat", -1);
printf("Seeded the PRNG with %d byte(s) of data from prngseed.dat.\n",nb);
 
函数
功能
RAND_screen
可以被周期性地调用以收集熵。
 RAND_load_file
这将使PRNG的文件内容达到指定的字节数,或者如果限制被指定为-1,则将它的全部种子。
RAND_write_file
显示了该函数及其对应的一些示例用法,
int RAND_egd(const char *path);
RAND_egd尝试连接到指定的Unix域套接字。
int RAND_egd_bytes(const char *path, int bytes);
RAND_egd_bytes将尝试连接到指定的Unix域套接字。
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int
bytes);
 
 
4.5 Arbitrary Precision Math
4.5.1 The Basics
BN_bn2bin
它会返回写入到提供的缓冲区的字节数。
BN_bin2bn
结果放入第三个指定的BIGNUM中论点,覆盖它以前可能持有的任何价值。
BN_bn2hex
存储在Cstyle字符串中的十六进制表示。
BN_bn2dec
函数BN_bn2dec将BIGNUM转换为存储在C-stylestring中的十进制表示形式。...
BN_hex2bn
将存储在C风格字符串中的数字的十六进制表示转换为BIGNUM。
BN_dec2bn
将十进制的转换成BIGNUM数据
 
4.5.2 Mathematical Operations
Function 
Comments
BN_add(r, a, b) 
(r = a + b) r may be the same as a or b.
BN_sub(r, a, b) 
(r = a - b)
BN_mul(r, a, b, ctx) 
(r = a x b) r may be the same as a or b.
BN_sqr(r, a, ctx) 
(r = pow(a, 2)) r may be the same as a. This function is faster than
BN_mul(r, a, a).
BN_div(d, r, a, b, ctx) 
(d = a / b, r = a % b) Neither d nor r may be the same as either a or b.
Either d or r may be NULL.
BN_mod(r, a, b, ctx) 
(r = a % b)
BN_nnmod(r, a, b, ctx) 
(r = abs(a % b))
BN_mod_add(r, a, b, m,
ctx) 
(r = abs((a + b) % m))
BN mod sub(r, a, b, m,ctx)  
(r = abs((a - b) % m))
BN_mod_mul(r, a, b, m,ctx) 
(r = abs((a x b) % m)) r may be the same as a or b.
BN_mod_sqr(r, a, m,ctx) 
(r = abs(pow(a, 2) % m))
BN_exp(r, a, p, ctx) 
(r = pow(a, p))
BN_mod_exp(r, a, p, m,ctx) 
(r = pow(a, 2) % m)
BN_gcd(r, a, b, ctx) 
Finds the greatest common divisor of a and b. r may be the same as a orb.
 
 
4.5.3 Generating Prime Numbers(产生质素)
函数
BIGNUM *BN_generate_prime(BIGNUM *ret,
int bits,
int safe,
BIGNUM*add,
BIGNUM *rem,
void (*callback)(int,int, void *),
void *cb_arg);
功能
顾名思义,函数产生素数,更重要的是产生伪随机素数。
参数
意义
ret
用于接收生成的素数。 如果指定为NULL,则会创建一个新的BIGNUM,并使用BN_new进行初始化并返回。
bits
应该用来表示生成的素数的位数
safe
可以是零或非零,表示生成的素数是否应该是安全的。
add
用于指定生成的素数应具有的其他属性。
rem
用于指定生成的素数应具有的其他属性。
callback
在生成素数期间调用的函数,用于报告操作的状态。
cb_arg
如果指定了一个值,则仅用于传递给回调函数。
 
 
ID string 
Description
openssl 
引擎使用正常的内置函数进行加密操作。
openbsd_dev_crypto 
在OpenBSD操作系统上,这个引擎将使用操作系统内置的内核级加密技术。
cswift 
用于CryptoSwift加速硬件。
chil 
用于nCipher CHIL加速硬件。
atalla 
用于Compaq Atalla加速硬件。
nuron 
用于Nuron加速硬件。
ubsec 
用于Broadcom uBSec加速硬件。
aep 
用于Aep加速硬件。
sureware 
用于SureWare加速硬件。
 
 
Table 4-3. Flags for ENGINE_set_default
 
Flag
Description
ENGINE_METHOD_RSA
将引擎使用限制为仅限RSA操作。
ENGINE_METHOD_DSA
将引擎使用限制为仅DSA操作。
ENGINE_METHOD_DH
将引擎使用限制为仅限DH操作。
ENGINE_METHOD_RAND
将引擎使用限制为只有随机数字操作。
ENGINE_METHOD_CIPHERS
将引擎使用限制为仅对称密码操作。
ENGINE_METHOD_DIGESTS
将引擎使用限制为仅消化操作。
ENGINE_METHOD_ALL
允许OpenSSL使用任何上述实现。
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值