openssl3.2 - exp - buf to bio

文章目录

    • openssl3.2 - exp - buf to bio
    • 概述
    • 笔记
    • bio_get_length
      • 调用端代码
      • 函数实现
      • bio_to_buffer
    • END

openssl3.2 - exp - buf to bio

概述

不想让程序调用openssl API时, 有文件落地的动作.
如果程序有配置文件要用, 也是自己读文件到buffer, 然后转成BIO给openssl的相关有BIO入参的API用.
如果在程序中用数组定义了一些PEM内容的数组, 也可以将数组转成BIO来用.

从openssl测试代码中, 找到了BIO_new_mem_buf(), 可以做这个事情.
那么程序需要的文件输入, 都可以读入buffer, 转成BIO, 后续都用BIO来处理.

笔记

/*!
* \file main.cpp
* \note buffer to bio
*/#include "my_openSSL_lib.h"#include <stdlib.h>
#include <stdio.h>
#include <cstdint>
#include <assert.h>#include <openssl/bio.h>int test_bio_new_mem_buf(void);int main(int argc, char** argv)
{test_bio_new_mem_buf();return 0;
}int test_bio_new_mem_buf(void)
{int ok = 0;BIO* bio = NULL;BUF_MEM* bufmem = NULL;char data[16];int i_rc = 0;do {// BIO_free(bio); // openssl做了处理, 即使入参为NULL, 也不会报错// BIO_new_mem_buf是直接将入参的buffer指到内部指针上, 所以入参指针如果是自己new出来的, 就需要自己释放// 如果是文件输入, 可以自己读文件到buffer中, 然后就用BIO来操作.bio = BIO_new_mem_buf("Hello World\n", 12);if (NULL == bio){break; }i_rc = BIO_get_mem_ptr(bio, &bufmem);if (i_rc <= 0){break;}memset(data, 0, sizeof(data));if (5 != BIO_read(bio, data, 5)) { break; }if (0 != strncmp(data, "Hello", 5)){break;}// b->flags & BIO_FLAGS_MEM_RDONLY// bio默认是只读的, 是写不进去的.i_rc = BIO_write(bio, "test", 4);assert(i_rc <= 0);memset(data, 0, sizeof(data));i_rc = BIO_read(bio, data, 16); // 连续调用BIO_read时, 是继续往后读, 读一点, 内容就少一点assert(7 == i_rc); // 返回值是读了多少个字节if (0 != strncmp(data, " World\n", 7)){break;}i_rc = BIO_reset(bio); // 只读的bio可以恢复到刚创建时的状态, 可以从头开始读.assert(i_rc > 0);i_rc = BIO_read(bio, data, 16);assert(12 == i_rc);if (0 != strncmp(data, "Hello World\n", 12)){break;}ok = 1;} while (false);if (NULL != bio){BIO_free_all(bio);bio = NULL;}return ok;
}

bio_get_length

openssl 并不提供如何得到BIO对象内容的size.
因为很多BIO是不知道有多长的(e.g. bio for ssl)
但是对于由buffer转成BIO之后, 其实BIO内的数据长度是确定的.
翻翻openssl实现, 感觉也就只能通过试读来确定BIO的数据长度.
封装了一个函数bio_get_length(), 好使.

调用端代码

        // 如果是文件输入, 可以自己读文件到buffer中, 然后就用BIO来操作.bio = BIO_new_mem_buf("Hello World\n", 12);if (NULL == bio){break; }bio_length = bio_get_length(bio);assert(bio_length == 12);

函数实现

long bio_get_length(BIO* bio)
{long bio_length = 0;uint8_t* pBuf = NULL;int buf_len = 1024 * 1024;int i_rc = 0;// 只适合与已经全部装载了mem buffer内容的BIO// 因为 BIO_BUF_MEM 没有对外, 所以只能通过试读来确定BIO内容的长度do {if (NULL == bio){break;}pBuf = (uint8_t*)OPENSSL_malloc(buf_len);if (NULL == pBuf){break;}BIO_reset(bio);do {i_rc = BIO_read(bio, pBuf, buf_len);if (i_rc <= 0){break;}bio_length += i_rc;if (i_rc != buf_len){break;}} while (true);BIO_reset(bio);} while (false);if (NULL != pBuf){OPENSSL_free(pBuf);pBuf = NULL;}return bio_length;
}

bio_to_buffer

如果想对一个已经包含了内容的BIO中的内容, 转为buffer. 以下代码好使.

int test_bio_to_buffer(void)
{int ok = 0;BIO* bio = NULL;char data[16];int i_rc = 0;long bio_length = 0;uint8_t* pBufToLoadBIO = NULL;do {bio = BIO_new_mem_buf("Hello World\n", 12);if (NULL == bio){break;}// 得到BIO的数据长度, 才好去开bufferbio_length = bio_get_length(bio);assert(bio_length == 12);// 多开一个字节, 留一个'\0'的位置, 如果内容是可见字符, 看字符串方便pBufToLoadBIO = new uint8_t[bio_length + 1];if (NULL == pBufToLoadBIO){break;}pBufToLoadBIO[bio_length] = '\0';i_rc = BIO_read(bio, pBufToLoadBIO, bio_length);// 如果 bio_length 太大(> imax), 再分段读来处理, 现在先这样, 就当一次就读完了assert(i_rc == bio_length);// 现在可以拿pBufToLoadBIO去干活了(自己存文件, 或作其他处理)ok = 1;} while (false);if (NULL != bio){BIO_free_all(bio);bio = NULL;}if (NULL != pBufToLoadBIO){delete []pBufToLoadBIO;pBufToLoadBIO = NULL;}return ok;
}

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/705628.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3学习——路由prop配置、replace

写法一 在路由中可直接写prop: true&#xff0c;即可在页面中defineProps使用 相当于&#xff08;<Detail id“1” name“2” />&#xff09;,但只能是params {path: /service,name: 服务,component: () > import(../views/Service/index)&#xff0c;props: true}…

SQLlabs46关

看看源码 最终我们的id是放到order by后面了 如果我们直接用列去排序 ?sortusername/password username&#xff1a; passward 可以看到顺序是不同的&#xff0c;当然第一列第二列第三列也可以&#xff0c;基本上都是这个原理&#xff0c;那怎么去实现注入呢&#xff0c;我…

TypeScript与JavaScript 的区别

TypeScript 与 JavaScript 的区别&#xff1a; TypeScript Microsoft 在编译期间可以检查和修复错误 强类型&#xff0c;支持静态和动态类型 将代码转换为JavaScript&#xff0c;需要编译 支持模块、泛型、接口 没有庞大的开发人员社区 .ts和.tsx JavaScript Netscape&…

本地复制文本无法在Ubuntu终端中粘贴问题

在公司&#xff0c;安装Ubuntu环境后无法粘贴。 查询并自己实践后&#xff0c;解决方法如下&#xff1a; 1. sudo apt-get autoremove open-vm-tools 2. sudo apt-get install open-vm-tools-desktop 3.重启虚拟机 又可以愉快的复制粘贴了

【GPTs分享】GPTs分享之Write For Me

Write For Me 是一个专门定制的GPT版本&#xff0c;旨在为用户提供高质量的文本内容创作服务。它适用于各种写作需求&#xff0c;从商业计划、学术文章到创意故事等。下面是从简介、主要功能、使用案例、优点和局限性几个方面对Write For Me 的详细介绍。 简介 Write For Me …

Java 学习和实践笔记(22):package(包机制)、JDK常见的包、类的导入

前面学的类&#xff0c;每创建一个类&#xff0c;在电脑上就是创建了一个对应的类文件。而package 相当于文件夹对文件的管理作用。主要用于管理类、用于解决类的重名问题。这个含义很简单。因为实际的程序&#xff0c;类可能有成千上万个&#xff0c;这样就需要把不同功能的类…

「连载」边缘计算(十九)02-22:边缘部分源码(源码分析篇)

&#xff08;接上篇&#xff09; 从启动函数Start(&#xff09;中可以看到&#xff0c;其以go routine的方式启动很多后台处理服务&#xff0c;具体如下。 1&#xff09;初始化edged的kubeClient&#xff0c;具体如下所示。 // use self defined client to replace fake kube…

JDK5.0新增线程的两种方式

本文主要是了解&#xff0c;并没有进入深入学习&#xff0c;JUC时才会深入学习 8.1新增方式一&#xff1a;实现Callable接口 ~与使用Runable相比&#xff0c;Callable功能更强大些 -- 相比run&#xff08;&#xff09;方法&#xff0c;可以有返回值 ---方法可以抛出异常 -…

LeetCode刷题--- 环形子数组的最大和

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 ​​​​​​http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述动…

CSDN的AI创作助手

CSDN用到的AI创作助手详细介绍 CSDN&#xff08;中国软件开发者网&#xff09;是一个面向IT技术人员的综合性技术社区&#xff0c;提供技术问答、博客文章、开发工具等内容。AI创作助手是CSDN提供的一项人工智能服务&#xff0c;旨在帮助用户快速高效地创作文章。 AI创作助手基…

设计模式(十) - 工厂方式模式

前言 在此前的设计模式&#xff08;四&#xff09;简单工厂模式中我们介绍了简单工厂模式&#xff0c;在这篇文章中我们来介绍下工厂方法模式&#xff0c;它同样是创建型设计模式&#xff0c;而且又有些类似&#xff0c;文章的末尾会介绍他们之间的不同。 1.工厂方法模式简介 …

C# TesseractOCR识别身份证号

https://github.com/tesseract-ocr/tessdata 新建控制台项目并添加包 Tesseract和Tesseract.Drawing 下载训练的模型 地址 代码实现 using Tesseract;var filePath "F:\\Desktop\\韦小宝.png"; var exePath AppDomain.CurrentDomain.BaseDirectory; var …

机器视觉运动控制一体机在光伏汇流焊机器人系统的解决方案

一、市场应用背景 汇流焊是光伏太阳能电池板中段加工工艺&#xff0c;其前道工序为串焊&#xff0c;在此环节流程中&#xff0c;需要在多个太阳能电池片表面以平行方式串焊多条焊带&#xff0c;形成电池串。串焊好的多组电池串被有序排列输送到汇流焊接工作台&#xff0c;通过…

接受回调函数的函数

直接上代码 const oneWord function (str) {return str.replace(/ /g, ).toLowerCase(); };const upperFirstWorld function (str) {const [first, ...others] str.split( );return [first.toUpperCase(), ...others].join( ); };// 高阶函数 const transformer function …

SQL进阶(二):复杂数据结构处理:让你的 SQL 更加高效

复杂数据结构处理&#xff1a;让你的 SQL 更加高效&#xff0c;以SQLite为例 本文是在原本sql闯关的基础上总结得来&#xff0c;加入了自己的理解以及疑问解答&#xff08;by GPT4&#xff09; 原活动链接 用到的数据&#xff1a;链接 提取码&#xff1a;l03e 目录 0.课前小问…

git基础命令详解(全网最详细教程-本地仓库和远程仓库分开详细讲解)

1.git本地仓库操作 1.1什么是本地仓库 本地仓库位于本地工作区的隐藏目录 .git中,它包含了项目的完整历史记录和所有版本的文件; .git不算工作区,而是 Git 的版本库。 1.2本地仓库常用命令汇总 命令作用备注git init 初始化本地Git仓库(项目) 会在当前目录中创建—个.…

深度学习 精选笔记(3)线性神经网络-线性回归

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

workon把pyhton环境切换为python3.7环境配置

重新创建虚拟环境 创建workon的虚拟环境&#xff08;注意修改中文&#xff09; 注&#xff1a;-p后面的路径为你需要的python版本的python.exe执行文件 mkvirtualenv -p C:\Users\用户名\AppData\Local\Programs\Python\Python37\Python.exe 环境名进入环境&#xff08;注意…

代码随想录Day63 |503.下一个更大元素II 42. 接雨水

代码随想录Day63 |503.下一个更大元素II 42. 接雨水 503.下一个更大元素II42.接雨水双指针单调栈 503.下一个更大元素II 文档讲解&#xff1a;代码随想录 视频讲解&#xff1a; 单调栈&#xff0c;成环了可怎么办&#xff1f;LeetCode&#xff1a;503.下一个更大元素II 状态 单…

基于Java SSM框架实现高考填报信息系统项目【项目源码】计算机毕业设计

基于java的SSM框架实现高考填报信息系统演示 JAVA简介 Java主要采用CORBA技术和安全模型&#xff0c;可以在互联网应用的数据保护。它还提供了对EJB&#xff08;Enterprise JavaBeans&#xff09;的全面支持&#xff0c;java servlet API&#xff0c;JSP&#xff08;java serv…