技术标签: openssl
OpenSSL的SSL/TLS库,实现了SSL(Secur)/TLS(Transport Layer Security)/DTLS(Datagram Transport Layer Security)协议的多个版本。
SSL_CTX对象包含证书、算法等信息,用于建立TLS/SSL连接。
网络连接建立后可以赋值给SSL对象,然后可以使用SSL对象完成握手操作(SSL_accept或SSL_connect或SSL_do_handshake),握手完成后就可以读写了。关闭网络连接前先调用SSL_shutdown关闭TLS/SSL连接。
#include <openssl/ssl.h>
/* CA 设置 */
int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath);
int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile);
int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore);
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx);
int SSL_CTX_set_default_verify_file(SSL_CTX *ctx);
int SSL_CTX_set_default_verify_store(SSL_CTX *ctx);
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
const char *CApath);
/* CA证书相关操作 */
void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *list);
void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *list);
STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx);
int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *cacert);
int SSL_add_client_CA(SSL *ssl, X509 *cacert);
void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx);
const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s);
int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x);
int SSL_add1_to_CA_list(SSL *ssl, const X509 *x);
const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s);
/* 证书链设置 */
int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *sk);
int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *sk);
int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509);
int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509);
int SSL_CTX_get0_chain_certs(SSL_CTX *ctx, STACK_OF(X509) **sk);
int SSL_CTX_clear_chain_certs(SSL_CTX *ctx);
int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *sk);
int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *sk);
int SSL_add0_chain_cert(SSL *ssl, X509 *x509);
int SSL_add1_chain_cert(SSL *ssl, X509 *x509);
int SSL_get0_chain_certs(SSL *ssl, STACK_OF(X509) **sk);
int SSL_clear_chain_certs(SSL *ssl);
int SSL_CTX_build_cert_chain(SSL_CTX *ctx, flags);
int SSL_build_cert_chain(SSL *ssl, flags);
/* 证书和密钥设置 */
int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
int SSL_use_certificate(SSL *ssl, X509 *x);
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
int SSL_use_certificate_file(SSL *ssl, const char *file, int type);
int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
int SSL_use_certificate_chain_file(SSL *ssl, const char *file);
int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d,
long len);
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len);
int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, long len);
int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len);
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
int SSL_CTX_check_private_key(const SSL_CTX *ctx);
int SSL_check_private_key(const SSL *ssl);
int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override);
int SSL_use_cert_and_key(SSL *ssl, X509 *x, EVP_PKEY *pkey, STACK_OF(X509) *chain, int override);
/* 证书选择 */
int SSL_CTX_select_current_cert(SSL_CTX *ctx, X509 *x509);
int SSL_select_current_cert(SSL *ssl, X509 *x509);
int SSL_CTX_set_current_cert(SSL_CTX *ctx, long op);
int SSL_set_current_cert(SSL *ssl, long op);
#include <openssl/ssl.h>
SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
const SSL_METHOD *method);
SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);
int SSL_CTX_up_ref(SSL_CTX *ctx);
const SSL_METHOD *TLS_method(void);
const SSL_METHOD *TLS_server_method(void);
const SSL_METHOD *TLS_client_method(void);
const SSL_METHOD *SSLv23_method(void);
const SSL_METHOD *SSLv23_server_method(void);
const SSL_METHOD *SSLv23_client_method(void);
#ifndef OPENSSL_NO_SSL3_METHOD
const SSL_METHOD *SSLv3_method(void);
const SSL_METHOD *SSLv3_server_method(void);
const SSL_METHOD *SSLv3_client_method(void);
#endif
#ifndef OPENSSL_NO_TLS1_METHOD
const SSL_METHOD *TLSv1_method(void);
const SSL_METHOD *TLSv1_server_method(void);
const SSL_METHOD *TLSv1_client_method(void);
#endif
#ifndef OPENSSL_NO_TLS1_1_METHOD
const SSL_METHOD *TLSv1_1_method(void);
const SSL_METHOD *TLSv1_1_server_method(void);
const SSL_METHOD *TLSv1_1_client_method(void);
#endif
#ifndef OPENSSL_NO_TLS1_2_METHOD
const SSL_METHOD *TLSv1_2_method(void);
const SSL_METHOD *TLSv1_2_server_method(void);
const SSL_METHOD *TLSv1_2_client_method(void);
#endif
const SSL_METHOD *DTLS_method(void);
const SSL_METHOD *DTLS_server_method(void);
const SSL_METHOD *DTLS_client_method(void);
#ifndef OPENSSL_NO_DTLS1_METHOD
const SSL_METHOD *DTLSv1_method(void);
const SSL_METHOD *DTLSv1_server_method(void);
const SSL_METHOD *DTLSv1_client_method(void);
#endif
#ifndef OPENSSL_NO_DTLS1_2_METHOD
const SSL_METHOD *DTLSv1_2_method(void);
const SSL_METHOD *DTLSv1_2_server_method(void);
const SSL_METHOD *DTLSv1_2_client_method(void);
#endif
void SSL_CTX_free(SSL_CTX *ctx);
uint64_t SSL_CTX_set_options(SSL_CTX *ctx, uint64_t options);
uint64_t SSL_set_options(SSL *ssl, uint64_t options);
uint64_t SSL_CTX_clear_options(SSL_CTX *ctx, uint64_t options);
uint64_t SSL_clear_options(SSL *ssl, uint64_t options);
uint64_t SSL_CTX_get_options(const SSL_CTX *ctx);
uint64_t SSL_get_options(const SSL *ssl);
long SSL_get_secure_renegotiation_support(SSL *ssl);
typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, SSL_verify_cb verify_callback);
void SSL_set_verify(SSL *ssl, int mode, SSL_verify_cb verify_callback);
SSL_get_ex_data_X509_STORE_CTX_idx(void);
void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
void SSL_set_verify_depth(SSL *ssl, int depth);
int SSL_verify_client_post_handshake(SSL *ssl);
void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val);
void SSL_set_post_handshake_auth(SSL *ssl, int val);
int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version);
int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version);
int SSL_CTX_get_min_proto_version(SSL_CTX *ctx);
int SSL_CTX_get_max_proto_version(SSL_CTX *ctx);
int SSL_set_min_proto_version(SSL *ssl, int version);
int SSL_set_max_proto_version(SSL *ssl, int version);
int SSL_get_min_proto_version(SSL *ssl);
int SSL_get_max_proto_version(SSL *ssl);
X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
一些SSL_CTX中的设置也可以在SSL中单独设置或修改,接口也一并在此列出。
#include <openssl/ssl.h>
SSL_CONF_CTX *SSL_CONF_CTX_new(void);
void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx);
unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags);
unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags);
unsigned int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *prefix);
int SSL_CONF_cmd(SSL_CONF_CTX *ctx, const char *option, const char *value);
int SSL_CONF_cmd_value_type(SSL_CONF_CTX *ctx, const char *option);
int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv);
void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx);
void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl);
#include <openssl/ssl.h>
SSL *SSL_new(SSL_CTX *ctx);
SSL *SSL_dup(SSL *s);
int SSL_up_ref(SSL *s);
void SSL_free(SSL *ssl);
int SSL_set_fd(SSL *ssl, int fd);
int SSL_set_rfd(SSL *ssl, int fd);
int SSL_set_wfd(SSL *ssl, int fd);
int SSL_get_fd(const SSL *ssl);
int SSL_get_rfd(const SSL *ssl);
int SSL_get_wfd(const SSL *ssl);
void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio);
void SSL_set0_rbio(SSL *s, BIO *rbio);
void SSL_set0_wbio(SSL *s, BIO *wbio);
BIO *SSL_get_rbio(SSL *ssl);
BIO *SSL_get_wbio(SSL *ssl);
int SSL_accept(SSL *ssl);
int SSL_connect(SSL *ssl);
void SSL_set_connect_state(SSL *ssl);
void SSL_set_accept_state(SSL *ssl);
int SSL_is_server(const SSL *ssl);
int SSL_do_handshake(SSL *ssl);
int SSL_shutdown(SSL *ssl);
int SSL_get_shutdown(const SSL *ssl);
int SSL_clear(SSL *ssl);
ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags);
int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written);
int SSL_write(SSL *ssl, const void *buf, int num);
int SSL_pending(const SSL *ssl);
int SSL_has_pending(const SSL *s);
int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes);
int SSL_read(SSL *ssl, void *buf, int num);
int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes);
int SSL_peek(SSL *ssl, void *buf, int num);
int SSL_get_error(const SSL *ssl, int ret);
这些SSL函数不包含socket的基础操作,必须跟系统的socket或BIO结合使用。
The behaviour of SSL_accept() depends on the underlying BIO.
If the underlying BIO is blocking, SSL_accept() will only return once the handshake has been finished or an error occurred.
If the underlying BIO is nonblocking, SSL_accept() will also return when the underlying BIO could not satisfy the needs of
SSL_accept() to continue the handshake, indicating the problem by the return value -1. In this case a call to SSL_get_error() with
the return value of SSL_accept() will yield SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. The calling process then must repeat the
call after taking appropriate action to satisfy the needs of SSL_accept(). The action depends on the underlying BIO. When using a
nonblocking socket, nothing is to be done, but select() can be used to check for the required condition. When using a buffering BIO,
like a BIO pair, data must be written into or retrieved out of the BIO before being able to continue.
#include <openssl/bio.h>
const BIO_METHOD *BIO_s_accept(void);
long BIO_set_accept_name(BIO *b, char *name);
char *BIO_get_accept_name(BIO *b);
long BIO_set_accept_port(BIO *b, char *port);
char *BIO_get_accept_port(BIO *b);
BIO *BIO_new_accept(char *host_port);
long BIO_set_nbio_accept(BIO *b, int n);
long BIO_set_accept_bios(BIO *b, char *bio);
char *BIO_get_peer_name(BIO *b);
char *BIO_get_peer_port(BIO *b);
long BIO_get_accept_ip_family(BIO *b);
long BIO_set_accept_ip_family(BIO *b, long family);
long BIO_set_bind_mode(BIO *b, long mode);
long BIO_get_bind_mode(BIO *b);
int BIO_do_accept(BIO *b);
注意:上述操作仅是socket操作,没有涉及SSL相关内容,要实现SSL通信,还需要结合以下SSL操作
#include <openssl/bio.h>
#include <openssl/ssl.h>
const BIO_METHOD *BIO_f_ssl(void);
long BIO_set_ssl(BIO *b, SSL *ssl, long c);
long BIO_get_ssl(BIO *b, SSL **sslp);
long BIO_set_ssl_mode(BIO *b, long client);
long BIO_set_ssl_renegotiate_bytes(BIO *b, long num);
long BIO_set_ssl_renegotiate_timeout(BIO *b, long seconds);
long BIO_get_num_renegotiates(BIO *b);
BIO *BIO_new_ssl(SSL_CTX *ctx, int client);
BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
int BIO_ssl_copy_session_id(BIO *to, BIO *from);
void BIO_ssl_shutdown(BIO *bio);
long BIO_do_handshake(BIO *b);
在非阻塞模式下,操作无法立即完成时会返回错误,应用需要判断是需要重试还是真的有错误,判断是否需要重试、重试的原因和重试的操作:
int BIO_should_read(BIO *b);
int BIO_should_write(BIO *b);
int BIO_should_io_special(iBIO *b);
int BIO_retry_type(BIO *b);
int BIO_should_retry(BIO *b);
BIO *BIO_get_retry_BIO(BIO *bio, int *reason);
int BIO_get_retry_reason(BIO *bio);
void BIO_set_retry_reason(BIO *bio, int reason);
设置非阻塞模式:long BIO_set_nbio_accept(BIO *b, int n);
If the underlying accept socket is nonblocking and BIO_do_accept() is called to await an incoming connection it is possible for
BIO_should_io_special() with the reason BIO_RR_ACCEPT. If this happens then it is an indication that an accept attempt would block:
the application should take appropriate action to wait until the underlying socket has accepted a connection and retry the call.
如果accept socket是非阻塞模式,调用BIO_do_accept来等待连接,当前没有连接时会返回错误,BIO_should_retry会返回true,说明操作需要重试,BIO_should_io_special会返回true并且BIO_get_retry_reason会返回 BIO_RR_ACCEPT,这种情况说明accept操作需要阻塞等待,应用程序应该等待直到底层socket接受一个连接后再重试BIO_do_accept。等待可用使用select/poll/epoll来实现。
BIO * in = BIO_new(BIO_s_accept());
BIO_set_accept_name(in, port)
int fd = accept();
BIO* conn_io = BIO_new_fd(fd, 1);
ssl_io = BIO_dup_chain(ssl_bio);
BIO_push(ssl_io, conn_io);
文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大
文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码
文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版
文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗
文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程
文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0
文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader
文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型
文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写
文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录
文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点
文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文