实现excel报表文件生成功能

This commit is contained in:
lixiaoyuan
2025-09-20 16:41:08 +08:00
parent 0a71d7e61a
commit ee98556eec
114 changed files with 15206 additions and 55 deletions

View File

@@ -2,8 +2,8 @@
"debug":0,
"launchdate": "2025-09-01",
"weburl": "http://127.0.0.1:19601/",
"exportpath": "D:/Programs/openresty-1.27.1.1-win64/zdownload",
"database": {"host": "localhost", "port": 3306, "user": "root", "passwd": "123456", "dbname": "ess"},
"http": {"token":0, "port": 19801, "encryption":0, "encryptKey":""},
"mqtt": {"host":"mqtt://43.136.119.46:6203","username":"jsyhsec","password":"123456"},
"topic": {

BIN
bin/Release/gmssl.dll Normal file

Binary file not shown.

View File

@@ -69,6 +69,8 @@ include_directories(
${THIRDPARTY_PATH}/cpp-httplib-0.25.0
${THIRDPARTY_PATH}/paho_mqtt/include
${THIRDPARTY_PATH}/spdlog-1.13.0/include
${THIRDPARTY_PATH}/OpenXLSX/include
${THIRDPARTY_PATH}/GmSSL-3.1.1/include
#${PVLIBS_PATH}/include/pvserver
#${PVLIBS_PATH}/include/rllib
)
@@ -104,6 +106,8 @@ target_link_libraries(${PROJECT_NAME}
${THIRDPARTY_PATH}/mysql/lib/x64/libmysql.lib
${THIRDPARTY_PATH}/paho_mqtt/lib/paho-mqtt3a.lib
${THIRDPARTY_PATH}/paho_mqtt/lib/paho-mqtt3c.lib
${THIRDPARTY_PATH}/OpenXLSX/lib/OpenXLSX.lib
${THIRDPARTY_PATH}/GmSSL-3.1.1/lib/gmssl.lib
#${PVLIBS_PATH}/x64/serverlib.lib
#${PVLIBS_PATH}/x64/rllib.lib

View File

@@ -23,7 +23,7 @@ bool Config::init(std::string filename)
JSON::read(jsonroot, "debug", option.debug);
JSON::read(jsonroot, "weburl", option.webSrvUrl);
JSON::read(jsonroot, "launchdate", option.lunchDate);
JSON::read(jsonroot, "exportpath", option.exportpath);
if (jsonroot.contains("database"))
{

View File

@@ -8,6 +8,7 @@ struct AppOption
int debug {0};
std::string webSrvUrl;
std::string lunchDate;
std::string exportpath;
struct {
std::string host;

View File

@@ -148,4 +148,28 @@ string Crypto::md5(string src)
md5_encode(num, 16, tempA, tempB, tempC, tempD);
}
return md5_format(tempA) + md5_format(tempB) + md5_format(tempC) + md5_format(tempD);
}
std::vector<uint8_t> Crypto::sm4EcbEncrypt(const std::vector<uint8_t>& key, const std::vector<uint8_t>& plaintext)
{
SM4_KEY sm4_key;
std::vector<uint8_t> ciphertext(plaintext.size()); // ECB模式密文长度与明文相同需填充时另说
sm4_set_encrypt_key(&sm4_key, key.data());
// 假设明文已是分组整数倍或已处理填充
for (size_t i = 0; i < plaintext.size(); i += 16) {
sm4_encrypt(&sm4_key, &plaintext[i], &ciphertext[i]);
}
return ciphertext;
}
std::vector<uint8_t> Crypto::sm4EcbDecrypt(const std::vector<uint8_t>& key, const std::vector<uint8_t>& ciphertext) {
SM4_KEY sm4_key;
std::vector<uint8_t> plaintext(ciphertext.size());
sm4_set_decrypt_key(&sm4_key, key.data());
for (size_t i = 0; i < ciphertext.size(); i += 16) {
sm4_encrypt(&sm4_key, &ciphertext[i], &plaintext[i]); // 注意解密时也是用sm4_encrypt函数但密钥是解密密钥
}
return plaintext;
}

View File

@@ -1,4 +1,4 @@
#ifndef _Crypto_H_
#ifndef _Crypto_H_
#define _Crypto_H_
@@ -6,6 +6,9 @@
#include <vector>
#include <cstdlib>
#include <string>
#include <gmssl/sm4.h>
#include <gmssl/hex.h>
#include <gmssl/sm2.h>
using namespace std;
@@ -15,6 +18,21 @@ class Crypto
public:
static string md5(string src);
/**
* @brief SM4-ECB 加密示例
* @param key 16字节密钥
* @param plaintext 明文数据
* @return 密文字节向量
*/
static std::vector<uint8_t> sm4EcbEncrypt(const std::vector<uint8_t>& key, const std::vector<uint8_t>& plaintext);
/**
* @brief SM4-ECB 解密示例
* @param key 16字节密钥
* @param ciphertext 密文数据
* @return 明文字节向量
*/
static std::vector<uint8_t> sm4EcbDecrypt(const std::vector<uint8_t>& key, const std::vector<uint8_t>& ciphertext);
};
#endif // ! _Crypto_H_

31
src/common/XlsxEntity.cpp Normal file
View File

@@ -0,0 +1,31 @@
#include "XlsxEntity.h"
XlsxEntity::XlsxEntity(std::string filename)
{
xldom_.create(filename);
sheet_ = xldom_.workbook().worksheet("Sheet1");
}
XlsxEntity::~XlsxEntity()
{
this->close();
}
void XlsxEntity::setCell(std::string index, std::string v)
{
sheet_.cell(XLCellReference(index)).value() = v;
}
void XlsxEntity::setCell(int row, int col, std::string v)
{
sheet_.cell(row, col).value() = v;
}
void XlsxEntity::close()
{
if (xldom_.isOpen())
{
xldom_.save();
xldom_.close();
}
}

26
src/common/XlsxEntity.h Normal file
View File

@@ -0,0 +1,26 @@
#pragma once
#include "OpenXLSX.hpp"
#include <string>
using namespace OpenXLSX;
class XlsxEntity
{
public:
XlsxEntity(std::string filename);
~XlsxEntity();
/**
* @param [string index] 单元格索引,例如 A1, D6
*/
void setCell(std::string index, std::string v);
void setCell(int row, int col, std::string v);
void close();
private:
XLWorksheet sheet_;
XLDocument xldom_;
};

View File

@@ -29,25 +29,8 @@
#include "qt/MainWeb.h"
//#define wsa rlwsa
//void rlSocketTest()
//{
// rlwsa();
// rlSocket socket("127.0.0.1", 19801, 1);
// int ret = socket.connect();
// std::string s1 = "helloworld";
// socket.write(s1.c_str(), s1.size());
//
// std::vector<char> buf(1024, 0);
// while (true)
// {
// int len = socket.read(&buf[0], 1, 0);
// if (len > 0)
// {
// std::cout << "===>>> " << std::string(buf.begin(), buf.end());
// }
// }
//}
#include "database/Dao.h"
#include "common/XlsxEntity.h"
void memberJsonTest()
{
@@ -117,8 +100,27 @@ void memberJsonTest()
//std::cout << to << std::endl;
}
#include "common/Crypto.h"
int main(int argc, char** argv)
{
// 示例密钥 (16字节)
std::string key = "1234567890123456";
// 示例明文 (必须是16字节的整数倍本例为16字节)
std::string plaintext = "HelloWorld";
// 加密
auto encryptText = Crypto::sm4EcbEncrypt(vector<uint8_t>(key.begin(), key.end()), vector<uint8_t>(plaintext.begin(), plaintext.end()));
// 解密
auto decryptText = Crypto::sm4EcbDecrypt(vector<uint8_t>(key.begin(), key.end()), encryptText);
// 输出十六进制结果
std::cout << "Original: " << plaintext << std::endl;
std::cout << "Encrypted: " << std::string(encryptText.begin(), encryptText.end()) << std::endl;
std::cout << "Decrypted: " << std::string(decryptText.begin(), decryptText.end()) << std::endl;
// 设置控制台输出为 UTF-8 编码
SetConsoleOutputCP(CP_UTF8);
// 设置控制台输入为 UTF-8 编码(如果需要输入中文)
@@ -131,8 +133,6 @@ int main(int argc, char** argv)
// 运行后台服务
Application::instance().init();
while (1) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); };
// 启动 PV 服务主线程

View File

@@ -8,6 +8,7 @@
#include "app/Config.h"
#include "app/Station.h"
#include "app/Device.h"
#include "common/XlsxEntity.h"
static void FieldsToJson(Fields& fields, njson& json)
{
@@ -46,7 +47,6 @@ static void JsonToFields(njson& json, std::vector<std::string> vecKeys, Fields&
default:
break;
}
}
}
}
@@ -66,7 +66,7 @@ static njson FieldsToJsonArray(std::vector<Fields>& vecFields)
return jsonnode;
}
static void GetRequestParam(const httplib::Request& req, const std::vector<std::string>& vecKeys, Fields& fields)
static void GetRequestParams(const httplib::Request& req, const std::vector<std::string>& vecKeys, Fields& fields)
{
if (req.method == "GET")
{
@@ -86,6 +86,18 @@ static void GetRequestParam(const httplib::Request& req, const std::vector<std::
}
}
static void CheckRequiredParams(Fields& params, std::vector<std::string> keys, std::string& errmsg)
{
for (auto& key : keys)
{
if (!params.contains(key))
{
errmsg = "参数[" + key + "]错误";;
return;
}
}
}
class HttpHelper
{
public:
@@ -172,9 +184,9 @@ static std::map<std::string, HandlerOptions> g_mapHttpHandlerGet =
{"/queryStatDayList", HandlerOptions(&HttpEntity::queryStatDayList, {})},
{"/queryStatDetailList", HandlerOptions(&HttpEntity::queryStatDetailList, {})},
{"/queryStatCharts", HandlerOptions(&HttpEntity::queryStatCharts, {})},
{"/queryEnvironment", HandlerOptions(&HttpEntity::queryEnvironment, { "station_id"})},
{"/exportStatReport", HandlerOptions(&HttpEntity::exportStatReport, {})},
{"/queryEnvironment", HandlerOptions(&HttpEntity::queryEnvironment, { "station_id"})},
{"/queryServiceApiList", HandlerOptions(&HttpEntity::queryServiceApiList, {})},
{"/deleteServiceApi", HandlerOptions(&HttpEntity::deleteServiceApi, {"api_id"})},
@@ -381,14 +393,14 @@ Errcode HttpEntity::queryUserList(const httplib::Request& req, njson& json, std:
Errcode HttpEntity::insertUser(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"account", "name", "gender", "age", "phone", "email", "role_id"}, params);
GetRequestParams(req, {"account", "name", "gender", "age", "phone", "email", "role_id"}, params);
return DAO::insertUser(params);
}
Errcode HttpEntity::updateUser(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"user_id", "account", "name", "gender", "age", "phone", "email", "role_id"}, params);
GetRequestParams(req, {"user_id", "account", "name", "gender", "age", "phone", "email", "role_id"}, params);
return DAO::updateUserById(params);
}
@@ -445,14 +457,14 @@ Errcode HttpEntity::queryPermissionList(const httplib::Request& req, njson& json
Errcode HttpEntity::insertPermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"name", "describe", "is_open"}, params);
GetRequestParams(req, {"name", "describe", "is_open"}, params);
return DAO::insertPermission(params);
}
Errcode HttpEntity::updatePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"permission_id", "name", "describe", "is_open"}, params);
GetRequestParams(req, {"permission_id", "name", "describe", "is_open"}, params);
return DAO::updatePermissionById(params);
}
@@ -540,7 +552,7 @@ Errcode HttpEntity::queryRoleList(const httplib::Request& req, njson& json, std:
Errcode HttpEntity::queryRolePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"role_id"}, params);
GetRequestParams(req, {"role_id"}, params);
if (!params.contains("role_id")) { errmsg = "缺少参数[role_id]"; return Errcode::ERR_PARAM; }
return Errcode::OK;
}
@@ -548,13 +560,13 @@ Errcode HttpEntity::queryRolePermission(const httplib::Request& req, njson& json
Errcode HttpEntity::insertRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"name", "describe", "is_open", "permission"}, params);
GetRequestParams(req, {"name", "describe", "is_open", "permission"}, params);
return DAO::insertRole(params);
};
Errcode HttpEntity::updateRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"role_id", "name", "describe", "is_open", "permission"}, params);
GetRequestParams(req, {"role_id", "name", "describe", "is_open", "permission"}, params);
auto roleId = params.value("role_id");
std::string permission = params.remove("permission");
@@ -610,14 +622,14 @@ Errcode HttpEntity::insertStation(const httplib::Request& req, njson& json, std:
{
Fields params;
GetRequestParam(req, {"name", "address", "lon", "lat", "tel", "capacity", "status"}, params);
GetRequestParams(req, {"name", "address", "lon", "lat", "tel", "capacity", "status"}, params);
return DAO::insertStation(params);
};
Errcode HttpEntity::updateStation(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"station_id", "name", "address", "lon", "lat", "tel", "capacity", "status", "work_mode", "policy_id", "operation_date"}, params);
GetRequestParams(req, {"station_id", "name", "address", "lon", "lat", "tel", "capacity", "status", "work_mode", "policy_id", "operation_date"}, params);
std::string stationId = params.value("station_id");
params.check("capacity", "", "0.0");
params.check("lon", "", "0.0");
@@ -656,7 +668,7 @@ Errcode HttpEntity::deleteStation(const httplib::Request& req, njson& json, std:
Errcode HttpEntity::queryStationOverview(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"station_id"}, params);
GetRequestParams(req, {"station_id"}, params);
std::string stationId = params.value("station_id");
if (stationId.empty())
{
@@ -797,7 +809,7 @@ Errcode HttpEntity::queryDeviceList(const httplib::Request& req, njson& json, st
Errcode HttpEntity::insertDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
GetRequestParams(req, {"station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
Errcode err = DAO::insertDevice(params);
@@ -813,7 +825,7 @@ Errcode HttpEntity::insertDevice(const httplib::Request& req, njson& json, std::
Errcode HttpEntity::updateDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"device_id", "station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
GetRequestParams(req, {"device_id", "station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
Errcode err = DAO::updateDeviceById(params);
if (err == Errcode::OK)
@@ -840,7 +852,7 @@ Errcode HttpEntity::queryDevicTypeDef(const httplib::Request& req, njson& json,
Errcode HttpEntity::queryDevicByCategory(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"station_id", "category"}, params);
GetRequestParams(req, {"station_id", "category"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
if (!params.contains("category")) { errmsg = "缺少参数[category]"; return Errcode::ERR_PARAM; }
@@ -902,7 +914,7 @@ Errcode HttpEntity::queryDevicByCategory(const httplib::Request& req, njson& jso
Errcode HttpEntity::queryDevicCharts(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"station_id", "device_id"}, params);
GetRequestParams(req, {"station_id", "device_id"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
if (!params.contains("device_id")) { errmsg = "缺少参数[device_id]"; return Errcode::ERR_PARAM; }
@@ -924,7 +936,7 @@ Errcode HttpEntity::queryDevicCharts(const httplib::Request& req, njson& json, s
Errcode HttpEntity::queryDeviceBCUDetail(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"station_id", "device_id"}, params);
GetRequestParams(req, {"station_id", "device_id"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
if (!params.contains("device_id")) { errmsg = "缺少参数[device_id]"; return Errcode::ERR_PARAM; }
@@ -964,19 +976,19 @@ Errcode HttpEntity::queryPolicyList(const httplib::Request& req, njson& json, st
Errcode HttpEntity::insertPolicy(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"type", "name", "describe", "value", "is_open"}, params);
GetRequestParams(req, {"type", "name", "describe", "value", "is_open"}, params);
return DAO::insertPolicy(params);
};
Errcode HttpEntity::updatePolicy(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"policy_id", "type", "describe", "value", "is_open"}, params);
GetRequestParams(req, {"policy_id", "type", "describe", "value", "is_open"}, params);
return DAO::updatePolicyById(params);
};
Errcode HttpEntity::deletePolicy(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"policy_id"}, params);
GetRequestParams(req, {"policy_id"}, params);
return DAO::deletePolicyById(params.value("policy_id"));
};
Errcode HttpEntity::queryPolicyByType(const httplib::Request& req, njson& json, std::string& errmsg)
@@ -1004,7 +1016,7 @@ Errcode HttpEntity::querySystemLogList(const httplib::Request& req, njson& json,
Errcode HttpEntity::updateSystemLog(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"log_id", "status"}, params);
GetRequestParams(req, {"log_id", "status"}, params);
return DAO::updateSystemLogById(params);
}
@@ -1024,7 +1036,7 @@ Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, njson& json,
Errcode HttpEntity::updateAlertLog(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"log_id", "status"}, params);
GetRequestParams(req, {"log_id", "status"}, params);
return DAO::updateAlertLogById(params);
}
@@ -1159,7 +1171,7 @@ static std::string VerifyStatSqlCondition(Fields& params)
static std::string GetRequestStatParams(const httplib::Request& req, Fields& params)
{
GetRequestParam(req, {"station_id", "category", "start_date", "end_date"}, params);
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
VerifyRequstParamsStatDate(params);
return VerifyStatSqlCondition(params);
}
@@ -1226,7 +1238,7 @@ Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std
Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"station_id", "category", "start_date", "end_date"}, params);
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
std::string stationId = params.value("station_id");
std::string category = params.value("category");
std::string startDate = params.value("start_date");
@@ -1304,7 +1316,7 @@ Errcode HttpEntity::queryStatDetailList(const httplib::Request& req, njson& json
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
Fields params;
GetRequestParam(req, {"station_id", "category", "start_date", "end_date"}, params);
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
std::vector<Fields> result;
auto err = DAO::queryStatStationList(pageinfo, params, result);
@@ -1373,6 +1385,79 @@ Errcode HttpEntity::queryStatCharts(const httplib::Request& req, njson& json, st
return Errcode::OK;
}
Errcode HttpEntity::exportStatReport(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
CheckRequiredParams(params, {"station_id", "category", "start_date", "end_date"}, errmsg);
if (!errmsg.empty())
{
return Errcode::ERR_PARAM;
}
std::string stationId = params.value("station_id");
std::string category = params.value("category");
std::string startDate = params.value("start_date");
std::string endDate = params.value("end_date");
std::string sql = "SELECT s.name station_name, sd.* FROM stat_day sd LEFT JOIN station s ON sd.station_id=s.station_id";
" WHERE station_id = '" + stationId + "' AND category = '" + category + "'"
" AND dt BETWEEN '" + startDate + "' AND '" + endDate + "2025-09-19' AND sd.category = '1'";
std::string filename;
std::vector<Fields> result;
Errcode err = DAO::exec(NULL, sql, result);
if (result.size() > 0)
{
filename = "export_" + Utils::timeStr(0, "%Y%m%d%H%M%S") + ".xlsx";
XlsxEntity xlsx(Config::option.exportpath + "/" + filename);
std::vector<std::pair<std::string, std::string>> headers;
if (category == "1")
{
headers = {
{"日期", "dt"}, {"场站", "station_name"}, {"类别", "category"},
{"充电电量", "storage_elect_in"}, {"放电电量", "storage_elect_out"},
{"充电次数", "storage_num_in"}, {"放电次数", "storage_num_out"},
{"充电时长", "storage_t_in"}, {"放电时长", "storage_t_out"}
};
}
else if (category == "2")
{
headers = {
{"日期", "dt"}, {"场站", "station_name"}, {"类别", "category"},
{"充电电量", "charge_elect"}, {"充电次数", "charge_num"}, {"充电时长", "charge_t"}
};
}
else if (category == "3")
{
headers = {
{"日期", "dt"}, {"场站", "station_name"}, {"类别", "category"},
{"发电电量", "solar_elect_gen"}, {"入网电量", "solar_elect_grid"}, {"发电时长", "solar_t"},
};
}
for (int row = 0; row<result.size(); ++row)
{
auto& fields = result[row];
if (category == "1") { fields.value("category") = "储能设备"; }
else if (category == "2") { fields.value("category") = "充电设备"; }
else if (category == "3") { fields.value("category") = "发电设备"; }
for (int col = 0; col<headers.size(); ++col)
{
if (row == 0)
{
xlsx.setCell(row+1, col+1, headers[col].first);
}
xlsx.setCell(row+2, col+1, fields.value(headers[col].second));
}
}
xlsx.close();
}
json["data"] = filename;
return err;
}
Errcode HttpEntity::queryEnvironment(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string stationId = req.get_param_value("station_id");
@@ -1480,7 +1565,7 @@ Errcode HttpEntity::queryServiceApiList(const httplib::Request& req, njson& json
Errcode HttpEntity::insertServiceApi(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"name", "describe", "params", "is_open"}, params);
GetRequestParams(req, {"name", "describe", "params", "is_open"}, params);
if (params.size() == 0) { return Errcode::ERR_PARAM; }
return DAO::insert(NULL, "serviceapi", params);
@@ -1489,7 +1574,7 @@ Errcode HttpEntity::insertServiceApi(const httplib::Request& req, njson& json, s
Errcode HttpEntity::updateServiceApi(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"api_id", "name", "describe", "params", "is_open"}, params);
GetRequestParams(req, {"api_id", "name", "describe", "params", "is_open"}, params);
if (params.size() == 0) { return Errcode::ERR_PARAM; }
return DAO::update(NULL, "serviceapi", params, "api_id");
@@ -1498,6 +1583,6 @@ Errcode HttpEntity::updateServiceApi(const httplib::Request& req, njson& json, s
Errcode HttpEntity::deleteServiceApi(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"api_id"}, params);
GetRequestParams(req, {"api_id"}, params);
return DAO::remove(NULL, "serviceapi", "api_id", params.value("api_id"));
}

View File

@@ -99,6 +99,8 @@ public:
// 场站按类某一天的历史曲线数据
Errcode queryStatCharts(const httplib::Request& req, njson& json, std::string& errmsg);
Errcode exportStatReport(const httplib::Request& req, njson& json, std::string& errmsg);
Errcode queryEnvironment(const httplib::Request& req, njson& json, std::string& errmsg);
Errcode queryServiceApiList(const httplib::Request& req, njson& json, std::string& errmsg);

BIN
thirdparty/GmSSL-3.1.1/bin/gmssl.dll vendored Normal file

Binary file not shown.

BIN
thirdparty/GmSSL-3.1.1/bin/gmssl.exe vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,108 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_AEAD_H
#define GMSSL_AEAD_H
#include <string.h>
#include <stdint.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
#include <gmssl/gcm.h>
#include <gmssl/api.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
SM4_CBC_CTX enc_ctx;
SM3_HMAC_CTX mac_ctx;
uint8_t mac[SM3_HMAC_SIZE];
size_t maclen;
} SM4_CBC_SM3_HMAC_CTX;
#define SM4_CBC_SM3_HMAC_KEY_SIZE 48
#define SM4_CBC_SM3_HMAC_IV_SIZE 16
_gmssl_export int sm4_cbc_sm3_hmac_encrypt_init(SM4_CBC_SM3_HMAC_CTX *ctx,
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen);
_gmssl_export int sm4_cbc_sm3_hmac_encrypt_update(SM4_CBC_SM3_HMAC_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
_gmssl_export int sm4_cbc_sm3_hmac_encrypt_finish(SM4_CBC_SM3_HMAC_CTX *ctx,
uint8_t *out, size_t *outlen);
_gmssl_export int sm4_cbc_sm3_hmac_decrypt_init(SM4_CBC_SM3_HMAC_CTX *ctx,
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen);
_gmssl_export int sm4_cbc_sm3_hmac_decrypt_update(SM4_CBC_SM3_HMAC_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
_gmssl_export int sm4_cbc_sm3_hmac_decrypt_finish(SM4_CBC_SM3_HMAC_CTX *ctx,
uint8_t *out, size_t *outlen);
typedef struct {
SM4_CTR_CTX enc_ctx;
SM3_HMAC_CTX mac_ctx;
uint8_t mac[SM3_HMAC_SIZE];
size_t maclen;
} SM4_CTR_SM3_HMAC_CTX;
#define SM4_CTR_SM3_HMAC_KEY_SIZE 48
#define SM4_CTR_SM3_HMAC_IV_SIZE 16
_gmssl_export int sm4_ctr_sm3_hmac_encrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx,
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen);
_gmssl_export int sm4_ctr_sm3_hmac_encrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
_gmssl_export int sm4_ctr_sm3_hmac_encrypt_finish(SM4_CTR_SM3_HMAC_CTX *ctx,
uint8_t *out, size_t *outlen);
_gmssl_export int sm4_ctr_sm3_hmac_decrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx,
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen);
_gmssl_export int sm4_ctr_sm3_hmac_decrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
_gmssl_export int sm4_ctr_sm3_hmac_decrypt_finish(SM4_CTR_SM3_HMAC_CTX *ctx,
uint8_t *out, size_t *outlen);
typedef struct {
SM4_CTR_CTX enc_ctx;
GHASH_CTX mac_ctx;
uint8_t Y[16]; // E(K, Y_0)
size_t taglen;
uint8_t mac[16];
size_t maclen;
} SM4_GCM_CTX;
#define SM4_GCM_KEY_SIZE 16
#define SM4_GCM_DEFAULT_TAG_SIZE 16
_gmssl_export int sm4_gcm_encrypt_init(SM4_GCM_CTX *ctx,
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, size_t taglen);
_gmssl_export int sm4_gcm_encrypt_update(SM4_GCM_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
_gmssl_export int sm4_gcm_encrypt_finish(SM4_GCM_CTX *ctx,
uint8_t *out, size_t *outlen);
_gmssl_export int sm4_gcm_decrypt_init(SM4_GCM_CTX *ctx,
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, size_t taglen);
_gmssl_export int sm4_gcm_decrypt_update(SM4_GCM_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
_gmssl_export int sm4_gcm_decrypt_finish(SM4_GCM_CTX *ctx,
uint8_t *out, size_t *outlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,90 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_AES_H
#define GMSSL_AES_H
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#define AES128_KEY_BITS 128
#define AES192_KEY_BITS 192
#define AES256_KEY_BITS 256
#define AES128_KEY_SIZE (AES128_KEY_BITS/8)
#define AES192_KEY_SIZE (AES192_KEY_BITS/8)
#define AES256_KEY_SIZE (AES256_KEY_BITS/8)
#define AES_BLOCK_SIZE 16
#define AES128_ROUNDS 10
#define AES192_ROUNDS 12
#define AES256_ROUNDS 14
#define AES_MAX_ROUNDS AES256_ROUNDS
typedef struct {
uint32_t rk[4 * (AES_MAX_ROUNDS + 1)];
size_t rounds;
} AES_KEY;
int aes_set_encrypt_key(AES_KEY *key, const uint8_t *raw_key, size_t raw_key_len);
int aes_set_decrypt_key(AES_KEY *key, const uint8_t *raw_key, size_t raw_key_len);
void aes_encrypt(const AES_KEY *key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]);
void aes_decrypt(const AES_KEY *key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]);
void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE],
const uint8_t *in, size_t nblocks, uint8_t *out);
void aes_cbc_decrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE],
const uint8_t *in, size_t nblocks, uint8_t *out);
int aes_cbc_padding_encrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE],
const uint8_t *in, size_t inlen,
uint8_t *out, size_t *outlen);
int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE],
const uint8_t *in, size_t inlen,
uint8_t *out, size_t *outlen);
void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[AES_BLOCK_SIZE],
const uint8_t *in, size_t inlen, uint8_t *out);
#define aes_ctr_decrypt(key,ctr,in,inlen,out) aes_ctr_encrypt(key,ctr,in,inlen,out)
#define AES_GCM_IV_MIN_SIZE 1
#define AES_GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3)))
#define AES_GCM_IV_DEFAULT_BITS 96
#define AES_GCM_IV_DEFAULT_SIZE 12
#define AES_GCM_MIN_AAD_SIZE 0
#define AES_GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3)))
#define AES_GCM_MIN_PLAINTEXT_SIZE 0
#define AES_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3)
#define AES_GCM_MAX_TAG_SIZE 16
int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
uint8_t *out, size_t taglen, uint8_t *tag);
int aes_gcm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
const uint8_t *tag, size_t taglen, uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,23 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_API_H
#define GMSSL_API_H
#ifdef WIN32
#define _gmssl_export __declspec(dllexport)
#elif defined(__GNUC__)
// use -fvisibility=hidden to change the "default" behavior
#define _gmssl_export __attribute__((visibility("default")))
#else
#define _gmssl_export
#endif
#endif

View File

@@ -0,0 +1,301 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_ASN1_H
#define GMSSL_ASN1_H
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
#if __cplusplus
extern "C" {
#endif
#define ASN1_TAG_UNIVERSAL 0x00
#define ASN1_TAG_APPLICATION 0x40
#define ASN1_TAG_CONTENT_SPECIFIC 0x80
#define ASN1_TAG_PRIVATE 0xC0
#define ASN1_TAG_PRIMITIVE 0x00
#define ASN1_TAG_CONSTRUCTED 0x20
#define ASN1_TAG_IMPLICIT(index) (ASN1_TAG_CONTENT_SPECIFIC|(index))
#define ASN1_TAG_EXPLICIT(index) ASN1_TAG_IMPLICIT(ASN1_TAG_CONSTRUCTED|(index))
#define ASN1_FMT_FULL 0x01
enum ASN1_TAG {
ASN1_TAG_BOOLEAN = 1,
ASN1_TAG_INTEGER = 2,
ASN1_TAG_BIT_STRING = 3,
ASN1_TAG_OCTET_STRING = 4,
ASN1_TAG_NULL = 5,
ASN1_TAG_OBJECT_IDENTIFIER = 6,
ASN1_TAG_ObjectDescriptor = 7,
ASN1_TAG_EXTERNAL = 8,
ASN1_TAG_REAL = 9,
ASN1_TAG_ENUMERATED = 10, // 0x0A
ASN1_TAG_EMBEDDED = 11, // 0x0B
ASN1_TAG_UTF8String = 12, // 0x0C
ASN1_TAG_RELATIVE_OID = 13, // 0x0D
ASN1_TAG_NumericString = 18, // 0x12
ASN1_TAG_PrintableString = 19, // 0x13, printable subset of ascii
ASN1_TAG_TeletexString = 20, // 0x14, T61String
ASN1_TAG_VideotexString = 21, // 0x15
ASN1_TAG_IA5String = 22, // 0x16, 7-bit ascii
ASN1_TAG_UTCTime = 23, // 0x17
ASN1_TAG_GeneralizedTime = 24, // 0x18
ASN1_TAG_GraphicString = 25, // 0x19
ASN1_TAG_VisibleString = 26, // 0x20
ASN1_TAG_GeneralString = 27, // 0x21
ASN1_TAG_UniversalString = 28, // 0x22
ASN1_TAG_CHARACTER_STRING = 29, // 0x23
ASN1_TAG_BMPString = 30, // 0x24, 2-byte unicode with zeros
ASN1_TAG_SEQUENCE = 0x30,
ASN1_TAG_SET = 0x31,
ASN1_TAG_EXPLICIT = 0xa0,
};
const char *asn1_tag_name(int tag);
int asn1_tag_is_cstring(int tag);
int asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen);
int asn1_tag_from_der(int *tag, const uint8_t **in, size_t *inlen);
int asn1_tag_from_der_readonly(int *tag, const uint8_t **in, size_t *inlen); // read the next tag without changing *in,*inlen
int asn1_length_to_der(size_t dlen, uint8_t **out, size_t *outlen);
int asn1_length_from_der(size_t *dlen, const uint8_t **in, size_t *inlen);
int asn1_length_is_zero(size_t len);
int asn1_length_le(size_t len1, size_t len2); // less than
int asn1_data_to_der(const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_data_from_der(const uint8_t **d, size_t dlen, const uint8_t **in, size_t *inlen);
int asn1_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
int asn1_nonempty_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_nonempty_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
int asn1_any_type_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
int asn1_any_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); // 调用方应保证a,alen为TLV
int asn1_any_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); // 该函数会检查输入是否为TLV
#define ASN1_TRUE 0xff
#define ASN1_FALSE 0x00
const char *asn1_boolean_name(int val);
int asn1_boolean_from_name(int *val, const char *name);
int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen);
int asn1_boolean_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen);
#define asn1_boolean_to_der(val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_BOOLEAN,val,out,outlen)
#define asn1_boolean_from_der(val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_BOOLEAN,val,in,inlen)
#define asn1_implicit_boolean_to_der(i,val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen)
#define asn1_implicit_boolean_from_der(i,val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen)
// asn1_integer_ 不支持负数编解码
int asn1_integer_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_integer_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
#define asn1_integer_to_der(d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_INTEGER,d,dlen,out,outlen)
#define asn1_integer_from_der(d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_INTEGER,d,dlen,in,inlen)
#define asn1_implicit_integer_to_der(i,d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_integer_from_der(i,d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
// asn1_int_ 只支持小的无符号整数的编解码,不支持负数
int asn1_int_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen); // 当 val == -1 时,不输出,返回 0
int asn1_int_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen); // 不支持负数返回0时 *val 设置为 -1
#define asn1_int_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_INTEGER,val,out,outlen)
#define asn1_int_from_der(val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_INTEGER,val,in,inlen)
#define asn1_implicit_int_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen)
#define asn1_implicit_int_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen)
// 比特长度不必须为8的整数倍
int asn1_bit_string_to_der_ex(int tag, const uint8_t *d, size_t nbits, uint8_t **out, size_t *outlen);
int asn1_bit_string_from_der_ex(int tag, const uint8_t **d, size_t *nbits, const uint8_t **in, size_t *inlen);
#define asn1_bit_string_to_der(d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_BIT_STRING,d,nbits,out,outlen)
#define asn1_bit_string_from_der(d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_BIT_STRING,d,nbits,in,inlen)
#define asn1_implicit_bit_string_to_der(i,d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,nbits,out,outlen)
#define asn1_implicit_bit_string_from_der(i,d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,nbits,in,inlen)
// 比特长度必须为8的整数倍因此使用字节长度
int asn1_bit_octets_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_bit_octets_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
#define asn1_bit_octets_to_der(d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_BIT_STRING,d,dlen,out,outlen)
#define asn1_bit_octets_from_der(d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_BIT_STRING,d,dlen,in,inlen)
#define asn1_implicit_bit_octets_to_der(i,d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_bit_octets_from_der(i,d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
// bits == -1 不编码,只支持较少的比特数量
int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen);
int asn1_bits_from_der_ex(int tag, int *bits, const uint8_t **in, size_t *inlen);
#define asn1_bits_to_der(bits,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_BIT_STRING,bits,out,outlen)
#define asn1_bits_from_der(bits,in,inlen) asn1_bits_from_der_ex(ASN1_TAG_BIT_STRING,bits,in,inlen)
#define asn1_implicit_bits_to_der(i,bits,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_IMPLICIT(i),bits,out,outlen)
#define asn1_implicit_bits_from_der(i,bits,in,inlen) asn1_bits_from_der_ex(ASN1_TAG_IMPLICIT(i),bits,in,inlen)
// names[i]对应第i个比特
int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char **names, size_t names_cnt, int bits);
#define asn1_octet_string_to_der_ex(tag,d,dlen,out,outlen) asn1_type_to_der(tag,d,dlen,out,outlen)
#define asn1_octet_string_from_der_ex(tag,d,dlen,in,inlen) asn1_type_from_der(tag,d,dlen,in,inlen)
#define asn1_octet_string_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_OCTET_STRING,d,dlen,out,outlen)
#define asn1_octet_string_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_OCTET_STRING,d,dlen,in,inlen)
#define asn1_implicit_octet_string_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_octet_string_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
const char *asn1_null_name(void);
int asn1_null_to_der(uint8_t **out, size_t *outlen);
int asn1_null_from_der(const uint8_t **in, size_t *inlen);
#define ASN1_OID_MIN_NODES 2
#define ASN1_OID_MAX_NODES 32
#define ASN1_OID_MIN_OCTETS 1
#define ASN1_OID_MAX_OCTETS (1 + (ASN1_OID_MAX_NODES - 2) * 5)
int asn1_object_identifier_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen);
int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_cnt, const uint8_t *in, size_t inlen);
int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen);
int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen);
#define asn1_object_identifier_to_der(nodes,nodes_cnt,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,nodes,nodes_cnt,out,outlen)
#define asn1_object_identifier_from_der(nodes,nodes_cnt,in,inlen) asn1_object_identifier_from_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,nodes,nodes_cnt,in,inlen)
#define asn1_implicit_object_identifier_to_der(i,nodes,nodes_cnt,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_IMPLICIT(i),nodes,nodes_cnt,out,outlen)
#define asn1_implicit_object_identifier_from_der(i,nodes,nodes_cnt,in,inlen) asn1_object_identifier_from_der_ex(ASN1_TAG_IMPLICIT(i),nodes,nodes_cnt,in,inlen)
int asn1_object_identifier_equ(const uint32_t *a, size_t a_cnt, const uint32_t *b, size_t b_cnt);
int asn1_object_identifier_print(FILE *fp, int fmt, int ind, const char *label, const char *name,
const uint32_t *nodes, size_t nodes_cnt);
typedef struct {
int oid;
char *name;
uint32_t *nodes;
size_t nodes_cnt;
int flags;
char *description;
} ASN1_OID_INFO;
const ASN1_OID_INFO *asn1_oid_info_from_name(const ASN1_OID_INFO *infos, size_t count, const char *name);
const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t count, int oid);
// 如果一个正确解析的OID并不在infos列表中那么仍然返回1但是调用方必须检查返回的info是否为空
int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt,
const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen);
int asn1_oid_info_from_der(const ASN1_OID_INFO **info,
const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen);
#define asn1_enumerated_to_der_ex(tag,val,out,outlen) asn1_int_to_der_ex(tag,val,out,outlen)
#define asn1_enumerated_from_der_ex(tag,val,in,inlen) asn1_int_from_der_ex(tag,val,in,inlen)
#define asn1_enumerated_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_ENUMERATED,val,out,outlen)
#define asn1_enumerated_from_der(val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_ENUMERATED,val,in,inlen)
#define asn1_implicit_enumerated_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen)
#define asn1_implicit_enumerated_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen)
int asn1_string_is_utf8_string(const char *d, size_t dlen);
int asn1_utf8_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_utf8_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
#define asn1_utf8_string_to_der(d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_UTF8String,d,dlen,out,outlen)
#define asn1_utf8_string_from_der(d,dlen,in,inlen) asn1_utf8_string_from_der_ex(ASN1_TAG_UTF8String,d,dlen,in,inlen)
#define asn1_implicit_utf8_string_to_der(i,d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_utf8_string_from_der(i,d,dlen,in,inlen) asn1_utf8_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
int asn1_string_is_printable_string(const char *d, size_t dlen);
int asn1_printable_string_case_ignore_match(const char *a, size_t alen, const char *b, size_t blen);
int asn1_printable_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_printable_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
#define asn1_printable_string_to_der(d,dlen,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_PrintableString,d,dlen,out,outlen)
#define asn1_printable_string_from_der(d,dlen,in,inlen) asn1_printable_string_from_der_ex(ASN1_TAG_PrintableString,d,dlen,in,inlen)
#define asn1_implicit_printable_string_to_der(i,d,dlen,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_printable_string_from_der(i,d,dlen,in,inlen) asn1_printable_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
int asn1_string_is_ia5_string(const char *d, size_t dlen);
int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen);
int asn1_ia5_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen);
#define asn1_ia5_string_to_der(d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IA5String,d,dlen,out,outlen)
#define asn1_ia5_string_from_der(d,dlen,in,inlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IA5String,d,dlen,in,inlen)
#define asn1_implicit_ia5_string_to_der(i,d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_ia5_string_from_der(i,d,dlen,in,inlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen);
#define ASN1_UTC_TIME_STRLEN (sizeof("YYMMDDHHMMSSZ")-1)
#define ASN1_GENERALIZED_TIME_STRLEN (sizeof("YYYYMMDDHHMMSSZ")-1)
#define ASN1_GENERALIZED_TIME_MAX_SIZE (2 + ASN1_GENERALIZED_TIME_STRLEN)
int asn1_time_to_str(int utc_time, time_t timestamp, char *str);
int asn1_time_from_str(int utc_time, time_t *timestamp, const char *str);
int asn1_utc_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen);
int asn1_utc_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen);
#define asn1_utc_time_to_der(tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_UTCTime,tv,out,outlen)
#define asn1_utc_time_from_der(tv,in,inlen) asn1_utc_time_from_der_ex(ASN1_TAG_UTCTime,tv,in,inlen)
#define asn1_implicit_utc_time_to_der(i,tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen)
#define asn1_implicit_utc_time_from_der(i,tv,in,inlen) asn1_utc_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen)
int asn1_generalized_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen);
int asn1_generalized_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen);
#define asn1_generalized_time_to_der(tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_GeneralizedTime,tv,out,outlen)
#define asn1_generalized_time_from_der(tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_GeneralizedTime,tv,in,inlen)
#define asn1_implicit_generalized_time_to_der(i,tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen)
#define asn1_implicit_generalized_time_from_der(i,tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen)
// BasicConstraints might be an empty sequence in entity certificates
#define asn1_sequence_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SEQUENCE,d,dlen,out,outlen)
#define asn1_sequence_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_SEQUENCE,d,dlen,in,inlen)
#define asn1_implicit_sequence_to_der(i,d,dlen,out,outlen) asn1_nonempty_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_sequence_from_der(i,d,dlen,in,inlen) asn1_nonempty_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen)
#define asn1_sequence_of_to_der(d,dlen,out,outlen) asn1_nonempty_type_to_der(ASN1_TAG_SEQUENCE,d,dlen,out,outlen)
#define asn1_sequence_of_from_der(d,dlen,in,inlen) asn1_nonempty_type_from_der(ASN1_TAG_SEQUENCE,d,dlen,in,inlen)
int asn1_sequence_of_int_to_der(const int *nums, size_t nums_cnt, uint8_t **out, size_t *outlen);
int asn1_sequence_of_int_from_der(int *nums, size_t *nums_cnt, size_t max_nums, const uint8_t **in, size_t *inlen);
int asn1_sequence_of_int_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#define asn1_set_to_der(d,dlen,out,outlen) asn1_nonempty_type_to_der(ASN1_TAG_SET,d,dlen,out,outlen)
#define asn1_set_from_der(d,dlen,in,inlen) asn1_nonempty_type_from_der(ASN1_TAG_SET,d,dlen,in,inlen)
#define asn1_implicit_set_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_set_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen)
#define asn1_set_of_to_der(d,dlen,out,outlen) asn1_nonempty_type_to_der(ASN1_TAG_SET,d,dlen,out,outlen)
#define asn1_set_of_from_der(d,dlen,in,inlen) asn1_nonempty_type_from_der(ASN1_TAG_SET,d,dlen,in,inlen)
#define asn1_implicit_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen)
#define asn1_implicit_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen)
int asn1_header_to_der(int tag, size_t dlen, uint8_t **out, size_t *outlen);
#define asn1_implicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
#define asn1_octet_string_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_OCTET_STRING,dlen,out,outlen)
#define asn1_sequence_header_to_der_ex(tag,dlen,out,outlen) asn1_header_to_der(tag,dlen,out,outlen)
#define asn1_sequence_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SEQUENCE,dlen,out,outlen)
#define asn1_implicit_sequence_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
#define asn1_set_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SET,dlen,out,outlen)
#define asn1_implicit_set_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
#define asn1_explicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
#define asn1_explicit_to_der(i,d,dlen,out,outlen) asn1_nonempty_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen)
#define asn1_explicit_from_der(i,d,dlen,in,inlen) asn1_nonempty_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen)
// d,dlen 是 SEQUENCE OF, SET OF 中的值
int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, size_t *cnt);
int asn1_types_get_item_by_index(const uint8_t *d, size_t dlen, int tag,
int index, const uint8_t **item_d, size_t *item_dlen);
int asn1_check(int expr);
#if __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_BASE64_H
#define GMSSL_BASE64_H
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
BASE64 Public API
BASE64_CTX
base64_encode_init
base64_encode_update
base64_encode_finish
base64_decode_init
base64_decode_update
base64_decode_finish
*/
typedef struct {
/* number saved in a partial encode/decode */
int num;
/*
* The length is either the output line length (in input bytes) or the
* shortest input line length that is ok. Once decoding begins, the
* length is adjusted up each time a longer line is decoded
*/
int length;
/* data to encode */
unsigned char enc_data[80];
/* number read on current line */
int line_num;
int expect_nl;
} BASE64_CTX;
# define BASE64_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80)
# define BASE64_DECODE_LENGTH(l) ((l+3)/4*3+80)
void base64_encode_init(BASE64_CTX *ctx);
int base64_encode_update(BASE64_CTX *ctx, const uint8_t *in, int inlen, uint8_t *out, int *outlen);
void base64_encode_finish(BASE64_CTX *ctx, uint8_t *out, int *outlen);
void base64_decode_init(BASE64_CTX *ctx);
int base64_decode_update(BASE64_CTX *ctx, const uint8_t *in, int inlen, uint8_t *out, int *outlen);
int base64_decode_finish(BASE64_CTX *ctx, uint8_t *out, int *outlen);
int base64_encode_block(unsigned char *t, const unsigned char *f, int dlen);
int base64_decode_block(unsigned char *t, const unsigned char *f, int n);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_BLOCK_CIPHER_H
#define GMSSL_BLOCK_CIPHER_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/aes.h>
#include <gmssl/sm4.h>
#ifdef __cplusplus
extern "C" {
#endif
#define BLOCK_CIPHER_BLOCK_SIZE 16
#define BLOCK_CIPHER_MIN_KEY_SIZE 16
#define BLOCK_CIPHER_MAX_KEY_SIZE 32
typedef struct BLOCK_CIPHER BLOCK_CIPHER;
typedef struct BLOCK_CIPHER_KEY BLOCK_CIPHER_KEY;
struct BLOCK_CIPHER_KEY {
union {
SM4_KEY sm4_key;
AES_KEY aes_key;
} u;
const BLOCK_CIPHER *cipher;
};
typedef void (*block_cipher_set_encrypt_key_func)(BLOCK_CIPHER_KEY *key, const uint8_t *raw_key);
typedef void (*block_cipher_set_decrypt_key_func)(BLOCK_CIPHER_KEY *key, const uint8_t *raw_key);
typedef void (*block_cipher_encrypt_func)(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out);
typedef void (*block_cipher_decrypt_func)(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out);
struct BLOCK_CIPHER {
int oid;
size_t key_size;
size_t block_size;
block_cipher_set_encrypt_key_func set_encrypt_key;
block_cipher_set_decrypt_key_func set_decrypt_key;
block_cipher_encrypt_func encrypt;
block_cipher_decrypt_func decrypt;
};
const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void);
const BLOCK_CIPHER *BLOCK_CIPHER_aes128(void);
const BLOCK_CIPHER *block_cipher_from_name(const char *name);
const char *block_cipher_name(const BLOCK_CIPHER *cipher);
int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key);
int block_cipher_set_decrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key);
int block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out);
int block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/* RFC 8439 "ChaCha20 and Poly1305 for IETF Protocols" */
#ifndef GMSSL_CHACHA20_H
#define GMSSL_CHACHA20_H
#define CHACHA20_IS_BIG_ENDIAN 0
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define CHACHA20_KEY_BITS 256
#define CHACHA20_NONCE_BITS 96
#define CHACHA20_COUNTER_BITS 32
#define CHACHA20_KEY_SIZE (CHACHA20_KEY_BITS/8)
#define CHACHA20_NONCE_SIZE (CHACHA20_NONCE_BITS/8)
#define CHACHA20_COUNTER_SIZE (CHACHA20_COUNTER_BITS/8)
#define CHACHA20_KEY_WORDS (CHACHA20_KEY_SIZE/sizeof(uint32_t))
#define CHACHA20_NONCE_WORDS (CHACHA20_NONCE_SIZE/sizeof(uint32_t))
#define CHACHA20_COUNTER_WORDS (CHACHA20_COUNTER_SIZE/sizeof(uint32_t))
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint32_t d[16];
} CHACHA20_STATE;
void chacha20_init(CHACHA20_STATE *state,
const uint8_t key[CHACHA20_KEY_SIZE],
const uint8_t nonce[CHACHA20_NONCE_SIZE], uint32_t counter);
void chacha20_generate_keystream(CHACHA20_STATE *state,
size_t counts, uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,552 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/*
References:
1. GM/T 0010-2012 SM2 Cryptography Message Syntax Specification
2. RFC 2315 PKCS #7 Cryptographic Message Syntax Version 1.5
3. RFC 5652 Cryptographic Message Syntax (CMS)
*/
#ifndef GMSSL_CMS_H
#define GMSSL_CMS_H
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <gmssl/x509.h>
#ifdef __cplusplus
extern "C" {
#endif
enum {
CMS_version_v1 = 1,
};
/*
ContentType:
OID_cms_data
OID_cms_signed_data
OID_cms_enveloped_data
OID_cms_signed_and_enveloped_data
OID_cms_encrypted_data
OID_cms_key_agreement_info
*/
const char *cms_content_type_name(int oid);
int cms_content_type_from_name(const char *name);
int cms_content_type_to_der(int oid, uint8_t **out, size_t *outlen);
int cms_content_type_from_der(int *oid, const uint8_t **in, size_t *inlen);
/*
ContentInfo ::= SEQUENCE {
contentType OBJECT IDENTIFIER,
content [0] EXPLICIT ANY OPTIONAL }
*/
int cms_content_info_header_to_der(
int content_type, size_t content_len,
uint8_t **out, size_t *outlen);
int cms_content_info_to_der(
int content_type,
const uint8_t *content, size_t content_len,
uint8_t **out, size_t *outlen);
int cms_content_info_from_der(
int *content_type,
const uint8_t **content, size_t *content_len, // 这里获得的是完整的TLV
const uint8_t **in, size_t *inlen);
int cms_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
Data ::= OCTET STRING
*/
#define cms_data_to_der(d,dlen,out,outlen) asn1_octet_string_to_der(d,dlen,out,outlen)
#define cms_data_from_der(d,dlen,in,inlen) asn1_octet_string_from_der(d,dlen,in,inlen)
#define cms_data_print(fp,fmt,ind,label,d,dlen) format_bytes(fp,fmt,ind,label,d,dlen)
/*
EncryptedContentInfo ::= SEQUENCE {
contentType OBJECT IDENTIFIER,
contentEncryptionAlgorithm AlgorithmIdentifier,
encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL,
sharedInfo1 [1] IMPLICIT OCTET STRING OPTIONAL,
sharedInfo2 [2] IMPLICIT OCTET STRING OPTIONAL }
*/
int cms_enced_content_info_to_der(
int content_type,
int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len,
const uint8_t *enced_content, size_t enced_content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
uint8_t **out, size_t *outlen);
int cms_enced_content_info_from_der(
int *content_type,
int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len,
const uint8_t **enced_content, size_t *enced_content_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len,
const uint8_t **in, size_t *inlen);
int cms_enced_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int cms_enced_content_info_encrypt_to_der(
int enc_algor,
const uint8_t *key, size_t keylen,
const uint8_t *iv, size_t ivlen,
int content_type, const uint8_t *content, size_t content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
uint8_t **out, size_t *outlen);
int cms_enced_content_info_decrypt_from_der(
int *enc_algor,
const uint8_t *key, size_t keylen,
int *content_type, uint8_t *content, size_t *content_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len,
const uint8_t **in, size_t *inlen);
/*
EncryptedData ::= SEQUENCE {
version INTEGER (1),
encryptedContentInfo EncryptedContentInfo }
*/
int cms_encrypted_data_to_der(
int version,
int content_type,
int enc_algor, const uint8_t *iv, size_t ivlen,
const uint8_t *enced_content, size_t enced_content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
uint8_t **out, size_t *outlen);
int cms_encrypted_data_from_der(
int *version,
int *content_type,
int *enc_algor, const uint8_t **iv, size_t *ivlen,
const uint8_t **enced_content, size_t *enced_content_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len,
const uint8_t **in, size_t *inlen);
int cms_encrypted_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int cms_encrypted_data_encrypt_to_der(
int enc_algor,
const uint8_t *key, size_t keylen,
const uint8_t *iv, size_t ivlen,
int content_type, const uint8_t *content, size_t content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
uint8_t **out, size_t *outlen);
int cms_encrypted_data_decrypt_from_der(
int *enc_algor,
const uint8_t *key, size_t keylen,
int *content_type, uint8_t *content, size_t *content_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len,
const uint8_t **in, size_t *inlen);
/*
IssuerAndSerialNumber ::= SEQUENCE {
isser Name,
serialNumber INTEGER }
*/
int cms_issuer_and_serial_number_to_der(
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial_number, size_t serial_number_len,
uint8_t **out, size_t *outlen);
int cms_issuer_and_serial_number_from_der(
const uint8_t **issuer, size_t *issuer_len,
const uint8_t **serial_number, size_t *serial_number_len,
const uint8_t **in, size_t *inlen);
int cms_issuer_and_serial_number_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
SignerInfo ::= SEQUENCE {
version INTEGER (1),
issuerAndSerialNumber IssuerAndSerialNumber,
digestAlgorithm AlgorithmIdentifier,
authenticatedAttributes [0] IMPLICIT SET OF Attribute OPTINOAL,
digestEncryptionAlgorithm AlgorithmIdentifier,
encryptedDigest OCTET STRING,
unauthenticatedAttributes [1] IMPLICIT SET OF Attribute OPTINOAL, }
*/
int cms_signer_info_to_der(
int version,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial_number, size_t serial_number_len,
int digest_algor,
const uint8_t *authed_attrs, size_t authed_attrs_len,
int signature_algor,
const uint8_t *enced_digest, size_t enced_digest_len,
const uint8_t *unauthed_attrs, size_t unauthed_attrs_len,
uint8_t **out, size_t *outlen);
int cms_signer_info_from_der(
int *version,
const uint8_t **issuer, size_t *issuer_len,
const uint8_t **serial_number, size_t *serial_number_len,
int *digest_algor,
const uint8_t **authed_attrs, size_t *authed_attrs_len,
int *signature_algor,
const uint8_t **enced_digest, size_t *enced_digest_len,
const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len,
const uint8_t **in, size_t *inlen);
int cms_signer_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int cms_signer_info_sign_to_der(
const SM3_CTX *sm3_ctx, const SM2_KEY *sm2_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial_number, size_t serial_number_len,
const uint8_t *authed_attrs, size_t authed_attrs_len,
const uint8_t *unauthed_attrs, size_t unauthed_attrs_len,
uint8_t **out, size_t *outlen);
int cms_signer_info_verify_from_der(
const SM3_CTX *sm3_ctx, const uint8_t *certs, size_t certslen,
const uint8_t **cert, size_t *certlen,
const uint8_t **issuer, size_t *issuer_len,
const uint8_t **serial, size_t *serial_len,
const uint8_t **authed_attrs, size_t *authed_attrs_len,
const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len,
const uint8_t **in, size_t *inlen);
/*
SignerInfos ::= SET OF SignerInfo;
*/
int cms_signer_infos_add_signer_info(
uint8_t *d, size_t *dlen, size_t maxlen,
const SM3_CTX *sm3_ctx, const SM2_KEY *sign_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial_number, size_t serial_number_len,
const uint8_t *authed_attrs, size_t authed_attrs_len,
const uint8_t *unauthed_attrs, size_t unauthed_attrs_len);
#define cms_signer_infos_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen)
#define cms_signer_infos_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen)
int cms_signer_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int cms_digest_algors_to_der(const int *digest_algors, size_t digest_algors_cnt, uint8_t **out, size_t *outlen);
int cms_digest_algors_from_der(int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors,
const uint8_t **in, size_t *inlen);
int cms_digest_algors_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
SignedData ::= SEQUENCE {
version INTEGER (1),
digestAlgorithms SET OF AlgorithmIdentifier,
contentInfo ContentInfo,
certificates [0] IMPLICIT SET OF Certificate OPTIONAL,
crls [1] IMPLICIT SET OF CertificateRevocationList OPTIONAL,
signerInfos SET OF SignerInfo }
*/
int cms_signed_data_to_der(
int version,
const int *digest_algors, size_t digest_algors_cnt,
const int content_type, const uint8_t *content, const size_t content_len,
const uint8_t *certs, size_t certs_len,
const uint8_t *crls, const size_t crls_len,
const uint8_t *signer_infos, size_t signer_infos_len,
uint8_t **out, size_t *outlen);
int cms_signed_data_from_der(
int *version,
int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors,
int *content_type, const uint8_t **content, size_t *content_len,
const uint8_t **certs, size_t *certs_len,
const uint8_t **crls, size_t *crls_len,
const uint8_t **signer_infos, size_t *signer_infos_len,
const uint8_t **in, size_t *inlen);
int cms_signed_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
typedef struct {
uint8_t *certs;
size_t certs_len;
SM2_KEY *sign_key;
} CMS_CERTS_AND_KEY;
int cms_signed_data_sign_to_der(
const CMS_CERTS_AND_KEY *signers, size_t signers_cnt,
int content_type, const uint8_t *data, size_t datalen, // 当OID_cms_data时为raw data
const uint8_t *crls, size_t crls_len, // 可以为空
uint8_t **out, size_t *outlen);
int cms_signed_data_verify_from_der(
const uint8_t *extra_certs, size_t extra_certs_len,
const uint8_t *extra_crls, size_t extra_crls_len,
int *content_type, const uint8_t **content, size_t *content_len, // 是否应该返回raw data呢
const uint8_t **certs, size_t *certs_len,
const uint8_t **crls, size_t *crls_len,
const uint8_t **signer_infos, size_t *signer_infos_len,
const uint8_t **in, size_t *inlen);
/*
RecipientInfo ::= SEQUENCE {
version INTEGER (1),
issuerAndSerialNumber IssuerAndSerialNumber,
keyEncryptionAlgorithm AlgorithmIdentifier,
encryptedKey OCTET STRING -- DER-encoding of SM2Cipher
}
由于encryptedKey的类型为SM2Cipher, 而SM2Cipher中有2个INTEGER因此长度是不固定的。
因此不能预先确定输出长度
*/
int cms_recipient_info_to_der(
int version,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial_number, size_t serial_number_len,
int public_key_enc_algor,
const uint8_t *enced_key, size_t enced_key_len,
uint8_t **out, size_t *outlen);
int cms_recipient_info_from_der(
int *version,
const uint8_t **issuer, size_t *issuer_len,
const uint8_t **serial_number, size_t *serial_number_len,
int *pke_algor, const uint8_t **params, size_t *params_len,// SM2加密只使用SM3没有默认参数但是ECIES可能有
const uint8_t **enced_key, size_t *enced_key_len,
const uint8_t **in, size_t *inlen);
int cms_recipient_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int cms_recipient_info_encrypt_to_der(
const SM2_KEY *public_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len,
const uint8_t *in, size_t inlen,
uint8_t **out, size_t *outlen);
int cms_recipient_info_decrypt_from_der(
const SM2_KEY *sm2_key,
const uint8_t *rcpt_issuer, size_t rcpt_issuer_len,
const uint8_t *rcpt_serial, size_t rcpt_serial_len,
uint8_t *out, size_t *outlen, size_t maxlen,
const uint8_t **in, size_t *inlen);
int cms_recipient_infos_add_recipient_info(
uint8_t *d, size_t *dlen, size_t maxlen,
const SM2_KEY *public_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len,
const uint8_t *in, size_t inlen);
#define cms_recipient_infos_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen)
#define cms_recipient_infos_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen)
int cms_recipient_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
EnvelopedData ::= SEQUENCE {
version Version,
recipientInfos SET OF RecipientInfo,
encryptedContentInfo EncryptedContentInfo }
*/
int cms_enveloped_data_to_der(
int version,
const uint8_t *rcpt_infos, size_t rcpt_infos_len,
int content_type,
int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len,
const uint8_t *enced_content, size_t enced_content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
uint8_t **out, size_t *outlen);
int cms_enveloped_data_from_der(
int *version,
const uint8_t **rcpt_infos, size_t *rcpt_infos_len,
const uint8_t **enced_content_info, size_t *enced_content_info_len,
const uint8_t **in, size_t *inlen);
int cms_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int cms_enveloped_data_encrypt_to_der(
const uint8_t *rcpt_certs, size_t rcpt_certs_len,
int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
int content_type, const uint8_t *content, size_t content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
uint8_t **out, size_t *outlen);
int cms_enveloped_data_decrypt_from_der(
const SM2_KEY *sm2_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial_number, size_t serial_number_len,
int *content_type, uint8_t *content, size_t *content_len,
const uint8_t **rcpt_infos, size_t *rcpt_infos_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len,
const uint8_t **in, size_t *inlen);
/*
SignedAndEnvelopedData ::= SEQUENCE {
version INTEGER (1),
recipientInfos SET OF RecipientInfo,
digestAlgorithms SET OF AlgorithmIdentifier,
encryptedContentInfo EncryptedContentInfo,
certificates [0] IMPLICIT SET OF Certificate OPTIONAL,
crls [1] IMPLICIT SET OF CertificateRevocationList OPTIONAL,
signerInfos SET OF SignerInfo }
*/
int cms_signed_and_enveloped_data_to_der(
int version,
const uint8_t *rcpt_infos, size_t rcpt_infos_len,
const int *digest_algors, size_t digest_algors_cnt,
int content_type,
int enc_algor, const uint8_t *iv, size_t ivlen,
const uint8_t *enced_content, size_t enced_content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
const uint8_t *certs, size_t certs_len,
const uint8_t *crls, size_t crls_len,
const uint8_t *signer_infos, size_t signer_infos_len,
uint8_t **out, size_t *outlen);
int cms_signed_and_enveloped_data_from_der(
int *version,
const uint8_t **rcpt_infos, size_t *rcpt_infos_len,
int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors,
const uint8_t **enced_content_info, size_t *enced_content_info_len,
const uint8_t **certs, size_t *certs_len,
const uint8_t **crls, size_t *crls_len,
const uint8_t **signer_infos, size_t *signer_infos_len,
const uint8_t **in, size_t *inlen);
int cms_signed_and_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int cms_signed_and_enveloped_data_encipher_to_der(
const CMS_CERTS_AND_KEY *signers, size_t signers_cnt,
const uint8_t *rcpt_certs, size_t rcpt_certs_len,
int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
int content_type, const uint8_t *content, size_t content_len,
const uint8_t *signers_crls, size_t signers_crls_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
uint8_t **out, size_t *outlen);
int cms_signed_and_enveloped_data_decipher_from_der(
const SM2_KEY *rcpt_key,
const uint8_t *rcpt_issuer, size_t rcpt_issuer_len,
const uint8_t *rcpt_serial, size_t rcpt_serial_len,
int *content_type, uint8_t *content, size_t *content_len,
const uint8_t **prcpt_infos, size_t *prcpt_infos_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len,
const uint8_t **certs, size_t *certs_len,
const uint8_t **crls, size_t *crls_len,
const uint8_t **psigner_infos, size_t *psigner_infos_len,
const uint8_t *extra_certs, size_t extra_certs_len,
const uint8_t *extra_crls, size_t extra_crls_len,
const uint8_t **in, size_t *inlen);
/*
KeyAgreementInfo ::= SEQUENCE {
version INTEGER (1),
tempPublicKeyR SM2PublicKey,
userCertificate Certificate,
userID OCTET STRING }
*/
int cms_key_agreement_info_to_der(
int version,
const SM2_KEY *temp_public_key_r,
const uint8_t *user_cert, size_t user_cert_len,
const uint8_t *user_id, size_t user_id_len,
uint8_t **out, size_t *outlen);
int cms_key_agreement_info_from_der(
int *version,
SM2_KEY *temp_public_key_r,
const uint8_t **user_cert, size_t *user_cert_len,
const uint8_t **user_id, size_t *user_id_len,
const uint8_t **in, size_t *inlen);
int cms_key_agreement_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
// 下面是公开API
// 公开API的设计考虑
// 1. 不需要调用其他函数
// 2. 在逻辑上容易理解
// 3. 将cms,cmslen看做对象
// 生成ContentInfo, type == data
int cms_set_data(uint8_t *cms, size_t *cmslen,
const uint8_t *d, size_t dlen);
int cms_encrypt(
uint8_t *cms, size_t *cmslen, // ContentInfo (type encryptedData)
int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, // 对称加密算法、密钥和IV
int content_type, const uint8_t *content, size_t content_len, // 待加密的输入数据
const uint8_t *shared_info1, size_t shared_info1_len, // 附加信息
const uint8_t *shared_info2, size_t shared_info2_len);
int cms_decrypt(
const uint8_t *cms, size_t cmslen, // ContentInfo (type encryptedData)
int *enc_algor, const uint8_t *key, size_t keylen, // 解密密钥(我们不知道解密算法)
int *content_type, uint8_t *content, size_t *content_len, // 输出的解密数据类型及数据
const uint8_t **shared_info1, size_t *shared_info1_len, // 附加信息
const uint8_t **shared_info2, size_t *shared_info2_len);
int cms_sign(
uint8_t *cms, size_t *cms_len,
const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, // 签名者的签名私钥和证书
int content_type, const uint8_t *content, size_t content_len, // 待签名的输入数据
const uint8_t *crls, size_t crls_len);
int cms_verify(
const uint8_t *cms, size_t cms_len,
const uint8_t *extra_certs, size_t extra_certs_len,
const uint8_t *extra_crls, size_t extra_crls_len,
int *content_type, const uint8_t **content, size_t *content_len,
const uint8_t **certs, size_t *certs_len,
const uint8_t **crls, size_t *crls_len,
const uint8_t **signer_infos, size_t *signer_infos_len);
int cms_envelop(
uint8_t *cms, size_t *cms_len,
const uint8_t *rcpt_certs, size_t rcpt_certs_len, // 接收方证书,注意这个参数的类型可以容纳多个证书,但是只有在一个接受者时对调用方最方便
int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, // 对称加密算法及参数
int content_type, const uint8_t *content, size_t content_len, // 待加密的输入数据
const uint8_t *shared_info1, size_t shared_info1_len, // 附加输入信息
const uint8_t *shared_info2, size_t shared_info2_len);
int cms_deenvelop(
const uint8_t *cms, size_t cms_len,
const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, // 接收方的解密私钥和对应的证书,注意只需要一个解密方
int *content_type, uint8_t *content, size_t *content_len,
const uint8_t **rcpt_infos, size_t *rcpt_infos_len, // 解析得到,用于显示
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len);
int cms_sign_and_envelop(
uint8_t *cms, size_t *cms_len,
const CMS_CERTS_AND_KEY *signers, size_t signers_cnt,
const uint8_t *rcpt_certs, size_t rcpt_certs_len,
int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
int content_type, const uint8_t *content, size_t content_len,
const uint8_t *signers_crls, size_t signers_crls_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len);
int cms_deenvelop_and_verify(
const uint8_t *cms, size_t cms_len,
const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len,
const uint8_t *extra_signer_certs, size_t extra_signer_certs_len,
const uint8_t *extra_signer_crls, size_t extra_signer_crls_len,
int *content_type, uint8_t *content, size_t *content_len,
const uint8_t **rcpt_infos, size_t *rcpt_infos_len,
const uint8_t **signer_infos, size_t *signer_infos_len,
const uint8_t **signer_certs, size_t *signer_certs_len,
const uint8_t **signer_crls, size_t *signer_crls_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len);
// 生成ContentInfo, type == keyAgreementInfo
int cms_set_key_agreement_info(
uint8_t *cms, size_t *cms_len,
const SM2_KEY *temp_public_key_r,
const uint8_t *user_cert, size_t user_cert_len,
const uint8_t *user_id, size_t user_id_len);
#define PEM_CMS "CMS"
int cms_to_pem(const uint8_t *cms, size_t cms_len, FILE *fp);
int cms_from_pem(uint8_t *cms, size_t *cms_len, size_t maxlen, FILE *fp);
int cms_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/* FIPS PUB 46-3 "Data Encryption Standard (DES)" */
#ifndef GMSSL_DES_H
#define GMSSL_DES_H
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#define DES_KEY_BITS 56
#define DES_BLOCK_BITS 64
#define DES_KEY_SIZE ((DES_KEY_BITS)/7)
#define DES_BLOCK_SIZE (DES_BLOCK_BITS/8)
#define DES_RK_BITS 48
#define DES_RK_SIZE (DES_RK_BITS/8)
#define DES_ROUNDS 16
#define DES_EDE_KEY_SIZE (DES_KEY_SIZE * 3)
typedef struct {
uint64_t rk[DES_ROUNDS];
} DES_KEY;
void des_set_encrypt_key(DES_KEY *key, const uint8_t raw_key[DES_KEY_SIZE]);
void des_set_decrypt_key(DES_KEY *key, const uint8_t raw_key[DES_KEY_SIZE]);
void des_encrypt(DES_KEY *key, const uint8_t in[DES_BLOCK_SIZE], uint8_t out[DES_BLOCK_SIZE]);
typedef struct {
DES_KEY K[3];
} DES_EDE_KEY;
void des_ede_set_encrypt_key(DES_EDE_KEY *key, const uint8_t raw_key[DES_EDE_KEY_SIZE]);
void des_ede_set_decrypt_key(DES_EDE_KEY *key, const uint8_t raw_key[DES_EDE_KEY_SIZE]);
void des_ede_encrypt(DES_EDE_KEY *key, const uint8_t in[DES_BLOCK_SIZE], uint8_t out[DES_BLOCK_SIZE]);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_DIGEST_H
#define GMSSL_DIGEST_H
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm3.h>
#ifdef ENABLE_BROKEN_CRYPTO
#include <gmssl/md5.h>
#include <gmssl/sha1.h>
#endif
#include <gmssl/sha2.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct DIGEST DIGEST;
typedef struct DIGEST_CTX DIGEST_CTX;
#define DIGEST_MAX_SIZE 64
#define DIGEST_MAX_BLOCK_SIZE (1024/8)
struct DIGEST_CTX {
union {
SM3_CTX sm3_ctx;
#ifdef ENABLE_BROKEN_CRYPTO
MD5_CTX md5_ctx;
SHA1_CTX sha1_ctx;
#endif
SHA224_CTX sha224_ctx;
SHA256_CTX sha256_ctx;
SHA384_CTX sha384_ctx;
SHA512_CTX sha512_ctx;
} u;
const DIGEST *digest;
};
struct DIGEST {
int oid;
size_t digest_size;
size_t block_size;
size_t ctx_size;
int (*init)(DIGEST_CTX *ctx);
int (*update)(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen);
int (*finish)(DIGEST_CTX *ctx, uint8_t *dgst);
};
const DIGEST *DIGEST_sm3(void);
#ifdef ENABLE_BROKEN_CRYPTO
const DIGEST *DIGEST_md5(void);
const DIGEST *DIGEST_sha1(void);
#endif
const DIGEST *DIGEST_sha224(void);
const DIGEST *DIGEST_sha256(void);
const DIGEST *DIGEST_sha384(void);
const DIGEST *DIGEST_sha512(void);
const DIGEST *DIGEST_sha512_224(void);
const DIGEST *DIGEST_sha512_256(void);
const DIGEST *digest_from_name(const char *name);
const char *digest_name(const DIGEST *digest);
int digest_init(DIGEST_CTX *ctx, const DIGEST *algor);
int digest_update(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen);
int digest_finish(DIGEST_CTX *ctx, uint8_t *dgst, size_t *dgstlen);
int digest(const DIGEST *digest, const uint8_t *data, size_t datalen, uint8_t *dgst, size_t *dgstlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_DYLIB_H
#define GMSSL_DYLIB_H
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
#include <windows.h>
typedef HMODULE dylib_handle_t;
#define dylib_load_library(so_path) LoadLibraryA(so_path)
#define dylib_get_function(handle,name) GetProcAddress(handle,name)
#define dylib_close_library(handle)
#define dylib_error_str() ""
#else
#include <dlfcn.h>
typedef void *dylib_handle_t;
#define dylib_load_library(so_path) dlopen(so_path,RTLD_LAZY)
#define dylib_get_function(handle,name) dlsym(handle,name)
#define dylib_close_library(handle) dlclose(handle)
#define dylib_error_str() dlerror()
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_EC_H
#define GMSSL_EC_H
#include <time.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm2.h>
#include <gmssl/oid.h>
#include <gmssl/asn1.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
NamedCurve:
OID_sm2
OID_prime192v1
OID_prime256v1
OID_secp256k1
OID_secp384r1
OID_secp521r1
*/
const char *ec_named_curve_name(int curve);
int ec_named_curve_from_name(const char *name);
int ec_named_curve_to_der(int curve, uint8_t **out, size_t *outlen);
int ec_named_curve_from_der(int *curve, const uint8_t **in, size_t *inlen);
/*
ECPoint ::= OCTET STRING -- uncompressed point
*/
int ec_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
ECPrivateKey ::= SEQUENCE {
version INTEGER, -- value MUST be (1)
privateKey OCTET STRING, -- big endian encoding of integer
parameters [0] EXPLICIT OBJECT IDENTIFIER OPTIONAL, -- namedCurve
publicKey [1] EXPLICIT BIT STRING OPTIONAL -- ECPoint
}
*/
enum {
EC_private_key_version = 1,
};
int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_ENDIAN_H
#define GMSSL_ENDIAN_H
/* Big Endian R/W */
#define GETU16(p) \
((uint16_t)(p)[0] << 8 | \
(uint16_t)(p)[1])
#define GETU32(p) \
((uint32_t)(p)[0] << 24 | \
(uint32_t)(p)[1] << 16 | \
(uint32_t)(p)[2] << 8 | \
(uint32_t)(p)[3])
#define GETU64(p) \
((uint64_t)(p)[0] << 56 | \
(uint64_t)(p)[1] << 48 | \
(uint64_t)(p)[2] << 40 | \
(uint64_t)(p)[3] << 32 | \
(uint64_t)(p)[4] << 24 | \
(uint64_t)(p)[5] << 16 | \
(uint64_t)(p)[6] << 8 | \
(uint64_t)(p)[7])
// 注意PUTU32(buf, val++) 会出错!
#define PUTU16(p,V) \
((p)[0] = (uint8_t)((V) >> 8), \
(p)[1] = (uint8_t)(V))
#define PUTU32(p,V) \
((p)[0] = (uint8_t)((V) >> 24), \
(p)[1] = (uint8_t)((V) >> 16), \
(p)[2] = (uint8_t)((V) >> 8), \
(p)[3] = (uint8_t)(V))
#define PUTU64(p,V) \
((p)[0] = (uint8_t)((V) >> 56), \
(p)[1] = (uint8_t)((V) >> 48), \
(p)[2] = (uint8_t)((V) >> 40), \
(p)[3] = (uint8_t)((V) >> 32), \
(p)[4] = (uint8_t)((V) >> 24), \
(p)[5] = (uint8_t)((V) >> 16), \
(p)[6] = (uint8_t)((V) >> 8), \
(p)[7] = (uint8_t)(V))
/* Little Endian R/W */
#define GETU16_LE(p) (*(const uint16_t *)(p))
#define GETU32_LE(p) (*(const uint32_t *)(p))
#define GETU64_LE(p) (*(const uint64_t *)(p))
#define PUTU16_LE(p,V) *(uint16_t *)(p) = (V)
#define PUTU32_LE(p,V) *(uint32_t *)(p) = (V)
#define PUTU64_LE(p,V) *(uint64_t *)(p) = (V)
/* Rotate */
#define ROL32(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
#define ROL64(a,n) (((a)<<(n))|((a)>>(64-(n))))
#define ROR32(a,n) ROL32((a),32-(n))
#define ROR64(a,n) ROL64(a,64-n)
#endif

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_ERROR_H
#define GMSSL_ERROR_H
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GMSSL_FMT_BIN 1
#define GMSSL_FMT_HEX 2
#define GMSSL_FMT_DER 4
#define GMSSL_FMT_PEM 8
#define DEBUG 1
#define warning_print() \
do { if (DEBUG) fprintf(stderr, "%s:%d:%s():\n",__FILE__, __LINE__, __func__); } while (0)
#define error_print() \
do { if (DEBUG) fprintf(stderr, "%s:%d:%s():\n",__FILE__, __LINE__, __func__); } while (0)
#define error_print_msg(fmt, ...) \
do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__); } while (0)
#define error_puts(str) \
do { if (DEBUG) fprintf(stderr, "%s: %d: %s: %s", __FILE__, __LINE__, __func__, str); } while (0)
void print_der(const uint8_t *in, size_t inlen);
void print_bytes(const uint8_t *in, size_t inlen);
void print_nodes(const uint32_t *in, size_t inlen);
#define FMT_CARRAY 0x80
int format_print(FILE *fp, int format, int indent, const char *str, ...);
int format_bytes(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen);
int format_string(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen);
//int tls_trace(int format, int indent, const char *str, ...);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_FILE_H
#define GMSSL_FILE_H
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int file_size(FILE *fp, size_t *size);
int file_read_all(const char *file, uint8_t **out, size_t *outlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_GCM_H
#define GMSSL_GCM_H
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <gmssl/gf128.h>
#include <gmssl/block_cipher.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GCM_IV_MIN_SIZE 1
#define GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3)))
#define GCM_IV_DEFAULT_BITS 96
#define GCM_IV_DEFAULT_SIZE 12
#define GCM_MIN_AAD_SIZE 0
#define GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3)))
#define GCM_MIN_PLAINTEXT_SIZE 0
#define GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3)
#define GHASH_SIZE (16)
#define GCM_IS_LITTLE_ENDIAN 1
void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen,
const uint8_t *c, size_t clen, uint8_t out[16]);
typedef struct {
gf128_t H;
gf128_t X;
size_t aadlen;
size_t clen;
uint8_t block[16];
size_t num;
} GHASH_CTX;
void ghash_init(GHASH_CTX *ctx, const uint8_t h[16], const uint8_t *aad, size_t aadlen);
void ghash_update(GHASH_CTX *ctx, const uint8_t *c, size_t clen);
void ghash_finish(GHASH_CTX *ctx, uint8_t out[16]);
int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
uint8_t *out, size_t taglen, uint8_t *tag);
int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
const uint8_t *tag, size_t taglen, uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/* GF(2^128) defined by f(x) = x^128 + x^7 + x^2 + x + 1
* A + B mod f(x) = a xor b
* A * 2 mod f(x)
*/
#ifndef GMSSL_GF128_H
#define GMSSL_GF128_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
//typedef unsigned __int128 gf128_t;
typedef struct {
uint64_t hi;
uint64_t lo;
} gf128_t;
// Note: send by value is comptabile with uint128_t and sse2
gf128_t gf128_from_hex(const char *s);
int gf128_equ_hex(gf128_t a, const char *s);
gf128_t gf128_zero(void);
gf128_t gf128_add(gf128_t a, gf128_t b);
gf128_t gf128_mul(gf128_t a, gf128_t b);
gf128_t gf128_mul2(gf128_t a);
gf128_t gf128_from_bytes(const uint8_t p[16]);
void gf128_to_bytes(gf128_t a, uint8_t p[16]);
int gf128_print(FILE *fp, int fmt ,int ind, const char *label, gf128_t a);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/* NIST SP800-90A Rev.1 "Recommendation for Random Number Generation
* Using Deterministic Random Bit Generators", 10.1.1 Hash_DRBG */
#ifndef GMSSL_HASH_DRBG_H
#define GMSSL_HASH_DRBG_H
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/digest.h>
/* seedlen for hash_drgb, table 2 of nist sp 800-90a rev.1 */
#define HASH_DRBG_SM3_SEED_BITS 440 /* 55 bytes */
#define HASH_DRBG_SHA1_SEED_BITS 440
#define HASH_DRBG_SHA224_SEED_BITS 440
#define HASH_DRBG_SHA512_224_SEED_BITS 440
#define HASH_DRBG_SHA256_SEED_BITS 440
#define HASH_DRBG_SHA512_256_SEED_BITS 440
#define HASH_DRBG_SHA384_SEED_BITS 888 /* 110 bytes */
#define HASH_DRBG_SHA512_SEED_BITS 888
#define HASH_DRBG_MAX_SEED_BITS 888
#define HASH_DRBG_SM3_SEED_SIZE (HASH_DRBG_SM3_SEED_BITS/8)
#define HASH_DRBG_SHA1_SEED_SIZE (HASH_DRBG_SHA1_SEED_BITS/8)
#define HASH_DRBG_SHA224_SEED_SIZE (HASH_DRBG_SHA224_SEED_BITS/8)
#define HASH_DRBG_SHA512_224_SEED_SIZE (HASH_DRBG_SHA512_224_SEED_BITS/8)
#define HASH_DRBG_SHA256_SEED_SIZE (HASH_DRBG_SHA256_SEED_BITS/8)
#define HASH_DRBG_SHA512_256_SEED_SIZE (HASH_DRBG_SHA512_256_SEED_BITS/8)
#define HASH_DRBG_SHA384_SEED_SIZE (HASH_DRBG_SHA384_SEED_BITS/8)
#define HASH_DRBG_SHA512_SEED_SIZE (HASH_DRBG_SHA512_SEED_BITS/8)
#define HASH_DRBG_MAX_SEED_SIZE (HASH_DRBG_MAX_SEED_BITS/8)
#define HASH_DRBG_RESEED_INTERVAL ((uint64_t)1 << 48)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
const DIGEST *digest;
uint8_t V[HASH_DRBG_MAX_SEED_SIZE];
uint8_t C[HASH_DRBG_MAX_SEED_SIZE];
size_t seedlen;
uint64_t reseed_counter;
} HASH_DRBG;
int hash_drbg_init(HASH_DRBG *drbg,
const DIGEST *digest,
const uint8_t *entropy, size_t entropy_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *personalstr, size_t personalstr_len);
int hash_drbg_reseed(HASH_DRBG *drbg,
const uint8_t *entropy, size_t entropy_len,
const uint8_t *additional, size_t additional_len);
int hash_drbg_generate(HASH_DRBG *drbg,
const uint8_t *additional, size_t additional_len,
size_t outlen, uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_HEX_H
#define GMSSL_HEX_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
// RFC 5869
#ifndef GMSSL_HKDF_H
#define GMSSL_HKDF_H
#include <string.h>
#include <gmssl/digest.h>
#include <gmssl/hmac.h>
#ifdef __cplusplus
extern "C" {
#endif
int hkdf_extract(const DIGEST *digest, const uint8_t *salt, size_t saltlen,
const uint8_t *ikm, size_t ikmlen,
uint8_t *prk, size_t *prklen);
int hkdf_expand(const DIGEST *digest, const uint8_t *prk, size_t prklen,
const uint8_t *opt_info, size_t opt_infolen,
size_t L, uint8_t *okm);
int sm3_hkdf_extract(const uint8_t *salt, size_t saltlen,
const uint8_t *ikm, size_t ikmlen,
uint8_t *prk, size_t *prklen);
int sm3_hkdf_expand(const uint8_t *prk, size_t prklen,
const uint8_t *opt_info, size_t opt_infolen,
size_t L, uint8_t *okm);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_HMAC_H
#define GMSSL_HMAC_H
#include <string.h>
#include <gmssl/digest.h>
#ifdef __cplusplus
extern "C" {
#endif
#define HMAC_MAX_SIZE (DIGEST_MAX_SIZE)
typedef struct hmac_ctx_st {
const DIGEST *digest;
DIGEST_CTX digest_ctx;
DIGEST_CTX i_ctx;
DIGEST_CTX o_ctx;
} HMAC_CTX;
size_t hmac_size(const HMAC_CTX *ctx);
int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const uint8_t *key, size_t keylen);
int hmac_update(HMAC_CTX *ctx, const uint8_t *data, size_t datalen);
int hmac_finish(HMAC_CTX *ctx, uint8_t *mac, size_t *maclen);
int hmac(const DIGEST *md, const uint8_t *key, size_t keylen,
const uint8_t *data, size_t dlen,
uint8_t *mac, size_t *maclen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_HTTP_H
#define GMSSL_HTTP_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int http_parse_uri(const char *uri, char host[128], int *port, char path[256]);
int http_parse_response(char *buf, size_t buflen, uint8_t **content, size_t *contentlen, size_t *left);
int http_get(const char *uri, uint8_t *buf, size_t *contentlen, size_t buflen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_MD5_H
#define GMSSL_MD5_H
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MD5_IS_BIG_ENDIAN 0
#define MD5_DIGEST_SIZE 16
#define MD5_BLOCK_SIZE 64
#define MD5_STATE_WORDS (MD5_BLOCK_SIZE/sizeof(uint32_t))
typedef struct {
uint32_t state[MD5_STATE_WORDS];
uint64_t nblocks;
uint8_t block[MD5_BLOCK_SIZE];
size_t num;
} MD5_CTX;
void md5_init(MD5_CTX *ctx);
void md5_update(MD5_CTX *ctx, const uint8_t *data, size_t datalen);
void md5_finish(MD5_CTX *ctx, uint8_t dgst[MD5_DIGEST_SIZE]);
void md5_digest(const uint8_t *data, size_t datalen, uint8_t dgst[MD5_DIGEST_SIZE]);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_MEM_H
#define GMSSL_MEM_H
#include <stdint.h>
#include <stddef.h> // where size_t from
void memxor(void *r, const void *a, size_t len);
void gmssl_memxor(void *r, const void *a, const void *b, size_t len);
int gmssl_secure_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len);
void gmssl_secure_clear(void *ptr, size_t len);
int mem_is_zero(const uint8_t *buf, size_t len); // FIXME: uint8_t * to void *
#endif

View File

@@ -0,0 +1,215 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_OID_H
#define GMSSL_OID_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
enum {
OID_undef = 0,
// ShangMi schemes in GM/T 0006-2012
OID_sm1,
OID_ssf33,
OID_sm4,
OID_zuc,
OID_sm2,
OID_sm2sign,
OID_sm2keyagreement,
OID_sm2encrypt,
OID_sm9,
OID_sm9sign,
OID_sm9keyagreement,
OID_sm9encrypt,
OID_sm3,
OID_sm3_keyless,
OID_hmac_sm3,
OID_sm2sign_with_sm3,
OID_rsasign_with_sm3,
OID_ec_public_key, // X9.62 ecPublicKey
OID_prime192v1,
OID_prime256v1,
OID_secp256k1,
OID_secp192k1,
OID_secp224k1,
OID_secp224r1,
OID_secp384r1,
OID_secp521r1,
OID_at_name,
OID_at_surname,
OID_at_given_name,
OID_at_initials,
OID_at_generation_qualifier,
OID_at_common_name,
OID_at_locality_name,
OID_at_state_or_province_name,
OID_at_organization_name,
OID_at_organizational_unit_name,
OID_at_title,
OID_at_dn_qualifier,
OID_at_country_name,
OID_at_serial_number,
OID_at_pseudonym,
OID_domain_component,
OID_email_address,
// Cert Extensions
OID_ce_authority_key_identifier,
OID_ce_subject_key_identifier,
OID_ce_key_usage,
OID_ce_certificate_policies,
OID_ce_policy_mappings,
OID_ce_subject_alt_name,
OID_ce_issuer_alt_name,
OID_ce_subject_directory_attributes,
OID_ce_basic_constraints,
OID_ce_name_constraints,
OID_ce_policy_constraints,
OID_ce_ext_key_usage,
OID_ce_crl_distribution_points,
OID_ce_inhibit_any_policy,
OID_ce_freshest_crl,
OID_netscape_cert_type,
OID_netscape_cert_comment,
OID_ct_precertificate_scts,
OID_ad_ca_issuers,
OID_ad_ocsp,
// CRL Extensions
//OID_ce_authority_key_identifier,
//OID_ce_issuer_alt_name,
OID_ce_crl_number,
OID_ce_delta_crl_indicator,
OID_ce_issuing_distribution_point,
//OID_ce_freshest_crl,
OID_pe_authority_info_access,
// CRL Entry Extensions
OID_ce_crl_reasons,
OID_ce_invalidity_date,
OID_ce_certificate_issuer,
// X.509 KeyPropuseID
OID_any_extended_key_usage,
OID_kp_server_auth,
OID_kp_client_auth,
OID_kp_code_signing,
OID_kp_email_protection,
OID_kp_time_stamping,
OID_kp_ocsp_signing,
OID_qt_cps,
OID_qt_unotice,
OID_md5,
OID_sha1,
OID_sha224,
OID_sha256,
OID_sha384,
OID_sha512,
OID_sha512_224,
OID_sha512_256,
OID_hmac_sha1,
OID_hmac_sha224,
OID_hmac_sha256,
OID_hmac_sha384,
OID_hmac_sha512,
OID_hmac_sha512_224,
OID_hmac_sha512_256,
OID_pbkdf2, // {pkcs-5 12}
OID_pbes2, // {pkcs-5 13}
OID_sm4_ecb, // 1 2 156 10197 1 104 1
OID_sm4_cbc, // 1 2 156 10197 1 104 2
OID_aes,
OID_aes128_cbc,
OID_aes192_cbc,
OID_aes256_cbc,
OID_aes128, // 没有OID
OID_ecdsa_with_sha1,
OID_ecdsa_with_sha224,
OID_ecdsa_with_sha256,
OID_ecdsa_with_sha384,
OID_ecdsa_with_sha512,
OID_rsasign_with_md5,
OID_rsasign_with_sha1,
OID_rsasign_with_sha224,
OID_rsasign_with_sha256,
OID_rsasign_with_sha384,
OID_rsasign_with_sha512,
OID_rsa_encryption,
OID_rsaes_oaep,
OID_any_policy,
OID_cms_data,
OID_cms_signed_data,
OID_cms_enveloped_data,
OID_cms_signed_and_enveloped_data,
OID_cms_encrypted_data,
OID_cms_key_agreement_info,
};
// {iso(1) org(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7)}
#define oid_pkix 1,3,6,1,5,5,7
#define oid_pe oid_pkix,1
#define oid_qt oid_pkix,2
#define oid_kp oid_pkix,3
#define oid_ad oid_pkix,48
// {iso(1) member-body(2) us(840) rsadsi(113549)}
#define oid_rsadsi 1,2,840,113549
#define oid_pkcs oid_rsadsi,1
#define oid_pkcs5 oid_pkcs,5
// {iso(1) member-body(2) us(840) ansi-x962(10045)}
#define oid_x9_62 1,2,840,10045
#define oid_at 2,5,4
#define oid_ce 2,5,29
#define oid_sm 1,2,156,10197
#define oid_sm_algors oid_sm,1
#define oid_sm2_cms oid_sm,6,1,4,2
#define oid_cnt(nodes) (sizeof(nodes)/sizeof((nodes)[0]))
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_PBKDF2_H
#define GMSSL_PBKDF2_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#include <gmssl/hmac.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
PBKDF2 Public API
PBKDF2_MIN_ITER
PBKDF2_DEFAULT_SALT_SIZE
PBKDF2_MAX_SALT_SIZE
pbkdf2_hmac_sm3_genkey
*/
#define PBKDF2_MIN_ITER 10000
#define PBKDF2_MAX_ITER (INT_MAX)
#define PBKDF2_MAX_SALT_SIZE 64
#define PBKDF2_DEFAULT_SALT_SIZE 8
int pbkdf2_genkey(const DIGEST *digest,
const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t iter,
size_t outlen, uint8_t *out);
int pbkdf2_hmac_sm3_genkey(
const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t iter,
size_t outlen, uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_PEM_H
#define GMSSL_PEM_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/base64.h>
#ifdef __cplusplus
extern "C" {
#endif
int pem_read(FILE *fp, const char *name, uint8_t *out, size_t *outlen, size_t maxlen);
int pem_write(FILE *fp, const char *name, const uint8_t *in, size_t inlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,169 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
// RFC 5208: PKCS #8: Private-Key Information Syntax Specification version 1.2
#ifndef GMSSL_PKCS8_H
#define GMSSL_PKCS8_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <gmssl/sm2.h>
#include <gmssl/pem.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12}
PBKDF2-params ::= SEQUENCE {
salt CHOICE {
specified OCTET STRING,
otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}}
},
iterationCount INTEGER (1..MAX),
keyLength INTEGER (1..MAX) OPTIONAL, -- 这个参数可以由函数指定
prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
}
prf must be OID_hmac_sm3
cipher must be OID_sm4_cbc
*/
int pbkdf2_params_to_der(const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf,
uint8_t **out, size_t *outlen);
int pbkdf2_params_from_der(const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf,
const uint8_t **in, size_t *inlen);
int pbkdf2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int pbkdf2_algor_to_der(
const uint8_t *salt, size_t saltlen,
int iter,
int keylen,
int prf,
uint8_t **out, size_t *outlen);
int pbkdf2_algor_from_der(
const uint8_t **salt, size_t *saltlen,
int *iter,
int *keylen,
int *prf,
const uint8_t **in, size_t *inlen);
int pbkdf2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13}
PBES2-params ::= SEQUENCE {
keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, -- id-PBKDF2
encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}}
PBES2-Encs:
AES-CBC-Pad [RFC2898]
RC5-CBC-Pad
DES-CBC-Pad legacy
DES-EDE3-CBC-Pad legacy
RC2-CBC-Pad legacy
*/
int pbes2_enc_algor_to_der(
int cipher,
const uint8_t *iv, size_t ivlen,
uint8_t **out, size_t *outlen);
int pbes2_enc_algor_from_der(
int *cipher,
const uint8_t **iv, size_t *ivlen,
const uint8_t **in, size_t *inlen);
int pbes2_enc_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int pbes2_params_to_der(
const uint8_t *salt, size_t saltlen,
int iter,
int keylen,
int prf,
int cipher,
const uint8_t *iv, size_t ivlen,
uint8_t **out, size_t *outlen);
int pbes2_params_from_der(
const uint8_t **salt, size_t *saltlen,
int *iter,
int *keylen,
int *prf,
int *cipher,
const uint8_t **iv, size_t *ivlen,
const uint8_t **in, size_t *inlen);
int pbes2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int pbes2_algor_to_der(
const uint8_t *salt, size_t saltlen,
int iter,
int keylen,
int prf,
int cipher,
const uint8_t *iv, size_t ivlen,
uint8_t **out, size_t *outlen);
int pbes2_algor_from_der(
const uint8_t **salt, size_t *saltlen,
int *iter,
int *keylen,
int *prf,
int *cipher,
const uint8_t **iv, size_t *ivlen,
const uint8_t **in, size_t *inlen);
int pbes2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
from [RFC 5208]
EncryptedPrivateKeyInfo ::= SEQUENCE {
encryptionAlgorithm EncryptionAlgorithmIdentifier,
encryptedData OCTET STRING }
encryptionAlgorithm:
id-PBES2
PrivateKeyInfo ::= SEQUENCE {
version INTEGER { v1(0) },
privateKeyAlgorithm AlgorithmIdentifier,
privateKey OCTET STRING,
attributes [0] Attributes OPTIONAL }
*/
int pkcs8_enced_private_key_info_to_der(
const uint8_t *salt, size_t saltlen,
int iter,
int keylen,
int prf,
int cipher,
const uint8_t *iv, size_t ivlen,
const uint8_t *enced, size_t encedlen,
uint8_t **out, size_t *outlen);
int pkcs8_enced_private_key_info_from_der(
const uint8_t **salt, size_t *saltlen,
int *iter,
int *keylen,
int *prf,
int *cipher,
const uint8_t **iv, size_t *ivlen,
const uint8_t **enced, size_t *encedlen,
const uint8_t **in, size_t *inlen);
int pkcs8_enced_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_RAND_H
#define GMSSL_RAND_H
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/api.h>
#ifdef __cplusplus
extern "C" {
#endif
#define RAND_BYTES_MAX_SIZE (256)
_gmssl_export int rand_bytes(uint8_t *buf, size_t buflen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_RC4_H
#define GMSSL_RC4_H
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define RC4_MIN_KEY_BITS 40
#define RC4_STATE_NUM_WORDS 256
typedef struct {
uint8_t d[RC4_STATE_NUM_WORDS];
} RC4_STATE;
void rc4_init(RC4_STATE *state, const uint8_t *key, size_t keylen);
void rc4_generate_keystream(RC4_STATE *state, size_t outlen, uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_RDRAND_H
#define GMSSL_RDRAND_H
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
int rdrand_bytes(uint8_t *buf, size_t buflen);
#ifdef INTEL_RDSEED
int rdseed_bytes(uint8_t *buf, size_t buflen);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_RSA_H
#define GMSSL_RSA_H
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
RSAPrivateKey ::= SEQUENCE {
version INTEGER, -- 0
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER -- q^-1 mod p
}
*/
int rsa_public_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SDF_H
#define GMSSL_SDF_H
#include <string.h>
#include <stdint.h>
#include <gmssl/sm2.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
SDF Public API
sdf_load_library
sdf_unload_library
SDF_DEVICE
sdf_open_device
sdf_close_device
sdf_print_device_info
sdf_rand_bytes
sdf_load_sign_key
SDF_KEY
sdf_sign
sdf_release_key
*/
typedef struct {
void *handle;
char issuer[41];
char name[17];
char serial[17];
} SDF_DEVICE;
typedef struct {
SM2_KEY public_key;
void *session;
int index;
} SDF_KEY;
int sdf_load_library(const char *so_path, const char *vendor);
int sdf_open_device(SDF_DEVICE *dev);
int sdf_print_device_info(FILE *fp, int fmt, int ind, const char *lable, SDF_DEVICE *dev);
int sdf_rand_bytes(SDF_DEVICE *dev, uint8_t *buf, size_t len);
int sdf_load_sign_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass);
int sdf_sign(SDF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen);
int sdf_release_key(SDF_KEY *key);
int sdf_close_device(SDF_DEVICE *dev);
void sdf_unload_library(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SHA1_H
#define GMSSL_SHA1_H
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SHA1_IS_BIG_ENDIAN 1
#define SHA1_DIGEST_SIZE 20
#define SHA1_BLOCK_SIZE 64
#define SHA1_STATE_WORDS (SHA1_DIGEST_SIZE/sizeof(uint32_t))
typedef struct {
uint32_t state[SHA1_STATE_WORDS];
uint64_t nblocks;
uint8_t block[SHA1_BLOCK_SIZE];
size_t num;
} SHA1_CTX;
void sha1_init(SHA1_CTX *ctx);
void sha1_update(SHA1_CTX *ctx, const uint8_t *data, size_t datalen);
void sha1_finish(SHA1_CTX *ctx, uint8_t dgst[SHA1_DIGEST_SIZE]);
void sha1_digest(const uint8_t *data, size_t datalen, uint8_t dgst[SHA1_DIGEST_SIZE]);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,102 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SHA2_H
#define GMSSL_SHA2_H
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SHA2_IS_BIG_ENDIAN 1
#define SHA224_DIGEST_SIZE 28
#define SHA224_BLOCK_SIZE 64
#define SHA224_STATE_WORDS 8
typedef struct {
uint32_t state[SHA224_STATE_WORDS];
uint64_t nblocks;
uint8_t block[SHA224_BLOCK_SIZE];
size_t num;
} SHA224_CTX;
void sha224_init(SHA224_CTX *ctx);
void sha224_update(SHA224_CTX *ctx, const uint8_t* data, size_t datalen);
void sha224_finish(SHA224_CTX *ctx, uint8_t dgst[SHA224_DIGEST_SIZE]);
void sha224_digest(const uint8_t *data, size_t datalen,
uint8_t dgst[SHA224_DIGEST_SIZE]);
#define SHA256_DIGEST_SIZE 32
#define SHA256_BLOCK_SIZE 64
#define SHA256_STATE_WORDS 8
typedef struct {
uint32_t state[SHA256_STATE_WORDS];
uint64_t nblocks;
uint8_t block[SHA256_BLOCK_SIZE];
size_t num;
} SHA256_CTX;
void sha256_init(SHA256_CTX *ctx);
void sha256_update(SHA256_CTX *ctx, const uint8_t* data, size_t datalen);
void sha256_finish(SHA256_CTX *ctx, uint8_t dgst[SHA256_DIGEST_SIZE]);
void sha256_digest(const uint8_t *data, size_t datalen,
uint8_t dgst[SHA256_DIGEST_SIZE]);
#define SHA384_DIGEST_SIZE 48
#define SHA384_BLOCK_SIZE 128
#define SHA384_STATE_WORDS 8
typedef struct {
uint64_t state[SHA384_STATE_WORDS];
uint64_t nblocks;
uint8_t block[SHA384_BLOCK_SIZE];
size_t num;
} SHA384_CTX;
void sha384_init(SHA384_CTX *ctx);
void sha384_update(SHA384_CTX *ctx, const uint8_t* data, size_t datalen);
void sha384_finish(SHA384_CTX *ctx, uint8_t dgst[SHA384_DIGEST_SIZE]);
void sha384_digest(const uint8_t *data, size_t datalen,
uint8_t dgst[SHA384_DIGEST_SIZE]);
#define SHA512_DIGEST_SIZE 64
#define SHA512_BLOCK_SIZE 128
#define SHA512_STATE_WORDS 8
typedef struct {
uint64_t state[SHA512_STATE_WORDS];
uint64_t nblocks;
uint8_t block[SHA512_BLOCK_SIZE];
size_t num;
} SHA512_CTX;
void sha512_init(SHA512_CTX *ctx);
void sha512_update(SHA512_CTX *ctx, const uint8_t* data, size_t datalen);
void sha512_finish(SHA512_CTX *ctx, uint8_t dgst[SHA512_DIGEST_SIZE]);
void sha512_digest(const uint8_t *data, size_t datalen,
uint8_t dgst[SHA512_DIGEST_SIZE]);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SHA3_H
#define GMSSL_SHA3_H
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SHA3_KECCAK_P_SIZE (1600/8)
#define SHA3_224_DIGEST_SIZE (224/8)
#define SHA3_256_DIGEST_SIZE (256/8)
#define SHA3_384_DIGEST_SIZE (384/8)
#define SHA3_512_DIGEST_SIZE (512/8)
#define SHA3_224_CAPACITY (SHA3_224_DIGEST_SIZE * 2)
#define SHA3_256_CAPACITY (SHA3_256_DIGEST_SIZE * 2)
#define SHA3_384_CAPACITY (SHA3_384_DIGEST_SIZE * 2)
#define SHA3_512_CAPACITY (SHA3_512_DIGEST_SIZE * 2)
#define SHA3_224_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 144
#define SHA3_256_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 136
#define SHA3_384_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 104
#define SHA3_512_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 72
typedef struct {
uint64_t A[5][5];
uint8_t buf[SHA3_224_BLOCK_SIZE];
int num;
} SHA3_224_CTX;
void sha3_224_init(SHA3_224_CTX *ctx);
void sha3_224_update(SHA3_224_CTX *ctx, const uint8_t *data, size_t datalen);
void sha3_224_finish(SHA3_224_CTX *ctx, uint8_t dgst[SHA3_224_DIGEST_SIZE]);
typedef struct {
uint64_t A[5][5];
uint8_t buf[SHA3_256_BLOCK_SIZE];
int num;
} SHA3_256_CTX;
void sha3_256_init(SHA3_256_CTX *ctx);
void sha3_256_update(SHA3_256_CTX *ctx, const uint8_t *data, size_t datalen);
void sha3_256_finish(SHA3_256_CTX *ctx, uint8_t dgst[SHA3_256_DIGEST_SIZE]);
typedef struct {
uint64_t A[5][5];
uint8_t buf[SHA3_384_BLOCK_SIZE];
int num;
} SHA3_384_CTX;
void sha3_384_init(SHA3_384_CTX *ctx);
void sha3_384_update(SHA3_384_CTX *ctx, const uint8_t *data, size_t datalen);
void sha3_384_finish(SHA3_384_CTX *ctx, uint8_t dgst[SHA3_384_DIGEST_SIZE]);
typedef struct {
uint64_t A[5][5];
uint8_t buf[SHA3_512_BLOCK_SIZE];
int num;
} SHA3_512_CTX;
void sha3_512_init(SHA3_512_CTX *ctx);
void sha3_512_update(SHA3_512_CTX *ctx, const uint8_t *data, size_t datalen);
void sha3_512_finish(SHA3_512_CTX *ctx, uint8_t dgst[SHA3_512_DIGEST_SIZE]);
void sha3_shake128(const uint8_t *in, size_t *inlen, size_t outlen, uint8_t *out);
void sha3_shake256(const uint8_t *in, size_t *inlen, size_t outlen, uint8_t *out);
void sha3_keccak_p(uint8_t state[SHA3_KECCAK_P_SIZE]);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,116 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SKF_H
#define GMSSL_SKF_H
#include <string.h>
#include <stdint.h>
#include <gmssl/sm2.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
SKF Public API
skf_load_library
skf_unload_library
skf_list_devices
skf_print_device_info
SKF_DEVICE
skf_open_device
skf_close_deivce
skf_set_label
skf_change_authkey
skf_list_apps
skf_create_app
skf_delete_app
skf_change_app_admin_pin
skf_change_app_user_pin
skf_unblock_user_pin
skf_list_objects
skf_import_object
skf_export_object
skf_delete_object
skf_list_containers
skf_create_container
skf_delete_container
skf_import_sign_cert
skf_export_sign_cert
skf_rand_bytes
skf_load_sign_key
SKF_KEY
skf_sign
skf_release_key
*/
typedef struct {
void *handle;
char manufacturer[65];
char issuer[65];
char label[33];
char serial[33];
uint8_t hardware_version[2];
uint8_t firmware_version[2];
} SKF_DEVICE;
typedef struct {
SM2_KEY public_key;
void *app_handle;
char app_name[65];
void *container_handle;
char container_name[65];
} SKF_KEY;
int skf_load_library(const char *so_path, const char *vendor);
void skf_unload_library(void);
int skf_list_devices(FILE *fp, int fmt, int ind, const char *label);
int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname);
int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16]);
int skf_set_label(SKF_DEVICE *dev, const char *label);
int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16]);
int skf_close_device(SKF_DEVICE *dev);
int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp);
int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin);
int skf_delete_app(SKF_DEVICE *dev, const char *appname);
int skf_change_app_admin_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin);
int skf_change_app_user_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin);
int skf_unblock_user_pin(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *new_user_pin);
int skf_list_objects(FILE *fp, int fmt, int ind, const char *label, SKF_DEVICE *dev, const char *appname, const char *pin);
int skf_import_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname, const uint8_t *data, size_t datalen);
int skf_export_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname, uint8_t *out, size_t *outlen);
int skf_delete_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname);
int skf_list_containers(FILE *fp, int fmt, int ind, const char *label, SKF_DEVICE *dev, const char *appname, const char *pin);
int skf_create_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name);
int skf_delete_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name);
int skf_import_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, const uint8_t *cert, size_t certlen);
int skf_export_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, uint8_t *cert, size_t *certlen);
int skf_rand_bytes(SKF_DEVICE *dev, uint8_t *buf, size_t len);
int skf_load_sign_key(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, SKF_KEY *key);
int skf_sign(SKF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen);
int skf_release_key(SKF_KEY *key);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,382 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM2_H
#define GMSSL_SM2_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm3.h>
#include <gmssl/api.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
SM2 Public API
SM2_DEFAULT_ID
SM2_MAX_ID_LENGTH
SM2_MAX_SIGNATURE_SIZE
SM2_MAX_PLAINTEXT_SIZE
SM2_MAX_CIPHERTEXT_SIZE
SM2_KEY
sm2_key_generate
sm2_private_key_info_encrypt_to_der
sm2_private_key_info_decrypt_from_der
sm2_private_key_info_encrypt_to_pem
sm2_private_key_info_decrypt_from_pem
sm2_public_key_info_to_der
sm2_public_key_info_from_der
sm2_public_key_info_to_pem
sm2_public_key_info_from_pem
sm2_sign
sm2_verify
sm2_encrypt
sm2_decrypt
sm2_ecdh
SM2_SIGN_CTX
sm2_sign_init
sm2_sign_update
sm2_sign_finish
sm2_verify_init
sm2_verify_update
sm2_verify_finish
*/
typedef uint64_t SM2_BN[8];
int sm2_bn_is_zero(const SM2_BN a);
int sm2_bn_is_one(const SM2_BN a);
int sm2_bn_is_odd(const SM2_BN a);
int sm2_bn_cmp(const SM2_BN a, const SM2_BN b);
int sm2_bn_from_hex(SM2_BN r, const char hex[64]);
int sm2_bn_from_asn1_integer(SM2_BN r, const uint8_t *d, size_t dlen);
int sm2_bn_equ_hex(const SM2_BN a, const char *hex);
int sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const SM2_BN a);
int sm2_bn_rshift(SM2_BN ret, const SM2_BN a, unsigned int nbits);
void sm2_bn_to_bytes(const SM2_BN a, uint8_t out[32]);
void sm2_bn_from_bytes(SM2_BN r, const uint8_t in[32]);
void sm2_bn_to_hex(const SM2_BN a, char hex[64]);
void sm2_bn_to_bits(const SM2_BN a, char bits[256]);
void sm2_bn_set_word(SM2_BN r, uint32_t a);
void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b);
void sm2_bn_sub(SM2_BN ret, const SM2_BN a, const SM2_BN b);
int sm2_bn_rand_range(SM2_BN r, const SM2_BN range);
#define sm2_bn_init(r) memset((r),0,sizeof(SM2_BN))
#define sm2_bn_set_zero(r) memset((r),0,sizeof(SM2_BN))
#define sm2_bn_set_one(r) sm2_bn_set_word((r),1)
#define sm2_bn_copy(r,a) memcpy((r),(a),sizeof(SM2_BN))
#define sm2_bn_clean(r) memset((r),0,sizeof(SM2_BN))
// GF(p)
typedef SM2_BN SM2_Fp;
void sm2_fp_add(SM2_Fp r, const SM2_Fp a, const SM2_Fp b);
void sm2_fp_sub(SM2_Fp r, const SM2_Fp a, const SM2_Fp b);
void sm2_fp_mul(SM2_Fp r, const SM2_Fp a, const SM2_Fp b);
void sm2_fp_exp(SM2_Fp r, const SM2_Fp a, const SM2_Fp e);
void sm2_fp_dbl(SM2_Fp r, const SM2_Fp a);
void sm2_fp_tri(SM2_Fp r, const SM2_Fp a);
void sm2_fp_div2(SM2_Fp r, const SM2_Fp a);
void sm2_fp_neg(SM2_Fp r, const SM2_Fp a);
void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a);
void sm2_fp_inv(SM2_Fp r, const SM2_Fp a);
int sm2_fp_rand(SM2_Fp r);
int sm2_fp_sqrt(SM2_Fp r, const SM2_Fp a);
#define sm2_fp_init(r) sm2_bn_init(r)
#define sm2_fp_set_zero(r) sm2_bn_set_zero(r)
#define sm2_fp_set_one(r) sm2_bn_set_one(r)
#define sm2_fp_copy(r,a) sm2_bn_copy(r,a)
#define sm2_fp_clean(r) sm2_bn_clean(r)
// GF(n)
typedef SM2_BN SM2_Fn;
void sm2_fn_add(SM2_Fn r, const SM2_Fn a, const SM2_Fn b);
void sm2_fn_sub(SM2_Fn r, const SM2_Fn a, const SM2_Fn b);
void sm2_fn_mul(SM2_Fn r, const SM2_Fn a, const SM2_Fn b);
void sm2_fn_mul_word(SM2_Fn r, const SM2_Fn a, uint32_t b);
void sm2_fn_exp(SM2_Fn r, const SM2_Fn a, const SM2_Fn e);
void sm2_fn_neg(SM2_Fn r, const SM2_Fn a);
void sm2_fn_sqr(SM2_Fn r, const SM2_Fn a);
void sm2_fn_inv(SM2_Fn r, const SM2_Fn a);
int sm2_fn_rand(SM2_Fn r);
#define sm2_fn_init(r) sm2_bn_init(r)
#define sm2_fn_set_zero(r) sm2_bn_set_zero(r)
#define sm2_fn_set_one(r) sm2_bn_set_one(r)
#define sm2_fn_copy(r,a) sm2_bn_copy(r,a)
#define sm2_fn_clean(r) sm2_bn_clean(r)
typedef struct {
SM2_BN X;
SM2_BN Y;
SM2_BN Z;
} SM2_JACOBIAN_POINT;
void sm2_jacobian_point_init(SM2_JACOBIAN_POINT *R);
void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y);
void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT *P, SM2_BN x, SM2_BN y);
void sm2_jacobian_point_neg(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P);
void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P);
void sm2_jacobian_point_add(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q);
void sm2_jacobian_point_sub(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q);
void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT *R, const SM2_BN k, const SM2_JACOBIAN_POINT *P);
void sm2_jacobian_point_to_bytes(const SM2_JACOBIAN_POINT *P, uint8_t out[64]);
void sm2_jacobian_point_from_bytes(SM2_JACOBIAN_POINT *P, const uint8_t in[64]);
void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT *R, const SM2_BN k);
void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s);
void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]); // for testing only
int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT *P);
int sm2_jacobian_point_is_on_curve(const SM2_JACOBIAN_POINT *P);
int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]); // for testing only
int sm2_jacobian_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_JACOBIAN_POINT *P);
#define sm2_jacobian_point_set_infinity(R) sm2_jacobian_point_init(R)
#define sm2_jacobian_point_copy(R, P) memcpy((R), (P), sizeof(SM2_JACOBIAN_POINT))
typedef uint8_t sm2_bn_t[32];
typedef struct {
uint8_t x[32];
uint8_t y[32];
} SM2_POINT;
#define sm2_point_init(P) memset((P),0,sizeof(SM2_POINT))
#define sm2_point_set_infinity(P) sm2_point_init(P)
int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen);
void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]);
void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]);
int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y);
int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]);
int sm2_point_is_on_curve(const SM2_POINT *P);
int sm2_point_is_at_infinity(const SM2_POINT *P);
int sm2_point_add(SM2_POINT *R, const SM2_POINT *P, const SM2_POINT *Q);
int sm2_point_sub(SM2_POINT *R, const SM2_POINT *P, const SM2_POINT *Q);
int sm2_point_neg(SM2_POINT *R, const SM2_POINT *P);
int sm2_point_dbl(SM2_POINT *R, const SM2_POINT *P);
int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P);
int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]);
int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]); // R = k * P + s * G
/*
RFC 5480 Elliptic Curve Cryptography Subject Public Key Information
ECPoint ::= OCTET STRING
*/
#define SM2_POINT_MAX_SIZE (2 + 65)
int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen);
int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen);
int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P);
int sm2_point_from_hash(SM2_POINT *R, const uint8_t *data, size_t datalen);
typedef struct {
SM2_POINT public_key;
uint8_t private_key[32];
} SM2_KEY;
_gmssl_export int sm2_key_generate(SM2_KEY *key);
int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]); // key->public_key will be replaced
int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key); // key->private_key will be cleared // FIXME: support octets as input?
int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key);
int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key);
//int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key); // do we need this?
int sm2_public_key_digest(const SM2_KEY *key, uint8_t dgst[32]);
int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key);
/*
from RFC 5915
ECPrivateKey ::= SEQUENCE {
version INTEGER, -- value MUST be (1)
privateKey OCTET STRING, -- big endian encoding of integer 这里不是以INTEGER编码的因此长度固定
parameters [0] EXPLICIT ECParameters OPTIONAL,
-- ONLY namedCurve OID is permitted, by RFC 5480
-- MUST always include this field, by RFC 5915
publicKey [1] EXPLICIT BIT STRING OPTIONAL -- compressed_point
-- SHOULD always include this field, by RFC 5915 }
ECParameters ::= CHOICE { namedCurve OBJECT IDENTIFIER }
*/
#define SM2_PRIVATE_KEY_DEFAULT_SIZE 120 // generated
#define SM2_PRIVATE_KEY_BUF_SIZE 512 // MUST >= SM2_PRIVATE_KEY_DEFAULT_SIZE
int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen);
int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen);
int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int sm2_private_key_to_pem(const SM2_KEY *key, FILE *fp);
int sm2_private_key_from_pem(SM2_KEY *key, FILE *fp);
/*
AlgorithmIdentifier ::= {
algorithm OBJECT IDENTIFIER { id-ecPublicKey },
parameters OBJECT IDENTIFIER { id-sm2 } }
*/
int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen);
int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen);
/*
SubjectPublicKeyInfo from RFC 5280
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING -- uncompressed octets of ECPoint }
*/
_gmssl_export int sm2_public_key_info_to_der(const SM2_KEY *a, uint8_t **out, size_t *outlen);
_gmssl_export int sm2_public_key_info_from_der(SM2_KEY *a, const uint8_t **in, size_t *inlen);
_gmssl_export int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp);
_gmssl_export int sm2_public_key_info_from_pem(SM2_KEY *a, FILE *fp);
/*
PKCS #8 PrivateKeyInfo from RFC 5208
PrivateKeyInfo ::= SEQUENCE {
version Version { v1(0) },
privateKeyAlgorithm AlgorithmIdentifier,
privateKey OCTET STRING, -- DER-encoding of ECPrivateKey
attributes [0] IMPLICIT SET OF Attribute OPTIONAL }
*/
enum {
PKCS8_private_key_info_version = 0,
};
int sm2_private_key_info_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen);
int sm2_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, const uint8_t **in, size_t *inlen);
int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp);
// FIXME: #define default buffer size for sm2_private_key_info_from_pem
int sm2_private_key_info_from_pem(SM2_KEY *key, FILE *fp);
/*
EncryptedPrivateKeyInfo ::= SEQUENCE {
encryptionAlgorithm EncryptionAlgorithmIdentifier, -- id-PBES2
encryptedData OCTET STRING }
*/
_gmssl_export int sm2_private_key_info_encrypt_to_der(const SM2_KEY *key,
const char *pass, uint8_t **out, size_t *outlen);
_gmssl_export int sm2_private_key_info_decrypt_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrs_len,
const char *pass, const uint8_t **in, size_t *inlen);
_gmssl_export int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *key, const char *pass, FILE *fp);
// FIXME: #define default buffer size
_gmssl_export int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp);
typedef struct {
uint8_t r[32];
uint8_t s[32];
} SM2_SIGNATURE;
int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig);
int sm2_do_sign_fast(const SM2_Fn d, const uint8_t dgst[32], SM2_SIGNATURE *sig);
int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig);
#define SM2_MIN_SIGNATURE_SIZE 8
#define SM2_MAX_SIGNATURE_SIZE 72
int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen);
int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen);
int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
_gmssl_export int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen);
_gmssl_export int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen);
enum {
SM2_signature_compact_size = 70,
SM2_signature_typical_size = 71,
SM2_signature_max_size = 72,
};
int sm2_sign_fixlen(const SM2_KEY *key, const uint8_t dgst[32], size_t siglen, uint8_t *sig);
#define SM2_DEFAULT_ID "1234567812345678"
#define SM2_DEFAULT_ID_LENGTH (sizeof(SM2_DEFAULT_ID) - 1) // LENGTH for string and SIZE for bytes
#define SM2_DEFAULT_ID_BITS (SM2_DEFAULT_ID_LENGTH * 8)
#define SM2_MAX_ID_BITS 65535
#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8)
int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen);
typedef struct {
SM3_CTX sm3_ctx;
SM2_KEY key;
} SM2_SIGN_CTX;
_gmssl_export int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen);
_gmssl_export int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
_gmssl_export int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen);
int sm2_sign_finish_fixlen(SM2_SIGN_CTX *ctx, size_t siglen, uint8_t *sig);
_gmssl_export int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen);
_gmssl_export int sm2_verify_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
_gmssl_export int sm2_verify_finish(SM2_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen);
/*
SM2Cipher ::= SEQUENCE {
XCoordinate INTEGER,
YCoordinate INTEGER,
HASH OCTET STRING SIZE(32),
CipherText OCTET STRING }
*/
#define SM2_MIN_PLAINTEXT_SIZE 1 // re-compute SM2_MIN_CIPHERTEXT_SIZE when modify
#define SM2_MAX_PLAINTEXT_SIZE 255 // re-compute SM2_MAX_CIPHERTEXT_SIZE when modify
typedef struct {
SM2_POINT point;
uint8_t hash[32];
uint8_t ciphertext_size;
uint8_t ciphertext[SM2_MAX_PLAINTEXT_SIZE];
} SM2_CIPHERTEXT;
int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out);
int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen);
#define SM2_MIN_CIPHERTEXT_SIZE 45 // depends on SM2_MIN_PLAINTEXT_SIZE
#define SM2_MAX_CIPHERTEXT_SIZE 366 // depends on SM2_MAX_PLAINTEXT_SIZE
int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *c, uint8_t **out, size_t *outlen);
int sm2_ciphertext_from_der(SM2_CIPHERTEXT *c, const uint8_t **in, size_t *inlen);
int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
_gmssl_export int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
_gmssl_export int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
enum {
SM2_ciphertext_compact_point_size = 68,
SM2_ciphertext_typical_point_size = 69,
SM2_ciphertext_max_point_size = 70,
};
int sm2_do_encrypt_fixlen(const SM2_KEY *key, const uint8_t *in, size_t inlen, int point_size, SM2_CIPHERTEXT *out);
int sm2_encrypt_fixlen(const SM2_KEY *key, const uint8_t *in, size_t inlen, int point_size, uint8_t *out, size_t *outlen);
int sm2_do_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out);
_gmssl_export int sm2_ecdh(const SM2_KEY *key, const uint8_t *peer_public, size_t peer_public_len, SM2_POINT *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM2_BLIND_H
#define GMSSL_SM2_BLIND_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <gmssl/sm2.h>
#include <gmssl/mem.h>
#include <gmssl/asn1.h>
#include <gmssl/error.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
SM3_CTX sm3_ctx;
SM2_KEY public_key;
uint8_t blind_factor_a[32];
uint8_t blind_factor_b[32];
uint8_t sig_r[32];
} SM2_BLIND_SIGN_CTX;
#define SM2_BLIND_SIGN_MAX_COMMITLEN 65
int sm2_blind_sign_commit(SM2_Fn k, uint8_t *commit, size_t *commitlen);
int sm2_blind_sign_init(SM2_BLIND_SIGN_CTX *ctx, const SM2_KEY *public_key, const char *id, size_t idlen);
int sm2_blind_sign_update(SM2_BLIND_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
int sm2_blind_sign_finish(SM2_BLIND_SIGN_CTX *ctx, const uint8_t *commit, size_t commitlen, uint8_t blinded_sig_r[32]);
int sm2_blind_sign(const SM2_KEY *key, const SM2_Fn k, const uint8_t blinded_sig_r[32], uint8_t blinded_sig_s[32]);
int sm2_blind_sign_unblind(SM2_BLIND_SIGN_CTX *ctx, const uint8_t blinded_sig_s[32], uint8_t *sig, size_t *siglen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM2_COMMIT_H
#define GMSSL_SM2_COMMIT_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <stdint.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/mem.h>
#include <gmssl/asn1.h>
#include <gmssl/rand.h>
#include <gmssl/error.h>
#ifdef __cplusplus
extern "C" {
#endif
int sm2_commit_generate(const uint8_t x[32], uint8_t r[32], uint8_t commit[65], size_t *commitlen);
int sm2_commit_open(const uint8_t x[32], const uint8_t r[32], const uint8_t *commit, size_t commitlen);
int sm2_commit_vector_generate(const sm2_bn_t *x, size_t count, uint8_t r[32], uint8_t commit[65], size_t *commitlen);
int sm2_commit_vector_open(const sm2_bn_t *x, size_t count, const uint8_t r[32], const uint8_t *commit, size_t commitlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM2_ELGAMAL_H
#define GMSSL_SM2_ELGAMAL_H
#include <string.h>
#include <stdint.h>
#include <gmssl/sm2.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SM2_PRE_COMPUTE_MAX_OFFSETS 6
typedef struct {
uint16_t offset[SM2_PRE_COMPUTE_MAX_OFFSETS];
uint8_t offset_count;
uint8_t x_coordinate[32];
} SM2_PRE_COMPUTE;
int sm2_elgamal_decrypt_pre_compute(SM2_PRE_COMPUTE table[1<<16]);
int sm2_elgamal_solve_ecdlp(const SM2_PRE_COMPUTE table[1<<16], const SM2_POINT *point, uint32_t *private);
typedef struct {
SM2_POINT C1;
SM2_POINT C2;
} SM2_ELGAMAL_CIPHERTEXT;
int sm2_elgamal_do_encrypt(const SM2_KEY *pub_key, uint32_t in, SM2_ELGAMAL_CIPHERTEXT *out);
int sm2_elgamal_do_decrypt(const SM2_KEY *key, const SM2_ELGAMAL_CIPHERTEXT *in, uint32_t *out);
int sm2_elgamal_ciphertext_add(SM2_ELGAMAL_CIPHERTEXT *r,
const SM2_ELGAMAL_CIPHERTEXT *a,
const SM2_ELGAMAL_CIPHERTEXT *b,
const SM2_KEY *pub_key);
int sm2_elgamal_cipehrtext_sub(SM2_ELGAMAL_CIPHERTEXT *r,
const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_ELGAMAL_CIPHERTEXT *b,
const SM2_KEY *pub_key);
int sm2_elgamal_cipehrtext_neg(SM2_ELGAMAL_CIPHERTEXT *r,
const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_KEY *pub_key);
int sm2_elgamal_ciphertext_scalar_mul(SM2_ELGAMAL_CIPHERTEXT *R,
const uint8_t scalar[32], const SM2_ELGAMAL_CIPHERTEXT *A,
const SM2_KEY *pub_key);
int sm2_elgamal_ciphertext_to_der(const SM2_ELGAMAL_CIPHERTEXT *c, uint8_t **out, size_t *outlen);
int sm2_elgamal_ciphertext_from_der(SM2_ELGAMAL_CIPHERTEXT *c, const uint8_t **in, size_t *inlen);
int sm2_elgamal_encrypt(const SM2_KEY *pub_key, uint32_t in, uint8_t *out, size_t *outlen);
int sm2_elgamal_decrypt(SM2_KEY *key, const uint8_t *in, size_t inlen, uint32_t *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
// SM2 Key Shamir Secret Sharing
#ifndef GMSSL_SM2_KEY_SHARE_H
#define GMSSL_SM2_KEY_SHARE_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm2.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SM2_KEY_MAX_SHARES 12 // 12! = 479001600 < 2^31 = 2147483648
typedef struct {
SM2_KEY key;
size_t index;
size_t total_cnt;
} SM2_KEY_SHARE;
int sm2_key_split(const SM2_KEY *key, size_t recover_cnt, size_t total_cnt, SM2_KEY_SHARE *shares);
int sm2_key_recover(SM2_KEY *key, const SM2_KEY_SHARE *shares, size_t shares_cnt);
int sm2_key_share_encrypt_to_file(const SM2_KEY_SHARE *share, const char *pass, const char *path_prefix);
int sm2_key_share_decrypt_from_file(SM2_KEY_SHARE *share, const char *pass, const char *file);
int sm2_key_share_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY_SHARE *share);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM2_RECOVER_H
#define GMSSL_SM2_RECOVER_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm3.h>
#ifdef __cplusplus
extern "C" {
#endif
int sm2_signature_to_public_key_points(const SM2_SIGNATURE *sig, const uint8_t dgst[32],
SM2_POINT points[4], size_t *points_cnt);
int sm2_signature_conjugate(const SM2_SIGNATURE *sig, SM2_SIGNATURE *new_sig);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM2_RING_H
#define GMSSL_SM2_RING_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm2.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint8_t sm2_bn_t[32];
int sm2_ring_do_sign(const SM2_KEY *sign_key, const SM2_POINT *public_keys, size_t public_keys_cnt,
const uint8_t dgst[32], uint8_t r[32], sm2_bn_t *s);
int sm2_ring_do_verify(const SM2_POINT *public_keys, size_t public_keys_cnt,
const uint8_t dgst[32], const uint8_t r[32], const sm2_bn_t *s);
int sm2_ring_signature_to_der(const sm2_bn_t r, const sm2_bn_t *s, size_t s_cnt, uint8_t **out, size_t *outlen);
int sm2_ring_signature_from_der(sm2_bn_t r, sm2_bn_t *s, size_t *s_cnt, const uint8_t **in, size_t *inlen);
int sm2_ring_sign(const SM2_KEY *sign_key, const SM2_POINT *public_keys, size_t public_keys_cnt,
const uint8_t dgst[32], uint8_t *sig, size_t *siglen);
int sm2_ring_verify(const SM2_POINT *public_keys, size_t public_keys_cnt,
const uint8_t dgst[32], const uint8_t *sig, size_t siglen);
#define SM2_RING_SIGN_MAX_SIGNERS 32
typedef struct {
int state;
SM3_CTX sm3_ctx;
SM2_KEY sign_key;
SM2_POINT public_keys[SM2_RING_SIGN_MAX_SIGNERS];
size_t public_keys_count;
char *id;
size_t idlen;
} SM2_RING_SIGN_CTX;
int sm2_ring_sign_init(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *sign_key, const char *id, size_t idlen);
int sm2_ring_sign_add_signer(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *public_key);
int sm2_ring_sign_update(SM2_RING_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
int sm2_ring_sign_finish(SM2_RING_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen);
int sm2_ring_verify_init(SM2_RING_SIGN_CTX *ctx, const char *id, size_t idlen);
int sm2_ring_verify_add_signer(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *public_key);
int sm2_ring_verify_update(SM2_RING_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
int sm2_ring_verify_finish(SM2_RING_SIGN_CTX *ctx, uint8_t *sig, size_t siglen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM3_H
#define GMSSL_SM3_H
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
SM3 Public API
SM3_DIGEST_SIZE
SM3_HMAC_SIZE
SM3_CTX
sm3_init
sm3_update
sm3_finish
SM3_HMAC_CTX
sm3_hmac_init
sm3_hmac_update
sm3_hmac_finish
sm3_digest
sm3_hmac
*/
#define SM3_IS_BIG_ENDIAN 1
#define SM3_DIGEST_SIZE 32
#define SM3_BLOCK_SIZE 64
#define SM3_STATE_WORDS 8
#define SM3_HMAC_SIZE (SM3_DIGEST_SIZE)
typedef struct {
uint32_t digest[SM3_STATE_WORDS];
uint64_t nblocks;
uint8_t block[SM3_BLOCK_SIZE];
size_t num;
} SM3_CTX;
void sm3_init(SM3_CTX *ctx);
void sm3_update(SM3_CTX *ctx, const uint8_t *data, size_t datalen);
void sm3_finish(SM3_CTX *ctx, uint8_t dgst[SM3_DIGEST_SIZE]);
void sm3_digest(const uint8_t *data, size_t datalen, uint8_t dgst[SM3_DIGEST_SIZE]);
void sm3_compress_blocks(uint32_t digest[8], const uint8_t *data, size_t blocks);
typedef struct {
SM3_CTX sm3_ctx;
uint8_t key[SM3_BLOCK_SIZE];
} SM3_HMAC_CTX;
void sm3_hmac_init(SM3_HMAC_CTX *ctx, const uint8_t *key, size_t keylen);
void sm3_hmac_update(SM3_HMAC_CTX *ctx, const uint8_t *data, size_t datalen);
void sm3_hmac_finish(SM3_HMAC_CTX *ctx, uint8_t mac[SM3_HMAC_SIZE]);
void sm3_hmac(const uint8_t *key, size_t keylen,
const uint8_t *data, size_t datalen,
uint8_t mac[SM3_HMAC_SIZE]);
typedef struct {
SM3_CTX sm3_ctx;
size_t outlen;
} SM3_KDF_CTX;
void sm3_kdf_init(SM3_KDF_CTX *ctx, size_t outlen);
void sm3_kdf_update(SM3_KDF_CTX *ctx, const uint8_t *data, size_t datalen);
void sm3_kdf_finish(SM3_KDF_CTX *ctx, uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM3_RNG_H
#define GMSSL_SM3_RNG_H
#include <time.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SM3_RNG_MAX_RESEED_COUNTER (1<<20)
#define SM3_RNG_MAX_RESEED_SECONDS 600
typedef struct {
uint8_t V[55];
uint8_t C[55];
uint32_t reseed_counter;
time_t last_reseed_time;
} SM3_RNG;
int sm3_rng_init(SM3_RNG *rng, const uint8_t *nonce, size_t nonce_len,
const uint8_t *label, size_t label_len);
int sm3_rng_reseed(SM3_RNG *rng, const uint8_t *addin, size_t addin_len);
int sm3_rng_generate(SM3_RNG *rng, const uint8_t *addin, size_t addin_len,
uint8_t *out, size_t outlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM3_X8_AVX2_H
#define GMSSL_SM3_X8_AVX2_H
#include <stdint.h>
#include <immintrin.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
__m256i digest[8];
} SM3_X8_CTX;
void sm3_x8_init(SM3_X8_CTX *ctx);
void sm3_x8_compress_blocks(__m256i digest[8], const uint8_t *data, size_t datalen);
void sm3_x8_digest(const uint8_t *data, size_t datalen, uint8_t dgst[8][32]);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,142 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM4_H
#define GMSSL_SM4_H
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
SM4 Public API
SM4_KEY_SIZE
SM4_BLOCK_SIZE
SM4_CBC_CTX
sm4_cbc_encrypt_init
sm4_cbc_encrypt_update
sm4_cbc_encrypt_finish
sm4_cbc_decrypt_init
sm4_cbc_decrypt_update
sm4_cbc_decrypt_finish
SM4_CTR_CTX
sm4_ctr_encrypt_init
sm4_ctr_encrypt_update
sm4_ctr_encrypt_finish
sm4_ctr_decrypt_init
sm4_ctr_decrypt_update
sm4_ctr_decrypt_finish
*/
#define SM4_KEY_SIZE (16)
#define SM4_BLOCK_SIZE (16)
#define SM4_NUM_ROUNDS (32)
typedef struct {
uint32_t rk[SM4_NUM_ROUNDS];
} SM4_KEY;
void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]);
void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]);
void sm4_encrypt(const SM4_KEY *key, const uint8_t in[SM4_BLOCK_SIZE], uint8_t out[SM4_BLOCK_SIZE]);
#define sm4_decrypt(key,in,out) sm4_encrypt(key,in,out)
void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE],
const uint8_t *in, size_t nblocks, uint8_t *out);
void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE],
const uint8_t *in, size_t nblocks, uint8_t *out);
int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[SM4_BLOCK_SIZE],
const uint8_t *in, size_t inlen, uint8_t *out);
#define sm4_ctr_decrypt(key,ctr,in,inlen,out) sm4_ctr_encrypt(key,ctr,in,inlen,out)
#define SM4_GCM_IV_MIN_SIZE 1
#define SM4_GCM_IV_MAX_SIZE (((uint64_t)1 << (64-3)) - 1) // 2305843009213693951
#define SM4_GCM_IV_DEFAULT_BITS 96
#define SM4_GCM_IV_DEFAULT_SIZE 12
//#define NIST_SP800_GCM_MAX_IV_SIZE (((uint64_t)1 << (64-3)) - 1) // 2305843009213693951
#define SM4_GCM_MAX_IV_SIZE 64
#define SM4_GCM_MIN_IV_SIZE 1
#define SM4_GCM_DEFAULT_IV_SIZE 12
#define SM4_GCM_MIN_AAD_SIZE 0
#define SM4_GCM_MAX_AAD_SIZE (((uint64_t)1 << (64-3)) - 1) // 2305843009213693951
#define SM4_GCM_MIN_PLAINTEXT_SIZE 0
#define SM4_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) // 68719476704
#define SM4_GCM_MAX_TAG_SIZE 16
#define SM4_GCM_MIN_TAG_SIZE 12
// For certain applications (voice or video), tag may be 64 or 32 bits
// see NIST Special Publication 800-38D, Appendix C for more details
int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
uint8_t *out, size_t taglen, uint8_t *tag);
int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
const uint8_t *tag, size_t taglen, uint8_t *out);
typedef struct {
SM4_KEY sm4_key;
uint8_t iv[SM4_BLOCK_SIZE];
uint8_t block[SM4_BLOCK_SIZE];
size_t block_nbytes;
} SM4_CBC_CTX;
int sm4_cbc_encrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]);
int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen);
int sm4_cbc_decrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]);
int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen);
typedef struct {
SM4_KEY sm4_key;
uint8_t ctr[SM4_BLOCK_SIZE];
uint8_t block[SM4_BLOCK_SIZE];
size_t block_nbytes;
} SM4_CTR_CTX;
int sm4_ctr_encrypt_init(SM4_CTR_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t ctr[SM4_BLOCK_SIZE]);
int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int sm4_ctr_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen);
#define sm4_ctr_decrypt_init(ctx,key,ctr) sm4_ctr_encrypt_init(ctx,key,ctr)
#define sm4_ctr_decrypt_update(ctx,in,inlen,out,outlen) sm4_ctr_encrypt_update(ctx,in,inlen,out,outlen)
#define sm4_ctr_decrypt_finish(ctx,out,outlen) sm4_ctr_encrypt_finish(ctx,out,outlen)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM4_CBC_MAC_H
#define GMSSL_SM4_CBC_MAC_H
#include <stdint.h>
#include <gmssl/sm4.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
SM4_KEY key;
uint8_t iv[16];
size_t ivlen;
} SM4_CBC_MAC_CTX;
void sm4_cbc_mac_init(SM4_CBC_MAC_CTX *ctx, const uint8_t key[16]);
void sm4_cbc_mac_update(SM4_CBC_MAC_CTX *ctx, const uint8_t *data, size_t datalen);
void sm4_cbc_mac_finish(SM4_CBC_MAC_CTX *ctx, uint8_t mac[16]);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM4_CL_H
#define GMSSL_SM4_CL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <gmssl/sm4.h>
#ifdef APPLE
#include <OpenCL/OpenCL.h>
#else
#include <CL/cl.h>
#endif
typedef struct {
uint32_t rk[32];
cl_context context;
cl_command_queue queue;
cl_program program;
cl_kernel kernel;
cl_mem mem_rk;
cl_mem mem_io;
size_t workgroup_size;
} SM4_CL_CTX;
int sm4_cl_set_encrypt_key(SM4_CL_CTX *ctx, const uint8_t key[16]);
int sm4_cl_set_decrypt_key(SM4_CL_CTX *ctx, const uint8_t key[16]);
int sm4_cl_encrypt(SM4_CL_CTX *ctx, const uint8_t *in, size_t nblocks, uint8_t *out);
void sm4_cl_cleanup(SM4_CL_CTX *ctx);
int test_sm4_cl_encrypt(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM4_RNG_H
#define GMSSL_SM4_RNG_H
#include <time.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SM4_RNG_MAX_RESEED_COUNTER (1<<20)
#define SM4_RNG_MAX_RESEED_SECONDS 600
typedef struct {
uint8_t V[16];
uint8_t K[16];
uint32_t reseed_counter;
time_t last_reseed_time;
} SM4_RNG;
int sm4_rng_init(SM4_RNG *rng, const uint8_t *nonce, size_t nonce_len,
const uint8_t *label, size_t label_len);
int sm4_rng_update(SM4_RNG *rng, const uint8_t seed[32]);
int sm4_rng_reseed(SM4_RNG *rng, const uint8_t *addin, size_t addin_len);
int sm4_rng_generate(SM4_RNG *rng, const uint8_t *addin, size_t addin_len,
uint8_t *out, size_t outlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,561 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <gmssl/sm3.h>
#include <gmssl/sm2.h>
#ifndef GMSSL_SM9_H
#define GMSSL_SM9_H
#ifdef __cplusplus
extern "C" {
#endif
/*
SM9 Public API
SM9_SIGNATURE_SIZE
SM9_MAX_PLAINTEXT_SIZE
SM9_MAX_CIPHERTEXT_SIZE
SM9_SIGN_MASTER_KEY
sm9_sign_master_key_generate
sm9_sign_master_key_extract_key
sm9_sign_master_key_info_encrypt_to_der
sm9_sign_master_key_info_decrypt_from_der
sm9_sign_master_key_info_encrypt_to_pem
sm9_sign_master_key_info_decrypt_from_pem
sm9_sign_master_public_key_to_der
sm9_sign_master_public_key_from_der
sm9_sign_master_public_key_to_pem
sm9_sign_master_public_key_from_pem
SM9_SIGN_KEY
sm9_sign_key_info_encrypt_to_der
sm9_sign_key_info_decrypt_from_der
sm9_sign_key_info_encrypt_to_pem
sm9_sign_key_info_decrypt_from_pem
SM9_SIGN_CTX
sm9_sign_init
sm9_sign_update
sm9_sign_finish
sm9_verify_init
sm9_verify_update
sm9_verify_finish
SM9_ENC_MASTER_KEY
sm9_enc_master_key_generate
sm9_enc_master_key_extract_key
sm9_enc_master_key_info_encrypt_to_der
sm9_enc_master_key_info_decrypt_from_der
sm9_enc_master_key_info_encrypt_to_pem
sm9_enc_master_key_info_decrypt_from_pem
sm9_enc_master_public_key_to_der
sm9_enc_master_public_key_from_der
sm9_enc_master_public_key_to_pem
sm9_enc_master_public_key_from_pem
SM9_ENC_KEY
sm9_enc_key_info_encrypt_to_der
sm9_enc_key_info_decrypt_from_der
sm9_enc_key_info_encrypt_to_pem
sm9_enc_key_info_decrypt_from_pem
sm9_encrypt
sm9_decrypt
*/
#define SM9_HEX_SEP '\n'
typedef uint64_t sm9_bn_t[8];
#define sm9_bn_init(r) sm9_bn_set_zero(r)
#define sm9_bn_clean(r) sm9_bn_set_zero(r)
void sm9_bn_set_zero(sm9_bn_t r);
void sm9_bn_set_one(sm9_bn_t r);
int sm9_bn_is_zero(const sm9_bn_t a);
int sm9_bn_is_one(const sm9_bn_t a);
void sm9_bn_set_word(sm9_bn_t r, uint32_t a);
void sm9_bn_copy(sm9_bn_t r, const sm9_bn_t a);
int sm9_bn_rand_range(sm9_bn_t r, const sm9_bn_t range);
int sm9_bn_equ(const sm9_bn_t a, const sm9_bn_t b);
int sm9_bn_cmp(const sm9_bn_t a, const sm9_bn_t b);
void sm9_bn_add(sm9_bn_t r, const sm9_bn_t a, const sm9_bn_t b);
void sm9_bn_sub(sm9_bn_t ret, const sm9_bn_t a, const sm9_bn_t b);
void sm9_bn_to_bits(const sm9_bn_t a, char bits[256]);
void sm9_bn_to_bytes(const sm9_bn_t a, uint8_t out[32]);
void sm9_bn_from_bytes(sm9_bn_t r, const uint8_t in[32]);
void sm9_bn_to_hex(const sm9_bn_t a, char hex[64]);
int sm9_bn_from_hex(sm9_bn_t r, const char hex[64]);
int sm9_bn_print(FILE *fp, int fmt, int ind, const char *label, const sm9_bn_t a);
void sm9_print_bn(const char *prefix, const sm9_bn_t a); // 标准打印格式
typedef sm9_bn_t sm9_fp_t;
#define sm9_fp_init(r) sm9_fp_set_zero(r)
#define sm9_fp_clean(f) sm9_fp_set_zero(r)
#define sm9_fp_set_zero(r) sm9_bn_set_zero(r)
#define sm9_fp_set_one(r) sm9_bn_set_one(r)
#define sm9_fp_copy(r,a) sm9_bn_copy((r),(a))
#define sm9_fp_rand(r) sm9_bn_rand_range((r), SM9_P)
#define sm9_fp_is_zero(a) sm9_bn_is_zero(a)
#define sm9_fp_is_one(a) sm9_bn_is_one(a)
#define sm9_fp_equ(a,b) sm9_bn_equ((a),(b))
#define sm9_fp_to_bytes(a,buf) sm9_bn_to_bytes((a),(buf))
#define sm9_fp_to_hex(a,s) sm9_bn_to_hex((a),(s))
#define sm9_fp_print(fp,fmt,ind,label,a) sm9_bn_print(fp,fmt,ind,label,a)
void sm9_fp_add(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b);
void sm9_fp_sub(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b);
void sm9_fp_dbl(sm9_fp_t r, const sm9_fp_t a);
void sm9_fp_tri(sm9_fp_t r, const sm9_fp_t a);
void sm9_fp_neg(sm9_fp_t r, const sm9_fp_t a);
void sm9_fp_mul(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b);
void sm9_fp_sqr(sm9_fp_t r, const sm9_fp_t a);
void sm9_fp_pow(sm9_fp_t r, const sm9_fp_t a, const sm9_bn_t e);
void sm9_fp_inv(sm9_fp_t r, const sm9_fp_t a);
void sm9_fp_div2(sm9_fp_t r, const sm9_fp_t a);
int sm9_fp_from_bytes(sm9_fp_t r, const uint8_t buf[32]);
int sm9_fp_from_hex(sm9_fp_t r, const char hex[64]);
typedef sm9_bn_t sm9_fn_t;
#define sm9_fn_init(r) sm9_fn_set_zero(r)
#define sm9_fn_clean(f) sm9_fn_set_zero(r)
#define sm9_fn_set_zero(r) sm9_bn_set_zero(r)
#define sm9_fn_set_one(r) sm9_bn_set_one(r)
#define sm9_fn_copy(r,a) sm9_bn_copy((r),(a))
#define sm9_fn_rand(r) sm9_bn_rand_range((r), SM9_N)
#define sm9_fn_is_zero(a) sm9_bn_is_zero(a)
#define sm9_fn_is_one(a) sm9_bn_is_one(a)
#define sm9_fn_equ(a,b) sm9_bn_equ((a),(b))
#define sm9_fn_to_bytes(a,out) sm9_bn_to_bytes((a),(out))
#define sm9_fn_to_hex(a,s) sm9_bn_to_hex((a),(s))
#define sm9_fn_print(fp,fmt,ind,label,a) sm9_bn_print(fp,fmt,ind,label,a)
void sm9_fn_add(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b);
void sm9_fn_sub(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b);
void sm9_fn_mul(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b);
void sm9_fn_pow(sm9_fn_t r, const sm9_fn_t a, const sm9_bn_t e);
void sm9_fn_inv(sm9_fn_t r, const sm9_fn_t a);
void sm9_fn_from_hash(sm9_fn_t h, const uint8_t Ha[40]);
int sm9_fn_from_bytes(sm9_fn_t a, const uint8_t in[32]);
int sm9_fn_from_hex(sm9_fn_t r, const char hex[64]);
typedef uint64_t sm9_barrett_bn_t[9];
int sm9_barrett_bn_cmp(const sm9_barrett_bn_t a, const sm9_barrett_bn_t b);
void sm9_barrett_bn_add(sm9_barrett_bn_t r, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b);
void sm9_barrett_bn_sub(sm9_barrett_bn_t ret, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b);
typedef sm9_fp_t sm9_fp2_t[2];
extern const sm9_fp2_t SM9_FP2_ZERO;
extern const sm9_fp2_t SM9_FP2_ONE;
extern const sm9_fp2_t SM9_FP2_U;
#define sm9_fp2_init(a) sm9_fp2_set_zero(a)
#define sm9_fp2_clean(a) sm9_fp2_set_zero(a)
#define sm9_fp2_set_zero(a) sm9_fp2_copy((a), SM9_FP2_ZERO)
#define sm9_fp2_set_one(a) sm9_fp2_copy((a), SM9_FP2_ONE)
#define sm9_fp2_set_u(a) sm9_fp2_copy((a), SM9_FP2_U)
#define sm9_fp2_is_zero(a) sm9_fp2_equ((a), SM9_FP2_ZERO)
#define sm9_fp2_is_one(a) sm9_fp2_equ((a), SM9_FP2_ONE)
void sm9_fp2_set_fp(sm9_fp2_t r, const sm9_fp_t a);
void sm9_fp2_set(sm9_fp2_t r, const sm9_fp_t a0, const sm9_fp_t a1);
void sm9_fp2_copy(sm9_fp2_t r, const sm9_fp2_t a);
int sm9_fp2_rand(sm9_fp2_t r);
int sm9_fp2_equ(const sm9_fp2_t a, const sm9_fp2_t b);
void sm9_fp2_add(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b);
void sm9_fp2_dbl(sm9_fp2_t r, const sm9_fp2_t a);
void sm9_fp2_tri(sm9_fp2_t r, const sm9_fp2_t a);
void sm9_fp2_sub(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b);
void sm9_fp2_neg(sm9_fp2_t r, const sm9_fp2_t a);
void sm9_fp2_mul(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b);
void sm9_fp2_mul_u(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b);
void sm9_fp2_mul_fp(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp_t k);
void sm9_fp2_sqr(sm9_fp2_t r, const sm9_fp2_t a);
void sm9_fp2_sqr_u(sm9_fp2_t r, const sm9_fp2_t a);
void sm9_fp2_inv(sm9_fp2_t r, const sm9_fp2_t a);
void sm9_fp2_div(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b);
void sm9_fp2_div2(sm9_fp2_t r, const sm9_fp2_t a);
void sm9_fp2_to_hex(const sm9_fp2_t a, char hex[129]);
int sm9_fp2_from_hex(sm9_fp2_t r, const char hex[129]);
int sm9_fp2_print(FILE *fp, int fmt, int ind, const char *label, const sm9_fp2_t a);
typedef sm9_fp2_t sm9_fp4_t[2];
extern const sm9_fp4_t SM9_FP4_ZERO;
extern const sm9_fp4_t SM9_FP4_ONE;
extern const sm9_fp4_t SM9_FP4_U;
extern const sm9_fp4_t SM9_FP4_V;
#define sm9_fp4_init(a) sm9_fp4_set_zero(a)
#define sm9_fp4_clean(a) sm9_fp4_set_zero(a)
#define sm9_fp4_set_zero(a) sm9_fp4_copy((a), SM9_FP4_ZERO)
#define sm9_fp4_set_one(a) sm9_fp4_copy((a), SM9_FP4_ONE)
#define sm9_fp4_is_zero(a) sm9_fp4_equ((a), SM9_FP4_ZERO)
#define sm9_fp4_is_one(a) sm9_fp4_equ((a), SM9_FP4_ONE)
void sm9_fp4_set_u(sm9_fp4_t r);
void sm9_fp4_set_v(sm9_fp4_t r);
void sm9_fp4_set_fp(sm9_fp4_t r, const sm9_fp_t a);
void sm9_fp4_set_fp2(sm9_fp4_t r, const sm9_fp2_t a);
void sm9_fp4_set(sm9_fp4_t r, const sm9_fp2_t a0, const sm9_fp2_t a1);
void sm9_fp4_copy(sm9_fp4_t r, const sm9_fp4_t a);
int sm9_fp4_rand(sm9_fp4_t r);
int sm9_fp4_equ(const sm9_fp4_t a, const sm9_fp4_t b);
void sm9_fp4_add(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b);
void sm9_fp4_dbl(sm9_fp4_t r, const sm9_fp4_t a);
void sm9_fp4_sub(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b);
void sm9_fp4_neg(sm9_fp4_t r, const sm9_fp4_t a);
void sm9_fp4_mul(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b);
void sm9_fp4_mul_fp(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp_t k);
void sm9_fp4_mul_fp2(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp2_t b0);
void sm9_fp4_mul_v(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b);
void sm9_fp4_sqr(sm9_fp4_t r, const sm9_fp4_t a);
void sm9_fp4_sqr_v(sm9_fp4_t r, const sm9_fp4_t a);
void sm9_fp4_inv(sm9_fp4_t r, const sm9_fp4_t a);
void sm9_fp4_to_bytes(const sm9_fp4_t a, uint8_t buf[128]);
int sm9_fp4_from_bytes(sm9_fp4_t r, const uint8_t buf[128]);
void sm9_fp4_to_hex(const sm9_fp4_t a, char hex[259]);
int sm9_fp4_from_hex(sm9_fp4_t r, const char hex[259]);
typedef sm9_fp4_t sm9_fp12_t[3];
#define sm9_fp12_init(r) sm9_fp12_set_zero(a)
#define sm9_fp12_clean(r) sm9_fp12_set_zero(a)
void sm9_fp12_set_zero(sm9_fp12_t r);
void sm9_fp12_set_one(sm9_fp12_t r);
void sm9_fp12_set_u(sm9_fp12_t r);
void sm9_fp12_set_v(sm9_fp12_t r);
void sm9_fp12_set_w(sm9_fp12_t r);
void sm9_fp12_set_w_sqr(sm9_fp12_t r);
void sm9_fp12_set_fp(sm9_fp12_t r, const sm9_fp_t a);
void sm9_fp12_set_fp2(sm9_fp12_t r, const sm9_fp2_t a);
void sm9_fp12_set_fp4(sm9_fp12_t r, const sm9_fp4_t a);
void sm9_fp12_set(sm9_fp12_t r, const sm9_fp4_t a0, const sm9_fp4_t a1, const sm9_fp4_t a2);
void sm9_fp12_copy(sm9_fp12_t r, const sm9_fp12_t a);
int sm9_fp12_rand(sm9_fp12_t r);
int sm9_fp12_is_one(const sm9_fp12_t a);
int sm9_fp12_is_zero(const sm9_fp12_t a);
int sm9_fp12_equ(const sm9_fp12_t a, const sm9_fp12_t b);
void sm9_fp12_add(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b);
void sm9_fp12_dbl(sm9_fp12_t r, const sm9_fp12_t a);
void sm9_fp12_tri(sm9_fp12_t r, const sm9_fp12_t a);
void sm9_fp12_sub(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b);
void sm9_fp12_neg(sm9_fp12_t r, const sm9_fp12_t a);
void sm9_fp12_mul(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b);
void sm9_fp12_sqr(sm9_fp12_t r, const sm9_fp12_t a);
void sm9_fp12_inv(sm9_fp12_t r, const sm9_fp12_t a);
void sm9_fp12_pow(sm9_fp12_t r, const sm9_fp12_t a, const sm9_bn_t k);
void sm9_fp12_to_bytes(const sm9_fp12_t a, uint8_t buf[32 * 12]);
int sm9_fp12_from_bytes(sm9_fp12_t r, const uint8_t in[32 * 12]);
void sm9_fp12_to_hex(const sm9_fp12_t a, char hex[65 * 12]);
int sm9_fp12_from_hex(sm9_fp12_t r, const char hex[65 * 12]); // 这个明显是不对的
void sm9_fp12_print(const char *prefix, const sm9_fp12_t a);
void sm9_fp2_conjugate(sm9_fp2_t r, const sm9_fp2_t a);
void sm9_fp2_frobenius(sm9_fp2_t r, const sm9_fp2_t a);
void sm9_fp4_frobenius(sm9_fp4_t r, const sm9_fp4_t a);
void sm9_fp4_conjugate(sm9_fp4_t r, const sm9_fp4_t a);
void sm9_fp4_frobenius2(sm9_fp4_t r, const sm9_fp4_t a);
void sm9_fp4_frobenius3(sm9_fp4_t r, const sm9_fp4_t a);
void sm9_fp12_frobenius(sm9_fp12_t r, const sm9_fp12_t x);
void sm9_fp12_frobenius2(sm9_fp12_t r, const sm9_fp12_t x);
void sm9_fp12_frobenius3(sm9_fp12_t r, const sm9_fp12_t x);
void sm9_fp12_frobenius6(sm9_fp12_t r, const sm9_fp12_t x);
typedef struct {
sm9_fp_t X;
sm9_fp_t Y;
sm9_fp_t Z;
} SM9_POINT;
#define sm9_point_init(R) sm9_point_set_infinity(R)
#define sm9_point_clean(R) sm9_point_set_infinity(R)
void sm9_point_set_infinity(SM9_POINT *R);
void sm9_point_copy(SM9_POINT *R, const SM9_POINT *P);
void sm9_point_get_xy(const SM9_POINT *P, sm9_fp_t x, sm9_fp_t y);
int sm9_point_is_at_infinity(const SM9_POINT *P);
int sm9_point_equ(const SM9_POINT *P, const SM9_POINT *Q);
int sm9_point_is_on_curve(const SM9_POINT *P);
void sm9_point_dbl(SM9_POINT *R, const SM9_POINT *P);
void sm9_point_add(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q);
void sm9_point_neg(SM9_POINT *R, const SM9_POINT *P);
void sm9_point_sub(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q);
void sm9_point_mul(SM9_POINT *R, const sm9_bn_t k, const SM9_POINT *P);
void sm9_point_mul_generator(SM9_POINT *R, const sm9_bn_t k);
void sm9_point_from_hex(SM9_POINT *R, const char hex[65 * 2]);
int sm9_point_to_uncompressed_octets(const SM9_POINT *P, uint8_t octets[65]);
int sm9_point_from_uncompressed_octets(SM9_POINT *P, const uint8_t octets[65]);
int sm9_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_POINT *P);
typedef struct {
sm9_fp2_t X;
sm9_fp2_t Y;
sm9_fp2_t Z;
} SM9_TWIST_POINT;
#define sm9_twist_point_copy(R, P) memcpy((R), (P), sizeof(SM9_TWIST_POINT))
int sm9_twist_point_to_uncompressed_octets(const SM9_TWIST_POINT *P, uint8_t octets[129]);
int sm9_twist_point_from_uncompressed_octets(SM9_TWIST_POINT *P, const uint8_t octets[129]);
void sm9_twist_point_from_hex(SM9_TWIST_POINT *R, const char hex[65 * 4]);
int sm9_twist_point_is_at_infinity(const SM9_TWIST_POINT *P);
void sm9_twist_point_set_infinity(SM9_TWIST_POINT *R);
void sm9_twist_point_get_xy(const SM9_TWIST_POINT *P, sm9_fp2_t x, sm9_fp2_t y);
int sm9_twist_point_equ(const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q);
int sm9_twist_point_is_on_curve(const SM9_TWIST_POINT *P);
void sm9_twist_point_neg(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P);
void sm9_twist_point_dbl(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P);
void sm9_twist_point_add(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q);
void sm9_twist_point_sub(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q);
void sm9_twist_point_add_full(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q);
void sm9_twist_point_mul(SM9_TWIST_POINT *R, const sm9_bn_t k, const SM9_TWIST_POINT *P);
void sm9_twist_point_mul_generator(SM9_TWIST_POINT *R, const sm9_bn_t k);
int sm9_twist_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_TWIST_POINT *P);
void sm9_eval_g_tangent(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *P, const SM9_POINT *Q);
void sm9_eval_g_line(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *T, const SM9_TWIST_POINT *P, const SM9_POINT *Q);
void sm9_twist_point_pi1(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P);
void sm9_twist_point_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P);
void sm9_twist_point_neg_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P);
void sm9_final_exponent_hard_part(sm9_fp12_t r, const sm9_fp12_t f);
void sm9_final_exponent(sm9_fp12_t r, const sm9_fp12_t f);
void sm9_pairing(sm9_fp12_t r, const SM9_TWIST_POINT *Q, const SM9_POINT *P);
/* private key extract algorithms */
#define SM9_HID_SIGN 0x01
#define SM9_HID_EXCH 0x02
#define SM9_HID_ENC 0x03
#define SM9_HASH1_PREFIX 0x01
#define SM9_HASH2_PREFIX 0x02
int sm9_hash1(sm9_bn_t h1, const char *id, size_t idlen, uint8_t hid);
const char *sm9_oid_name(int oid);
int sm9_oid_from_name(const char *name);
int sm9_oid_to_der(int oid, uint8_t **out, size_t *outlen);
int sm9_oid_from_der(int *oid, const uint8_t **in, size_t *inlen);
int sm9_algor_to_der(int alg, int params, uint8_t **out, size_t *outlen);
int sm9_algor_from_der(int *alg, int *params, const uint8_t **in, size_t *inlen);
#define PEM_SM9_SIGN_MASTER_KEY "ENCRYPTED SM9 SIGN MASTER KEY"
#define PEM_SM9_SIGN_MASTER_PUBLIC_KEY "SM9 SIGN MASTER PUBLIC KEY"
#define PEM_SM9_SIGN_PRIVATE_KEY "ENCRYPTED SM9 SIGN PRIVATE KEY"
#define PEM_SM9_ENC_MASTER_KEY "ENCRYPTED SM9 ENC MASTER KEY"
#define PEM_SM9_ENC_MASTER_PUBLIC_KEY "SM9 ENC MASTER PUBLIC KEY"
#define PEM_SM9_ENC_PRIVATE_KEY "ENCRYPTED SM9 ENC PRIVATE KEY"
#define SM9_MAX_ID_SIZE (SM2_MAX_ID_SIZE)
/*
SM9SignMasterKey ::= SEQUENCE {
ks INTEGER,
Ppubs BIT STRING -- uncompressed octets of twisted point }
SM9SignMasterPublicKey ::= SEQUENCE {
Ppubs BIT STRING -- uncompressed octets of twisted point }
SM9SignPrivateKey ::= SEQUENCE {
ds BIT STRING, -- uncompressed octets of ECPoint
Ppubs BIT STRING -- uncompressed octets of twisted point }
*/
typedef struct {
SM9_TWIST_POINT Ppubs; // Ppubs = ks * P2
sm9_fn_t ks;
} SM9_SIGN_MASTER_KEY;
typedef struct {
SM9_TWIST_POINT Ppubs;
SM9_POINT ds;
} SM9_SIGN_KEY;
int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *master);
int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *master, const char *id, size_t idlen, SM9_SIGN_KEY *key);
// algorthm,parameters = sm9,sm9sign
#define SM9_SIGN_MASTER_KEY_MAX_SIZE 171
int sm9_sign_master_key_to_der(const SM9_SIGN_MASTER_KEY *msk, uint8_t **out, size_t *outlen);
int sm9_sign_master_key_from_der(SM9_SIGN_MASTER_KEY *msk, const uint8_t **in, size_t *inlen);
int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen);
int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen);
int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp);
int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp);
int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk);
#define SM9_SIGN_MASTER_PUBLIC_KEY_SIZE 136
int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp);
int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp);
int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk);
// algorithm,parameters = sm9sign,<null>
#define SM9_SIGN_KEY_SIZE 204
int sm9_sign_key_to_der(const SM9_SIGN_KEY *key, uint8_t **out, size_t *outlen);
int sm9_sign_key_from_der(SM9_SIGN_KEY *key, const uint8_t **in, size_t *inlen);
int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen);
int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen);
int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp);
int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp);
int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key);
/*
from GM/T 0080-2020 SM9 Cryptographic Alagorithm Application Specification
SM9Signature ::= SEQUENCE {
h OCTET STRING,
S BIT STRING -- uncompressed octets of ECPoint }
*/
typedef struct {
sm9_fn_t h;
SM9_POINT S;
} SM9_SIGNATURE;
int sm9_do_sign(const SM9_SIGN_KEY *key, const SM3_CTX *sm3_ctx, SM9_SIGNATURE *sig);
int sm9_do_verify(const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen, const SM3_CTX *sm3_ctx, const SM9_SIGNATURE *sig);
#define SM9_SIGNATURE_SIZE 104
int sm9_signature_to_der(const SM9_SIGNATURE *sig, uint8_t **out, size_t *outlen);
int sm9_signature_from_der(SM9_SIGNATURE *sig, const uint8_t **in, size_t *inlen);
int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
typedef struct {
SM3_CTX sm3_ctx;
} SM9_SIGN_CTX;
int sm9_sign_init(SM9_SIGN_CTX *ctx);
int sm9_sign_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, size_t *siglen);
int sm9_verify_init(SM9_SIGN_CTX *ctx);
int sm9_verify_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
int sm9_verify_finish(SM9_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen,
const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen);
/*
SM9EncMasterKey ::= SEQUENCE {
de INTEGER,
Ppube BIT STRING -- uncompressed octets of ECPoint }
SM9EncMasterPublicKey ::= SEQUENCE {
Ppube BIT STRING -- uncompressed octets of ECPoint }
SM9EncPrivateKey ::= SEQUENCE {
de BIT STRING, -- uncompressed octets of twisted point
Ppube BIT STRING -- uncompressed octets of ECPoint }
*/
typedef struct {
SM9_POINT Ppube; // Ppube = ke * P1
sm9_fn_t ke;
} SM9_ENC_MASTER_KEY;
typedef struct {
SM9_POINT Ppube;
SM9_TWIST_POINT de;
} SM9_ENC_KEY;
int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *master);
int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *master, const char *id, size_t idlen, SM9_ENC_KEY *key);
// algorithm,parameters = sm9,sm9encrypt
#define SM9_ENC_MASTER_KEY_MAX_SIZE 105
int sm9_enc_master_key_to_der(const SM9_ENC_MASTER_KEY *msk, uint8_t **out, size_t *outlen);
int sm9_enc_master_key_from_der(SM9_ENC_MASTER_KEY *msk, const uint8_t **in, size_t *inlen);
int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen);
int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen);
int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp);
int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp);
int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk);
#define SM9_ENC_MASTER_PUBLIC_KEY_SIZE 70
int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp);
int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp);
int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk);
// algorithm,parameters = sm9encrypt,<null>
#define SM9_ENC_KEY_SIZE 204
int sm9_enc_key_to_der(const SM9_ENC_KEY *key, uint8_t **out, size_t *outlen);
int sm9_enc_key_from_der(SM9_ENC_KEY *key, const uint8_t **in, size_t *inlen);
int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen);
int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen);
int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp);
int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp);
int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key);
#define SM9_MAX_PRIVATE_KEY_SIZE (SM9_SIGN_KEY_SIZE) // MAX(SIGN_MASTER_KEY, SIGN_KEY, ENC_MASTER_KEY, ENC_KEY)
#define SM9_MAX_PRIVATE_KEY_INFO_SIZE 512
#define SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE 1024
/*
from GM/T 0080-2020 SM9 Cryptographic Alagorithm Application Specification
SM9Cipher ::= SEQUENCE {
EnType INTEGER, -- 0 for XOR
C1 BIT STRING, -- uncompressed octets of ECPoint
C3 OCTET STRING, -- 32 bytes HMAC-SM3 tag
CipherText OCTET STRING }
*/
int sm9_kem_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, size_t klen, uint8_t *kbuf, SM9_POINT *C);
int sm9_kem_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, const SM9_POINT *C, size_t klen, uint8_t *kbuf);
int sm9_do_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen,
const uint8_t *in, size_t inlen, SM9_POINT *C1, uint8_t *c2, uint8_t c3[SM3_HMAC_SIZE]);
int sm9_do_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen,
const SM9_POINT *C1, const uint8_t *c2, size_t c2len, const uint8_t c3[SM3_HMAC_SIZE], uint8_t *out);
#define SM9_MAX_PLAINTEXT_SIZE 255
#define SM9_MAX_CIPHERTEXT_SIZE 367 // calculated in test_sm9_ciphertext()
int sm9_ciphertext_to_der(const SM9_POINT *C1, const uint8_t *c2, size_t c2len,
const uint8_t c3[SM3_HMAC_SIZE], uint8_t **out, size_t *outlen);
int sm9_ciphertext_from_der(SM9_POINT *C1, const uint8_t **c2, size_t *c2len,
const uint8_t **c3, const uint8_t **in, size_t *inlen);
int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SOCKET_H
#define GMSSL_SOCKET_H
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#include <winsock2.h>
typedef SOCKET tls_socket_t;
typedef int tls_ret_t;
typedef int tls_socklen_t;
#define tls_socket_send(sock,buf,len,flags) send(sock,buf,(int)(len),flags)
#define tls_socket_recv(sock,buf,len,flags) recv(sock,buf,(int)(len),flags)
#define tls_socket_close(sock) closesocket(sock)
#else
#include <fcntl.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
typedef int tls_socket_t;
typedef ssize_t tls_ret_t;
typedef socklen_t tls_socklen_t;
#define tls_socket_send(sock,buf,len,flags) send(sock,buf,len,flags)
#define tls_socket_recv(sock,buf,len,flags) recv(sock,buf,len,flags)
#define tls_socket_close(sock) close(sock)
#endif
int tls_socket_lib_init(void);
int tls_socket_lib_cleanup(void);
int tls_socket_create(tls_socket_t *sock, int af, int type, int protocl);
int tls_socket_connect(tls_socket_t sock, const struct sockaddr_in *addr);
int tls_socket_bind(tls_socket_t sock, const struct sockaddr_in *addr);
int tls_socket_listen(tls_socket_t sock, int backlog);
int tls_socket_accept(tls_socket_t sock, struct sockaddr_in *addr, tls_socket_t *conn_sock);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,875 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_TLS_H
#define GMSSL_TLS_H
#include <stdint.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
#include <gmssl/digest.h>
#include <gmssl/block_cipher.h>
#include <gmssl/socket.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
TLS Public API
TLS_PROTOCOL
TLS_protocol_tlcp
TLS_protocol_tls12
TLS_protocol_tls13
TLS_CIPHER_SUITE
TLS_cipher_ecc_sm4_cbc_sm3
TLS_cipher_ecc_sm4_gcm_sm3
TLS_cipher_ecdhe_sm4_cbc_sm3
TLS_cipher_ecdhe_sm4_gcm_sm3
TLS_cipher_sm4_gcm_sm3
TLS_CTX
tls_ctx_init
tls_ctx_set_cipher_suites
tls_ctx_set_ca_certificates
tls_ctx_set_certificate_and_key
tls_ctx_set_tlcp_server_certificate_and_keys
tls_ctx_cleanup
TLS_CONNECT
tls_init
tls_set_socket
tls_do_handshake
tls_send
tls_recv
tls_shutdown
tls_cleanup
*/
typedef uint32_t uint24_t;
#define tls_uint8_size() 1
#define tls_uint16_size() 2
#define tls_uint24_size() 3
void tls_uint8_to_bytes(uint8_t a, uint8_t **out, size_t *outlen);
void tls_uint16_to_bytes(uint16_t a, uint8_t **out, size_t *outlen);
void tls_uint24_to_bytes(uint24_t a, uint8_t **out, size_t *outlen);
void tls_uint32_to_bytes(uint32_t a, uint8_t **out, size_t *outlen);
void tls_array_to_bytes(const uint8_t *data, size_t len, uint8_t **out, size_t *outlen);
void tls_uint8array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen);
void tls_uint16array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen);
void tls_uint24array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen);
int tls_uint8_from_bytes(uint8_t *a, const uint8_t **in, size_t *inlen);
int tls_uint16_from_bytes(uint16_t *a, const uint8_t **in, size_t *inlen);
int tls_uint24_from_bytes(uint24_t *a, const uint8_t **in, size_t *inlen);
int tls_uint32_from_bytes(uint32_t *a, const uint8_t **in, size_t *inlen);
int tls_array_from_bytes(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen);
int tls_uint8array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen);
int tls_uint16array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen);
int tls_uint24array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen);
int tls_length_is_zero(size_t len);
typedef enum {
TLS_protocol_tlcp = 0x0101,
TLS_protocol_ssl2 = 0x0200,
TLS_protocol_ssl3 = 0x0300,
TLS_protocol_tls1 = 0x0301,
TLS_protocol_tls11 = 0x0302,
TLS_protocol_tls12 = 0x0303,
TLS_protocol_tls13 = 0x0304,
TLS_protocol_dtls1 = 0xfeff, // {254, 255}
TLS_protocol_dtls12 = 0xfefd, // {254, 253}
} TLS_PROTOCOL;
const char *tls_protocol_name(int proto);
typedef enum {
TLS_cipher_null_with_null_null = 0x0000,
// TLS 1.3, RFC 8998
TLS_cipher_sm4_gcm_sm3 = 0x00c6,
TLS_cipher_sm4_ccm_sm3 = 0x00c7,
// TLCP, GB/T 38636-2020, GM/T 0024-2012
TLS_cipher_ecdhe_sm4_cbc_sm3 = 0xe011, // 可以让TLSv1.2使用这个
TLS_cipher_ecdhe_sm4_gcm_sm3 = 0xe051,
TLS_cipher_ecc_sm4_cbc_sm3 = 0xe013,
TLS_cipher_ecc_sm4_gcm_sm3 = 0xe053,
TLS_cipher_ibsdh_sm4_cbc_sm3 = 0xe015,
TLS_cipher_ibsdh_sm4_gcm_sm3 = 0xe055,
TLS_cipher_ibc_sm4_cbc_sm3 = 0xe017,
TLS_cipher_ibc_sm4_gcm_sm3 = 0xe057,
TLS_cipher_rsa_sm4_cbc_sm3 = 0xe019,
TLS_cipher_rsa_sm4_gcm_sm3 = 0xe059,
TLS_cipher_rsa_sm4_cbc_sha256 = 0xe01c,
TLS_cipher_rsa_sm4_gcm_sha256 = 0xe05a,
// TLS 1.3 RFC 8446
TLS_cipher_aes_128_gcm_sha256 = 0x1301, // Mandatory-to-implement
TLS_cipher_aes_256_gcm_sha384 = 0x1302, // SHOULD implement
TLS_cipher_chacha20_poly1305_sha256 = 0x1303, // SHOULD implement
TLS_cipher_aes_128_ccm_sha256 = 0x1304,
TLS_cipher_aes_128_ccm_8_sha256 = 0x1305,
TLS_cipher_empty_renegotiation_info_scsv = 0x00ff,
} TLS_CIPHER_SUITE;
const char *tls_cipher_suite_name(int cipher);
int tls_cipher_suites_select(const uint8_t *client_ciphers, size_t client_ciphers_len,
const int *server_ciphers, size_t server_ciphers_cnt, int *selected_cipher);
int tls_cipher_suite_in_list(int cipher, const int *list, size_t list_count);
typedef enum {
TLS_compression_null = 0,
TLS_compression_default = 1,
} TLS_COMPRESSION_METHOD;
const char *tls_compression_method_name(int meth);
typedef enum {
TLS_record_invalid = 0, // TLS 1.3
TLS_record_change_cipher_spec = 20, // 0x14
TLS_record_alert = 21, // 0x15
TLS_record_handshake = 22, // 0x16
TLS_record_application_data = 23, // 0x17
TLS_record_heartbeat = 24, // 0x18
TLS_record_tls12_cid = 25, // 0x19
} TLS_RECORD_TYPE;
const char *tls_record_type_name(int type);
typedef enum {
TLS_handshake_hello_request = 0,
TLS_handshake_client_hello = 1,
TLS_handshake_server_hello = 2,
TLS_handshake_hello_verify_request = 3,
TLS_handshake_new_session_ticket = 4,
TLS_handshake_end_of_early_data = 5,
TLS_handshake_hello_retry_request = 6,
TLS_handshake_encrypted_extensions = 8,
TLS_handshake_certificate = 11,
TLS_handshake_server_key_exchange = 12,
TLS_handshake_certificate_request = 13,
TLS_handshake_server_hello_done = 14,
TLS_handshake_certificate_verify = 15,
TLS_handshake_client_key_exchange = 16,
TLS_handshake_finished = 20,
TLS_handshake_certificate_url = 21,
TLS_handshake_certificate_status = 22,
TLS_handshake_supplemental_data = 23,
TLS_handshake_key_update = 24,
TLS_handshake_compressed_certificate = 25,
TLS_handshake_ekt_key = 26,
TLS_handshake_message_hash = 254,
} TLS_HANDSHAKE_TYPE;
const char *tls_handshake_type_name(int type);
typedef enum {
TLS_cert_type_rsa_sign = 1,
TLS_cert_type_dss_sign = 2,
TLS_cert_type_rsa_fixed_dh = 3,
TLS_cert_type_dss_fixed_dh = 4,
TLS_cert_type_rsa_ephemeral_dh_RESERVED = 5,
TLS_cert_type_dss_ephemeral_dh_RESERVED = 6,
TLS_cert_type_fortezza_dms_RESERVED = 20,
TLS_cert_type_ecdsa_sign = 64, // also for sm2
TLS_cert_type_rsa_fixed_ecdh = 65,
TLS_cert_type_ecdsa_fixed_ecdh = 66,
TLS_cert_type_gost_sign256 = 67,
TLS_cert_type_gost_sign512 = 68,
TLS_cert_type_ibc_params = 80,
} TLS_CERTIFICATE_TYPE;
const char *tls_cert_type_name(int type);
int tls_cert_type_from_oid(int oid);
typedef enum {
TLS_extension_server_name = 0,
TLS_extension_max_fragment_length = 1,
TLS_extension_client_certificate_url = 2,
TLS_extension_trusted_ca_keys = 3,
TLS_extension_truncated_hmac = 4,
TLS_extension_status_request = 5,
TLS_extension_user_mapping = 6,
TLS_extension_client_authz = 7,
TLS_extension_server_authz = 8,
TLS_extension_cert_type = 9,
TLS_extension_supported_groups = 10,
TLS_extension_ec_point_formats = 11,
TLS_extension_srp = 12,
TLS_extension_signature_algorithms = 13,
TLS_extension_use_srtp = 14,
TLS_extension_heartbeat = 15,
TLS_extension_application_layer_protocol_negotiation= 16,
TLS_extension_status_request_v2 = 17,
TLS_extension_signed_certificate_timestamp = 18,
TLS_extension_client_certificate_type = 19,
TLS_extension_server_certificate_type = 20,
TLS_extension_padding = 21,
TLS_extension_encrypt_then_mac = 22,
TLS_extension_extended_master_secret = 23,
TLS_extension_token_binding = 24,
TLS_extension_cached_info = 25,
TLS_extension_tls_lts = 26,
TLS_extension_compress_certificate = 27,
TLS_extension_record_size_limit = 28,
TLS_extension_pwd_protect = 29,
TLS_extension_pwd_clear = 30,
TLS_extension_password_salt = 31,
TLS_extension_ticket_pinning = 32,
TLS_extension_tls_cert_with_extern_psk = 33,
TLS_extension_delegated_credentials = 34,
TLS_extension_session_ticket = 35,
TLS_extension_TLMSP = 36,
TLS_extension_TLMSP_proxying = 37,
TLS_extension_TLMSP_delegate = 38,
TLS_extension_supported_ekt_ciphers = 39,
TLS_extension_pre_shared_key = 41,
TLS_extension_early_data = 42,
TLS_extension_supported_versions = 43,
TLS_extension_cookie = 44,
TLS_extension_psk_key_exchange_modes = 46,
TLS_extension_certificate_authorities = 47,
TLS_extension_oid_filters = 48,
TLS_extension_post_handshake_auth = 49,
TLS_extension_signature_algorithms_cert = 50,
TLS_extension_key_share = 51,
TLS_extension_transparency_info = 52,
TLS_extension_connection_id = 53,
TLS_extension_external_id_hash = 55,
TLS_extension_external_session_id = 56,
TLS_extension_quic_transport_parameters = 57,
TLS_extension_ticket_request = 58,
TLS_extension_renegotiation_info = 65281,
} TLS_EXTENSION_TYPE;
const char *tls_extension_name(int ext);
typedef enum {
TLS_point_uncompressed = 0,
TLS_point_ansix962_compressed_prime = 1,
TLS_point_ansix962_compressed_char2 = 2,
} TLS_EC_POINT_FORMAT;
const char *tls_ec_point_format_name(int format);
typedef enum {
TLS_curve_type_explicit_prime = 1,
TLS_curve_type_explicit_char2 = 2,
TLS_curve_type_named_curve = 3,
} TLS_CURVE_TYPE;
const char *tls_curve_type_name(int type);
// 与其支持v2还不如直接修改v2让v2和v3兼容
typedef enum {
TLS_curve_secp256k1 = 22,
TLS_curve_secp256r1 = 23,
TLS_curve_secp384r1 = 24,
TLS_curve_secp521r1 = 25,
TLS_curve_brainpoolp256r1 = 26,
TLS_curve_brainpoolp384r1 = 27,
TLS_curve_brainpoolp512r1 = 28,
TLS_curve_x25519 = 29,
TLS_curve_x448 = 30,
TLS_curve_brainpoolp256r1tls13 = 31,
TLS_curve_brainpoolp384r1tls13 = 32,
TLS_curve_brainpoolp512r1tls13 = 33,
TLS_curve_sm2p256v1 = 41, // GmSSLv2: 30
} TLS_NAMED_CURVE;
const char *tls_named_curve_name(int curve);
typedef enum {
TLS_sig_rsa_pkcs1_sha1 = 0x0201,
TLS_sig_ecdsa_sha1 = 0x0203,
TLS_sig_rsa_pkcs1_sha256 = 0x0401,
TLS_sig_ecdsa_secp256r1_sha256 = 0x0403,
TLS_sig_rsa_pkcs1_sha256_legacy = 0x0420,
TLS_sig_rsa_pkcs1_sha384 = 0x0501,
TLS_sig_ecdsa_secp384r1_sha384 = 0x0503,
TLS_sig_rsa_pkcs1_sha384_legacy = 0x0520,
TLS_sig_rsa_pkcs1_sha512 = 0x0601,
TLS_sig_ecdsa_secp521r1_sha512 = 0x0603,
TLS_sig_rsa_pkcs1_sha512_legacy = 0x0620,
TLS_sig_sm2sig_sm3 = 0x0708, // GmSSLv2: 0x0707
TLS_sig_rsa_pss_rsae_sha256 = 0x0804,
TLS_sig_rsa_pss_rsae_sha384 = 0x0805,
TLS_sig_rsa_pss_rsae_sha512 = 0x0806,
TLS_sig_ed25519 = 0x0807,
TLS_sig_ed448 = 0x0808,
TLS_sig_rsa_pss_pss_sha256 = 0x0809,
TLS_sig_rsa_pss_pss_sha384 = 0x080A,
TLS_sig_rsa_pss_pss_sha512 = 0x080B,
TLS_sig_ecdsa_brainpoolP256r1tls13_sha256 = 0x081A,
TLS_sig_ecdsa_brainpoolP384r1tls13_sha384 = 0x081B,
TLS_sig_ecdsa_brainpoolP512r1tls13_sha512 = 0x081C,
} TLS_SIGNATURE_SCHEME;
const char *tls_signature_scheme_name(int scheme);
typedef enum {
TLS_change_cipher_spec = 1,
} TLS_CHANGE_CIPHER_SPEC_TYPE;
typedef enum {
TLS_alert_level_warning = 1,
TLS_alert_level_fatal = 2,
} TLS_ALERT_LEVEL;
const char *tls_alert_level_name(int level);
typedef enum {
TLS_alert_close_notify = 0,
TLS_alert_unexpected_message = 10,
TLS_alert_bad_record_mac = 20,
TLS_alert_decryption_failed = 21,
TLS_alert_record_overflow = 22,
TLS_alert_decompression_failure = 30,
TLS_alert_handshake_failure = 40,
TLS_alert_no_certificate = 41,
TLS_alert_bad_certificate = 42,
TLS_alert_unsupported_certificate = 43,
TLS_alert_certificate_revoked = 44,
TLS_alert_certificate_expired = 45,
TLS_alert_certificate_unknown = 46,
TLS_alert_illegal_parameter = 47,
TLS_alert_unknown_ca = 48,
TLS_alert_access_denied = 49,
TLS_alert_decode_error = 50,
TLS_alert_decrypt_error = 51,
TLS_alert_export_restriction = 60,
TLS_alert_protocol_version = 70,
TLS_alert_insufficient_security = 71,
TLS_alert_internal_error = 80,
TLS_alert_user_canceled = 90,
TLS_alert_no_renegotiation = 100,
TLS_alert_unsupported_extension = 110,
TLS_alert_unsupported_site2site = 200,
TLS_alert_no_area = 201,
TLS_alert_unsupported_areatype = 202,
TLS_alert_bad_ibcparam = 203,
TLS_alert_unsupported_ibcparam = 204,
TLS_alert_identity_need = 205,
} TLS_ALERT_DESCRIPTION;
const char *tls_alert_description_text(int description);
int tls_prf(const uint8_t *secret, size_t secretlen, const char *label,
const uint8_t *seed, size_t seedlen,
const uint8_t *more, size_t morelen,
size_t outlen, uint8_t *out);
int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32]);
int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32],
const char *label, const uint8_t *context, size_t context_len,
size_t outlen, uint8_t *out);
int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32]);
int tls_cbc_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *enc_key,
const uint8_t seq_num[8], const uint8_t header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int tls_cbc_decrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *dec_key,
const uint8_t seq_num[8], const uint8_t header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key,
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
uint8_t *out, size_t *outlen);
int tls_record_decrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key,
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
uint8_t *out, size_t *outlen);
int tls_seq_num_incr(uint8_t seq_num[8]);
int tls_random_generate(uint8_t random[32]);
int tls_random_print(FILE *fp, const uint8_t random[32], int format, int indent);
int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int protocol);
int tls_pre_master_secret_print(FILE *fp, const uint8_t pre_master_secret[48], int format, int indent);
int tls_secrets_print(FILE *fp,
const uint8_t *pre_master_secret, size_t pre_master_secret_len,
const uint8_t client_random[32], const uint8_t server_random[32],
const uint8_t master_secret[48],
const uint8_t *key_block, size_t key_block_len,
int format, int indent);
typedef struct {
uint8_t type;
uint8_t protocol[2];
uint8_t data_length[2];
} TLS_RECORD_HEADER;
#define TLS_RECORD_HEADER_SIZE (1 + tls_uint16_size() + tls_uint16_size()) // 5
#define TLS_MAX_PLAINTEXT_SIZE (1 << 14) // 16384
#define TLS_MAX_COMPRESSED_SIZE ((1 << 14) + 1024) // 17408
#define TLS_MAX_CIPHERTEXT_SIZE ((1 << 14) + 2048) // 18432
#define TLS_MAX_RECORD_SIZE (TLS_RECORD_HEADER_SIZE + TLS_MAX_CIPHERTEXT_SIZE) // 18437
#define tls_record_type(record) ((record)[0])
#define tls_record_header(record) ((record)+0)
#define tls_record_protocol(record) (((uint16_t)((record)[1]) << 8) | (record)[2])
#define tls_record_data(record) ((record)+TLS_RECORD_HEADER_SIZE)
#define tls_record_data_length(record) (((uint16_t)((record)[3]) << 8) | (record)[4])
#define tls_record_length(record) (TLS_RECORD_HEADER_SIZE + tls_record_data_length(record))
int tls_record_set_type(uint8_t *record, int type);
int tls_record_set_protocol(uint8_t *record, int protocol);
int tls_record_set_data_length(uint8_t *record, size_t length);
int tls_record_set_data(uint8_t *record, const uint8_t *data, size_t datalen);
// 握手消息ServerKeyExchange, ClientKeyExchange的解析依赖当前密码套件
#define tls_format_set_cipher_suite(fmt,cipher) do {(fmt)|=((cipher)<<8);} while (0)
int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent);
int tlcp_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent);
int tls_record_send(const uint8_t *record, size_t recordlen, tls_socket_t sock);
int tls_record_recv(uint8_t *record, size_t *recordlen, tls_socket_t sock);
int tls12_record_recv(uint8_t *record, size_t *recordlen, tls_socket_t sock);
// Handshake
typedef struct {
uint8_t type;
uint8_t length[3];
} TLS_HANDSHAKE_HEADER;
#define TLS_HANDSHAKE_HEADER_SIZE 4
#define TLS_MAX_HANDSHAKE_DATA_SIZE (TLS_MAX_PLAINTEXT_SIZE - TLS_HANDSHAKE_HEADER_SIZE)
#define tls_handshake_data(p) ((p) + TLS_HANDSHAKE_HEADER_SIZE)
//#define tls_handshake_data_length(p)
int tls_record_set_handshake(uint8_t *record, size_t *recordlen,
int type, const uint8_t *data, size_t datalen);
int tls_record_get_handshake(const uint8_t *record,
int *type, const uint8_t **data, size_t *datalen);
int tls_handshake_print(FILE *fp, const uint8_t *handshake, size_t handshakelen, int format, int indent);
// HelloRequest
int tls_hello_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
// ClientHello, ServerHello
#define TLS_MIN_SESSION_ID_SIZE 0
#define TLS_MAX_SESSION_ID_SIZE 32
int tls_record_set_handshake_client_hello(uint8_t *record, size_t *recordlen,
int client_protocol, const uint8_t random[32],
const uint8_t *session_id, size_t session_id_len,
const int *cipher_suites, size_t cipher_suites_count,
const uint8_t *exts, size_t exts_len);
int tls_record_get_handshake_client_hello(const uint8_t *record,
int *client_protocol, const uint8_t **random,
const uint8_t **session_id, size_t *session_id_len,
const uint8_t **cipher_suites, size_t *cipher_suites_len,
const uint8_t **exts, size_t *exts_len);
int tls_client_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
int tls_record_set_handshake_server_hello(uint8_t *record, size_t *recordlen,
int server_protocol, const uint8_t random[32],
const uint8_t *session_id, size_t session_id_len,
int cipher_suite, const uint8_t *exts, size_t exts_len);
int tls_record_get_handshake_server_hello(const uint8_t *record,
int *protocol, const uint8_t **random, const uint8_t **session_id, size_t *session_id_len,
int *cipher_suite, const uint8_t **exts, size_t *exts_len);
int tls_server_hello_print(FILE *fp, const uint8_t *server_hello, size_t len, int format, int indent);
// Extensions
int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt,
uint8_t **out, size_t *outlen);
int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen,
uint8_t **out, size_t *outlen);
int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen);
int tls_supported_groups_ext_to_bytes(const int *groups, size_t groups_cnt,
uint8_t **out, size_t *outlen);
int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_datalen,
uint8_t **out, size_t *outlen);
int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_datalen);
int tls_signature_algorithms_ext_to_bytes_ex(int ext_type, const int *algs, size_t algs_cnt,
uint8_t **out, size_t *outlen);
int tls_signature_algorithms_ext_to_bytes(const int *algs, size_t algs_cnt,
uint8_t **out, size_t *outlen);
int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt,
uint8_t **out, size_t *outlen);
int tls_process_client_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen,
uint8_t **out, size_t *outlen);
int tls_process_server_signature_algors(const uint8_t *ext_data, size_t ext_datalen);
int tls13_supported_versions_ext_to_bytes(int handshake_type, const int *protos, size_t protos_cnt,
uint8_t **out, size_t *outlen);
int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen,
uint8_t **out, size_t *outlen);
int tls13_process_server_supported_versions(const uint8_t *ext_data, size_t ext_datalen);
int tls13_key_share_entry_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen);
int tls13_client_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen);
int tls13_server_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen);
int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen,
const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public,
uint8_t **out, size_t *outlen);
int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_POINT *point);
int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len,
uint8_t **out, size_t *outlen);
int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen);
int tls_process_client_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen);
int tls_process_server_exts(const uint8_t *exts, size_t extslen,
int *ec_point_format, int *supported_group, int *signature_algor);
// Certificate
int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen,
const uint8_t *certs, size_t certslen);
// 这个函数比较特殊,是直接解析了证书链,而不是返回指针
// 应该提供一个独立的解析函数来解析TLS的证书链
int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *certs, size_t *certslen);
// ServerKeyExchange
int tls_server_key_exchange_print(FILE *fp, const uint8_t *ske, size_t skelen, int format, int indent);
#define TLS_MAX_SIGNATURE_SIZE SM2_MAX_SIGNATURE_SIZE
int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen);
int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen);
int tls_record_set_handshake_server_key_exchange_ecdhe(uint8_t *record, size_t *recordlen,
int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen);
int tls_record_get_handshake_server_key_exchange_ecdhe(const uint8_t *record,
int *curve, SM2_POINT *point, const uint8_t **sig, size_t *siglen);
int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen,
int format, int indent);
int tlcp_record_set_handshake_server_key_exchange_pke(uint8_t *record, size_t *recordlen,
const uint8_t *sig, size_t siglen);
int tlcp_record_get_handshake_server_key_exchange_pke(const uint8_t *record,
const uint8_t **sig, size_t *siglen);
int tlcp_server_key_exchange_pke_print(FILE *fp, const uint8_t *sig, size_t siglen, int format, int indent);
// CertificateRequest
#define TLS_MAX_CERTIFICATE_TYPES 256
#define TLS_MAX_CA_NAMES_SIZE (TLS_MAX_HANDSHAKE_DATA_SIZE - tls_uint8_size() - tls_uint16_size())
int tls_authorities_from_certs(uint8_t *ca_names, size_t *ca_names_len, size_t maxlen, const uint8_t *certs, size_t certslen);
int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_namelen, const uint8_t *certs, size_t certslen);
int tls_cert_types_accepted(const uint8_t *types, size_t types_len, const uint8_t *client_certs, size_t client_certs_len);
int tls_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen,
const uint8_t *cert_types, size_t cert_types_len,
const uint8_t *ca_names, size_t ca_names_len);
int tls_record_get_handshake_certificate_request(const uint8_t *record,
const uint8_t **cert_types, size_t *cert_types_len,
const uint8_t **ca_names, size_t *ca_names_len);
int tls_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
// ServerHelloDone
int tls_record_set_handshake_server_hello_done(uint8_t *record, size_t *recordlen);
int tls_record_get_handshake_server_hello_done(const uint8_t *record);
int tls_server_hello_done_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
// ClientKeyExchange
int tls_record_set_handshake_client_key_exchange_pke(uint8_t *record, size_t *recordlen,
const uint8_t *enced_pms, size_t enced_pms_len);
int tls_record_get_handshake_client_key_exchange_pke(const uint8_t *record,
const uint8_t **enced_pms, size_t *enced_pms_len);
int tls_client_key_exchange_pke_print(FILE *fp, const uint8_t *cke, size_t ckelen, int format, int indent);
int tls_client_key_exchange_print(FILE *fp, const uint8_t *cke, size_t ckelen, int format, int indent);
int tls_record_set_handshake_client_key_exchange_ecdhe(uint8_t *record, size_t *recordlen,
const SM2_POINT *point); // 这里不应该支持SM2_POINT类型
int tls_record_get_handshake_client_key_exchange_ecdhe(const uint8_t *record, SM2_POINT *point);
int tls_client_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen,
int format, int indent);
// CertificateVerify
int tls_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen,
const uint8_t *sig, size_t siglen);
int tls_record_get_handshake_certificate_verify(const uint8_t *record,
const uint8_t **sig, size_t *siglen);
int tls_certificate_verify_print(FILE *fp, const uint8_t *p, size_t len, int format, int indent);
typedef enum {
TLS_client_verify_client_hello = 0,
TLS_client_verify_server_hello = 1,
TLS_client_verify_server_certificate = 2,
TLS_client_verify_server_key_exchange = 3,
TLS_client_verify_cert_request = 4,
TLS_client_verify_server_hello_done = 5,
TLS_client_verify_client_certificate = 6,
TLS_client_verify_client_key_exchange = 7,
} TLS_CLIENT_VERIFY_INDEX;
typedef struct {
TLS_CLIENT_VERIFY_INDEX index;
uint8_t *handshake[8]; // Record data only, no record header
size_t handshake_len[8];
} TLS_CLIENT_VERIFY_CTX;
int tls_client_verify_init(TLS_CLIENT_VERIFY_CTX *ctx);
int tls_client_verify_update(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *handshake, size_t handshake_len);
int tls_client_verify_finish(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *sig, size_t siglen, const SM2_KEY *public_key);
void tls_client_verify_cleanup(TLS_CLIENT_VERIFY_CTX *ctx);
// Finished
// FIXME: 支持TLS 1.3 提供MIN, MAX或TLS12, TLS13, TLCP...
#define TLS_VERIFY_DATA_SIZE 12 // TLS 1.3或者其他版本支持更长的verify_data
#define TLS_FINISHED_RECORD_SIZE (TLS_RECORD_HEADER_SIZE + TLS_HANDSHAKE_HEADER_SIZE + TLS_VERIFY_DATA_SIZE) // 21
#define TLS_MAX_PADDING_SIZE (1 + 255)
#define TLS_MAC_SIZE SM3_HMAC_SIZE
#define TLS_FINISHED_RECORD_BUF_SIZE (TLS_FINISHED_RECORD_SIZE + TLS_MAC_SIZE + TLS_MAX_PADDING_SIZE) // 309
int tls_record_set_handshake_finished(uint8_t *record, size_t *recordlen,
const uint8_t *verify_data, size_t verify_data_len);
int tls_record_get_handshake_finished(const uint8_t *record,
const uint8_t **verify_data, size_t *verify_data_len);
int tls_finished_print(FILE *fp, const uint8_t *a, size_t len, int format, int indent);
// Alert
typedef struct {
uint8_t level;
uint8_t description;
} TLS_ALERT;
#define TLS_ALERT_RECORD_SIZE (TLS_RECORD_HEADER_SIZE + 2)
int tls_record_set_alert(uint8_t *record, size_t *recordlen, int alert_level, int alert_description);
int tls_record_get_alert(const uint8_t *record, int *alert_level, int *alert_description);
int tls_alert_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
// ChangeCipherSpec
typedef struct {
uint8_t type;
} TLS_CHANGE_CIPHER_SPEC;
const char *tls_change_cipher_spec_text(int change_cipher_spec);
int tls_change_cipher_spec_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
int tls_record_set_change_cipher_spec(uint8_t *record, size_t *recordlen);
int tls_record_get_change_cipher_spec(const uint8_t *record);
// ApplicationData
int tls_record_set_application_data(uint8_t *record, size_t *recordlen,
const uint8_t *data, size_t datalen);
int tls_record_get_application_data(uint8_t *record,
const uint8_t **data, size_t *datalen);
int tls_application_data_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
enum {
TLS_server_mode = 0,
TLS_client_mode = 1,
};
#define TLS_MAX_CIPHER_SUITES_COUNT 64
typedef struct {
int protocol;
int is_client;
int cipher_suites[TLS_MAX_CIPHER_SUITES_COUNT];
size_t cipher_suites_cnt;
uint8_t *cacerts;
size_t cacertslen;
uint8_t *certs;
size_t certslen;
SM2_KEY signkey;
SM2_KEY kenckey;
int verify_depth;
} TLS_CTX;
int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client);
int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cipher_suites_cnt);
int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth);
int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile,
const char *keyfile, const char *keypass);
int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chainfile,
const char *signkeyfile, const char *signkeypass,
const char *kenckeyfile, const char *kenckeypass);
void tls_ctx_cleanup(TLS_CTX *ctx);
#define TLS_MAX_CERTIFICATES_SIZE 2048
#define TLS_DEFAULT_VERIFY_DEPTH 4
#define TLS_MAX_VERIFY_DEPTH 5
typedef struct {
int protocol;
int is_client;
int cipher_suites[TLS_MAX_CIPHER_SUITES_COUNT];
size_t cipher_suites_cnt;
tls_socket_t sock;
uint8_t enced_record[TLS_MAX_RECORD_SIZE];
size_t enced_record_len;
uint8_t record[TLS_MAX_RECORD_SIZE];
// 其实这个就不太对了,还是应该有一个完整的密文记录
uint8_t databuf[TLS_MAX_PLAINTEXT_SIZE];
uint8_t *data;
size_t datalen;
int cipher_suite;
uint8_t session_id[32];
size_t session_id_len;
uint8_t server_certs[TLS_MAX_CERTIFICATES_SIZE]; // 动态的可能会好一点
size_t server_certs_len;
uint8_t client_certs[TLS_MAX_CERTIFICATES_SIZE];
size_t client_certs_len;
uint8_t ca_certs[2048];
size_t ca_certs_len;
SM2_KEY sign_key;
SM2_KEY kenc_key;
int verify_result;
uint8_t master_secret[48];
uint8_t key_block[96];
SM3_HMAC_CTX client_write_mac_ctx;
SM3_HMAC_CTX server_write_mac_ctx;
SM4_KEY client_write_enc_key;
SM4_KEY server_write_enc_key;
uint8_t client_seq_num[8];
uint8_t server_seq_num[8];
uint8_t client_write_iv[12]; // tls13
uint8_t server_write_iv[12]; // tls13
BLOCK_CIPHER_KEY client_write_key;
BLOCK_CIPHER_KEY server_write_key;
} TLS_CONNECT;
#define TLS_MAX_EXTENSIONS_SIZE 512 // 这个应该再考虑一下数值,是否可以用其他的缓冲区装载?
int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx);
int tls_set_socket(TLS_CONNECT *conn, tls_socket_t sock);
int tls_do_handshake(TLS_CONNECT *conn);
int tls_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen);
int tls_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen);
int tls_shutdown(TLS_CONNECT *conn);
void tls_cleanup(TLS_CONNECT *conn);
int tlcp_do_connect(TLS_CONNECT *conn);
int tlcp_do_accept(TLS_CONNECT *conn);
int tls12_do_connect(TLS_CONNECT *conn);
int tls12_do_accept(TLS_CONNECT *conn);
#define TLS13_SM2_ID "TLSv1.3+GM+Cipher+Suite"
#define TLS13_SM2_ID_LENGTH (sizeof(TLS13_SM2_ID)-1)
int tls13_do_connect(TLS_CONNECT *conn);
int tls13_do_accept(TLS_CONNECT *conn);
int tls_send_alert(TLS_CONNECT *conn, int alert);
int tls_send_warning(TLS_CONNECT *conn, int alert);
int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *sentlen);
int tls13_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen);
int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *server_cacerts_fp,
FILE *client_certs_fp, const SM2_KEY *client_sign_key);
int tls13_accept(TLS_CONNECT *conn, int port,
FILE *server_certs_fp, const SM2_KEY *server_sign_key,
FILE *client_cacerts_fp);
int tls13_supported_versions_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen);
int tls13_key_share_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen);
int tls_process_client_hello_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen);
int tls_process_server_hello_exts(const uint8_t *exts, size_t extslen,
int *ec_point_format, int *supported_group, int *signature_algor);
int tls13_encrypted_extensions_print(FILE *fp, int fmt, int ind, const uint8_t *data, size_t datalen);
int tls13_extension_print(FILE *fp, int fmt, int ind,
int handshake_type, int ext_type, const uint8_t *ext_data, size_t ext_datalen);
int tls13_extensions_print(FILE *fp, int fmt, int ind,
int handshake_type, const uint8_t *exts, size_t extslen);
int tls13_certificate_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen);
int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen);
int tls13_certificate_verify_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen);
int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen);
int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], int record_type,
const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content
uint8_t *out, size_t *outlen); // TLSCiphertext.encrypted_record
int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
int *record_type, uint8_t *out, size_t *outlen);
#ifdef TLS_DEBUG
# define tls_trace(s) fprintf(stderr,(s))
# define tls_record_trace(fp,rec,reclen,fmt,ind) tls_record_print(fp,rec,reclen,fmt,ind)
# define tlcp_record_trace(fp,rec,reclen,fmt,ind) tlcp_record_print(fp,rec,reclen,fmt,ind)
# define tls12_record_trace(fp,rec,reclen,fmt,ind) tls12_record_print(fp,rec,reclen,fmt,ind)
# define tls13_record_trace(fp,rec,reclen,fmt,ind) tls13_record_print(fp,fmt,ind,rec,reclen)
#else
# define tls_trace(s)
# define tls_record_trace(fp,rec,reclen,fmt,ind)
# define tlcp_record_trace(fp,rec,reclen,fmt,ind)
# define tls12_record_trace(fp,rec,reclen,fmt,ind)
# define tls13_record_trace(fp,rec,reclen,fmt,ind)
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_VERSION_H
#define GMSSL_VERSION_H
#include <gmssl/api.h>
#ifdef __cplusplus
extern "C" {
#endif
// Also update CPACK_PACKAGE_VERSION in CMakeLists.txt
#define GMSSL_VERSION_NUM 30101
#define GMSSL_VERSION_STR "GmSSL 3.1.1"
_gmssl_export int gmssl_version_num(void);
_gmssl_export const char *gmssl_version_str(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,16 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_X509_H
#define GMSSL_X509_H
#include <gmssl/x509_cer.h>
#endif

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_X509_ALG_H
#define GMSSL_X509_ALG_H
#include <time.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm2.h>
#include <gmssl/oid.h>
#include <gmssl/asn1.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY }
*/
const char *x509_digest_algor_name(int oid);
int x509_digest_algor_from_name(const char *name);
int x509_digest_algor_from_der(int *oid, const uint8_t **in, size_t *inlen);
int x509_digest_algor_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_digest_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
const char *x509_encryption_algor_name(int oid);
int x509_encryption_algor_from_name(const char *name);
int x509_encryption_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen);
int x509_encryption_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen);
int x509_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
const char *x509_signature_algor_name(int oid);
int x509_signature_algor_from_name(const char *name);
int x509_signature_algor_from_der(int *oid, const uint8_t **in, size_t *inlen);
int x509_signature_algor_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_signature_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
const char *x509_public_key_encryption_algor_name(int oid);
int x509_public_key_encryption_algor_from_name(const char *name);
int x509_public_key_encryption_algor_from_der(int *oid, const uint8_t **params, size_t *params_len, const uint8_t **in, size_t *inlen);
int x509_public_key_encryption_algor_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_public_key_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
const char *x509_public_key_algor_name(int oid);
int x509_public_key_algor_from_name(const char *name);
int x509_public_key_algor_to_der(int oid, int curve, uint8_t **out, size_t *outlen);
int x509_public_key_algor_from_der(int *oid, int *curve_or_null, const uint8_t **in, size_t *inlen);
int x509_public_key_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,390 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_X509_CER_H
#define GMSSL_X509_CER_H
#include <time.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm2.h>
#include <gmssl/oid.h>
#include <gmssl/asn1.h>
#ifdef __cplusplus
extern "C" {
#endif
enum X509_Version {
X509_version_v1 = 0,
X509_version_v2 = 1,
X509_version_v3 = 2,
};
const char *x509_version_name(int version);
int x509_explicit_version_to_der(int index, int version, uint8_t **out, size_t *outlen);
int x509_explicit_version_from_der(int index, int *version, const uint8_t **in, size_t *inlen);
/*
Time ::= CHOICE {
utcTime UTCTime,
generalTime GeneralizedTime }
*/
#define X509_MAX_UTC_TIME 2524607999 // "20491231235959Z"
#define X509_MAX_GENERALIZED_TIME 253402300799 // "99991231235959Z"
int x509_time_to_der(time_t a, uint8_t **out, size_t *outlen);
int x509_time_from_der(time_t *a, const uint8_t **in, size_t *inlen);
/*
Validity ::= SEQUENCE {
notBefore Time,
notAfter Time }
*/
#define X509_VALIDITY_MIN_DAYS 1
#define X509_VALIDITY_MAX_DAYS 3653
#define X509_VALIDITY_MAX_SECONDS (X509_VALIDITY_MAX_DAYS * 86400)
int x509_validity_add_days(time_t *not_after, time_t not_before, int days);
int x509_validity_to_der(time_t not_before, time_t not_after, uint8_t **out, size_t *outlen);
int x509_validity_from_der(time_t *not_before, time_t *not_after, const uint8_t **in, size_t *inlen);
int x509_validity_check(time_t not_before, time_t not_after, time_t now, int max_secs);
int x509_validity_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
DirectoryString or DirectoryName
DirectoryName ::= CHOICE {
teletexString TeletexString (SIZE (1..MAX)),
printableString PrintableString (SIZE (1..MAX)),
universalString UniversalString (SIZE (1..MAX)),
utf8String UTF8String (SIZE (1..MAX)),
bmpString BMPString (SIZE (1..MAX)),
}
*/
int x509_directory_name_check(int tag, const uint8_t *d, size_t dlen);
int x509_directory_name_check_ex(int tag, const uint8_t *d, size_t dlen, size_t minlen, size_t maxlen);
int x509_directory_name_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int x509_directory_name_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
int x509_explicit_directory_name_to_der(int index, int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int x509_explicit_directory_name_from_der(int index, int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
int x509_directory_name_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen);
/*
AttributeTypeAndValue ::= SEQUENCE {
type OBJECT IDENTIFIER,
value ANY -- DEFINED BY AttributeType }
id-at
OID_at_name name DirectoryName 1..ub-name
OID_at_surname surname DirectoryName 1..ub-name
OID_at_given_name givenName DirectoryName 1..ub-name
OID_at_initials initials DirectoryName 1..ub-name
OID_at_generation_qualifier generationQualifier DirectoryName 1..ub-name
OID_at_common_name commonName DirectoryName 1..ub-common-name
OID_at_locality_name localityName DirectoryName 1..ub-locality-name
OID_at_state_or_province_name stateOrProvinceName DirectoryName 1..ub-state-name
OID_at_organization_name organizationName DirectoryName 1..ub-organization-name
OID_at_organizational_unit_name organizationalUnitName DirectoryName 1..ub-organizational-unit-name
OID_at_title title DirectoryName 1..ub-title
OID_at_dn_qualifier dnQualifier PrintableString N/A
OID_at_country_name countryName PrintableString 2..2
OID_at_serial_number serialNumber PrintableString 1..ub-serial-number
OID_at_pseudonym pseudonym DirectoryName 1..ub-pseudonym
OID_domain_component domainComponent IA5String N/A
*/
const char *x509_name_type_name(int oid);
int x509_name_type_from_name(const char *name);
int x509_name_type_from_der(int *oid, const uint8_t **in, size_t *inlen);
int x509_name_type_to_der(int oid, uint8_t **out, size_t *outlen);
#define X509_ub_name 32768
#define X509_ub_common_name 64
#define X509_ub_locality_name 128
#define X509_ub_state_name 128
#define X509_ub_organization_name 64
#define X509_ub_organizational_unit_name 64
#define X509_ub_title 64
#define X509_ub_serial_number 64
#define X509_ub_pseudonym 128
int x509_attr_type_and_value_check(int oid, int tag, const uint8_t *val, size_t vlen);
int x509_attr_type_and_value_to_der(int oid, int tag, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen);
int x509_attr_type_and_value_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, const uint8_t **in, size_t *inlen);
int x509_attr_type_and_value_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
*/
int x509_rdn_to_der(int oid, int tag, const uint8_t *val, size_t vlen, const uint8_t *more, size_t mlen, uint8_t **out, size_t *outlen);
int x509_rdn_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, const uint8_t **more, size_t *mlen, const uint8_t **in, size_t *inlen);
int x509_rdn_check(const uint8_t *d, size_t dlen);
int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
Name ::= SEQUENCE OF RelativeDistinguishedName
*/
int x509_name_add_rdn(uint8_t *d, size_t *dlen, size_t maxlen, int oid, int tag, const uint8_t *val, size_t vlen, const uint8_t *more, size_t mlen);
int x509_name_add_country_name(uint8_t *d, size_t *dlen, size_t maxlen, const char val[2] ); // val: PrintableString SIZE(2)
int x509_name_add_state_or_province_name(uint8_t *d, size_t *dlen, size_t maxlen, int tag, const uint8_t *val, size_t vlen);
int x509_name_add_locality_name(uint8_t *d, size_t *dlen, size_t maxlen, int tag, const uint8_t *val, size_t vlen);
int x509_name_add_organization_name(uint8_t *d, size_t *dlen, size_t maxlen, int tag, const uint8_t *val, size_t vlen);
int x509_name_add_organizational_unit_name(uint8_t *d, size_t *dlen, size_t maxlen, int tag, const uint8_t *val, size_t vlen);
int x509_name_add_common_name(uint8_t *d, size_t *dlen, size_t maxlen, int tag, const uint8_t *val, size_t vlen);
int x509_name_add_domain_component(uint8_t *d, size_t *dlen, size_t maxlen, const char *val, size_t vlen); // val: IA5String
int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen,
const char country[2], const char *state, const char *locality,
const char *org, const char *org_unit, const char *common_name);
#define x509_name_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_name_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
int x509_name_check(const uint8_t *d, size_t dlen);
int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen);
int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uint8_t **val, size_t *vlen);
int x509_name_equ(const uint8_t *a, size_t alen, const uint8_t *b, size_t blen);
int x509_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
algorithm.algorithm = OID_ec_public_key;
algorithm.parameters = OID_sm2;
subjectPublicKey = ECPoint
*/
#define x509_public_key_info_to_der(key,out,outlen) sm2_public_key_info_to_der(key,out,outlen)
#define x509_public_key_info_from_der(key,in,inlen) sm2_public_key_info_from_der(key,in,inlen)
int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER,
critical BOOLEAN DEFAULT FALSE,
extnValue OCTET STRING -- contains the DER encoding of an ASN.1 value
id-ce:
OID_ce_authority_key_identifier
OID_ce_subject_key_identifier
OID_ce_key_usage
OID_ce_certificate_policies
OID_ce_policy_mappings
OID_ce_subject_alt_name
OID_ce_issuer_alt_name
OID_ce_subject_directory_attributes
OID_ce_basic_constraints
OID_ce_name_constraints
OID_ce_policy_constraints
OID_ce_ext_key_usage
OID_ce_crl_distribution_points
OID_ce_inhibit_any_policy
OID_ce_freshest_crl
OID_netscape_cert_comment
*/
const char *x509_ext_id_name(int oid);
int x509_ext_id_from_name(const char *name);
int x509_ext_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_count, const uint8_t **in, size_t *inlen);
int x509_ext_id_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen);
int x509_ext_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical, const uint8_t **val, size_t *vlen, const uint8_t **in, size_t *inlen);
int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
[3] EXPLICIT SEQUENCE OF Extension
*/
int x509_explicit_exts_to_der(int index, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int x509_explicit_exts_from_der(int index, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
#define x509_exts_to_der(d,dlen,out,outlen) x509_explicit_exts_to_der(3,d,dlen,out,outlen)
#define x509_exts_from_der(d,dlen,in,inlen) x509_explicit_exts_from_der(3,d,dlen,in,inlen)
int x509_exts_get_ext_by_oid(const uint8_t *d, size_t dlen, int oid,
int *critical, const uint8_t **val, size_t *vlen);
int x509_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT INTEGER DEFAULT v1,
serialNumber INTEGER,
siganture AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPulbicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL, -- If present, must be v2,v3
subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL, -- If present, must be v2,v3
extensions [3] EXPLICIT Extensions OPTIONAL -- If present, must be v3 }
*/
#define X509_SERIAL_NUMBER_MIN_LEN 1
#define X509_SERIAL_NUMBER_MAX_LEN 20
#define X509_UNIQUE_ID_MIN_LEN 32
#define X509_UNIQUE_ID_MAX_LEN 32
int x509_tbs_cert_to_der(
int version,
const uint8_t *serial, size_t serial_len,
int signature_algor,
const uint8_t *issuer, size_t issuer_len,
time_t not_before, time_t not_after,
const uint8_t *subject, size_t subject_len,
const SM2_KEY *subject_public_key,
const uint8_t *issuer_unique_id, size_t issuer_unique_id_len,
const uint8_t *subject_unique_id, size_t subject_unique_id_len,
const uint8_t *exts, size_t exts_len,
uint8_t **out, size_t *outlen);
int x509_tbs_cert_from_der(
int *version,
const uint8_t **serial, size_t *serial_len,
int *signature_algor,
const uint8_t **issuer, size_t *issuer_len,
time_t *not_before, time_t *not_after,
const uint8_t **subject, size_t *subject_len,
SM2_KEY *subject_public_key,
const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len,
const uint8_t **subject_unique_id, size_t *subject_unique_id_len,
const uint8_t **exts, size_t *exts_len,
const uint8_t **in, size_t *inlen);
int x509_tbs_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING }
*/
int x509_certificate_to_der(
const uint8_t *tbs, size_t tbslen,
int signature_algor,
const uint8_t *sig, size_t siglen,
uint8_t **out, size_t *outlen);
int x509_certificate_from_der(
const uint8_t **tbs, size_t *tbslen,
int *signature_algor,
const uint8_t **sig, size_t *siglen,
const uint8_t **in, size_t *inlen);
int x509_signed_from_der(
const uint8_t **tbs, size_t *tbslen,
int *signature_algor,
const uint8_t **sig, size_t *siglen,
const uint8_t **in, size_t *inlen);
int x509_signed_verify(const uint8_t *a, size_t alen, const SM2_KEY *pub_key,
const char *signer_id, size_t signer_id_len);
int x509_signed_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen,
const char *signer_id, size_t signer_id_len);
// x509_cert functions
int x509_cert_sign_to_der(
int version,
const uint8_t *serial, size_t serial_len,
int signature_algor,
const uint8_t *issuer, size_t issuer_len,
time_t not_before, time_t not_after,
const uint8_t *subject, size_t subject_len,
const SM2_KEY *subject_public_key,
const uint8_t *issuer_unique_id, size_t issuer_unique_id_len,
const uint8_t *subject_unique_id, size_t subject_unique_id_len,
const uint8_t *exts, size_t exts_len,
const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len,
uint8_t **out, size_t *outlen);
int x509_cert_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen);
int x509_cert_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen);
int x509_cert_to_pem(const uint8_t *a, size_t alen, FILE *fp);
int x509_cert_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp);
int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, const uint8_t *name, size_t namelen, FILE *fp);
int x509_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen,
const char *signer_id, size_t signer_id_len);
int x509_cert_get_details(const uint8_t *a, size_t alen,
int *version,
const uint8_t **serial_number, size_t *serial_number_len,
int *inner_signature_algor,
const uint8_t **issuer, size_t *issuer_len,
time_t *not_before, time_t *not_after,
const uint8_t **subject, size_t *subject_len,
SM2_KEY *subject_public_key,
const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len,
const uint8_t **subject_unique_id, size_t *subject_unique_id_len,
const uint8_t **extensions, size_t *extensions_len,
int *signature_algor,
const uint8_t **signature, size_t *signature_len);
typedef enum {
X509_cert_server_auth,
X509_cert_client_auth,
X509_cert_server_key_encipher,
X509_cert_client_key_encipher,
X509_cert_ca,
X509_cert_root_ca,
X509_cert_crl_sign,
} X509_CERT_TYPE;
int x509_cert_check(const uint8_t *cert, size_t certlen, int cert_type, int *path_len_constraint);
/*
IssuerAndSerialNumber ::= SEQUENCE {
isser Name,
serialNumber INTEGER }
*/
int x509_cert_get_issuer_and_serial_number(const uint8_t *a, size_t alen,
const uint8_t **issuer, size_t *issuer_len,
const uint8_t **serial_number, size_t *serial_number_len);
int x509_cert_get_issuer(const uint8_t *a, size_t alen, const uint8_t **name, size_t *namelen);
int x509_cert_get_subject(const uint8_t *a, size_t alen, const uint8_t **subj, size_t *subj_len);
int x509_cert_get_subject_public_key(const uint8_t *a, size_t alen, SM2_KEY *public_key);
int x509_cert_get_exts(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen);
int x509_certs_to_pem(const uint8_t *d, size_t dlen, FILE *fp);
int x509_certs_from_pem(uint8_t *d, size_t *dlen, size_t maxlen, FILE *fp);
int x509_certs_get_count(const uint8_t *d, size_t dlen, size_t *cnt);
int x509_certs_get_cert_by_index(const uint8_t *d, size_t dlen, int index, const uint8_t **cert, size_t *certlen);
int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen, const uint8_t *subject, size_t subject_len, const uint8_t **cert, size_t *certlen);
int x509_certs_get_last(const uint8_t *d, size_t dlen, const uint8_t **cert, size_t *certlen);
int x509_certs_get_cert_by_subject_and_key_identifier(const uint8_t *d, size_t dlen,
const uint8_t *subject, size_t subject_len,
const uint8_t *key_id, size_t key_id_len,
const uint8_t **cert, size_t *certlen);
int x509_certs_get_cert_by_issuer_and_serial_number(
const uint8_t *certs, size_t certs_len,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len,
const uint8_t **cert, size_t *cert_len);
typedef enum {
X509_cert_chain_server,
X509_cert_chain_client,
} X509_CERT_CHAIN_TYPE;
#define X509_MAX_VERIFY_DEPTH 6
int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result);
int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type,
const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result);
int x509_certs_get_subjects(const uint8_t *certs, size_t certslen, uint8_t *names, size_t *nameslen);
int x509_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_cert_new_from_file(uint8_t **out, size_t *outlen, const char *file);
int x509_certs_new_from_file(uint8_t **out, size_t *outlen, const char *file);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,309 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_X509_CRL_H
#define GMSSL_X509_CRL_H
#include <time.h>
#include <stdint.h>
#include <gmssl/sm2.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
CRLReason ::= ENUMERATED
*/
typedef enum {
X509_cr_unspecified = 0,
X509_cr_key_compromise = 1,
X509_cr_ca_compromise = 2 ,
X509_cr_affiliation_changed = 3,
X509_cr_superseded = 4,
X509_cr_cessation_of_operation = 5,
X509_cr_certificate_hold = 6,
X509_cr_not_assigned = 7,
X509_cr_remove_from_crl = 8,
X509_cr_privilege_withdrawn = 9,
X509_cr_aa_compromise = 10,
} X509_CRL_REASON;
const char *x509_crl_reason_name(int reason);
int x509_crl_reason_from_name(int *reason, const char *name);
int x509_crl_reason_to_der(int reason, uint8_t **out, size_t *outlen);
int x509_crl_reason_from_der(int *reason, const uint8_t **in, size_t *inlen);
int x509_implicit_crl_reason_from_der(int index, int *reason, const uint8_t **in, size_t *inlen);
/*
CRL Entry Extensions:
OID_ce_crl_reasons ENUMERATED non-critical
OID_ce_invalidity_date GeneralizedTime non-critical
OID_ce_certificate_issuer GeneralNames MUST critical
*/
const char *x509_crl_entry_ext_id_name(int oid);
int x509_crl_entry_ext_id_from_name(const char *name);
int x509_crl_entry_ext_id_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_crl_entry_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen);
int x509_crl_entry_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen);
int x509_crl_entry_ext_from_der(int *oid, int *critical, const uint8_t **val, size_t *vlen, const uint8_t **in, size_t *inlen);
int x509_crl_entry_ext_critical_check(int oid, int critical);
int x509_crl_entry_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_crl_reason_ext_to_der(int critical, int reason, uint8_t **out, size_t *outlen);
int x509_invalidity_date_ext_to_der(int critical, time_t date, uint8_t **out, size_t *outlen);
int x509_cert_issuer_ext_to_der(int critical, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int x509_crl_entry_ext_from_der_ex(int *oid, int *critical,
int *reason, time_t *invalid_date, const uint8_t **cert_issuer, size_t *cert_issuer_len,
const uint8_t **in, size_t *inlen);
int x509_crl_entry_exts_to_der(
int reason, time_t invalid_date, const uint8_t *cert_issuer, size_t cert_issuer_len,
uint8_t **out, size_t *outlen);
int x509_crl_entry_exts_from_der(
int *reason, time_t *invalid_date, const uint8_t **cert_issuer, size_t *cert_issuer_len,
const uint8_t **in, size_t *inlen);
int x509_crl_entry_exts_get(const uint8_t *d, size_t dlen,
int *reason, time_t *invalid_date, const uint8_t **cert_issuer, size_t *cert_issuer_len);
int x509_crl_entry_exts_check(const uint8_t *d, size_t dlen);
int x509_crl_entry_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
RevokedCertificate ::= SEQUENCE {
userCertificate CertificateSerialNumber,
revocationDate Time,
crlEntryExtensions Extensions OPTIONAL }
*/
int x509_revoked_cert_to_der(
const uint8_t *serial, size_t serial_len, time_t revoke_date,
const uint8_t *crl_entry_exts, size_t crl_entry_exts_len,
uint8_t **out, size_t *outlen);
int x509_revoked_cert_from_der(
const uint8_t **serial, size_t *serial_len, time_t *revoke_date,
const uint8_t **crl_entry_exts, size_t *crl_entry_exts_len,
const uint8_t **in, size_t *inlen);
int x509_revoked_cert_to_der_ex(
const uint8_t *serial, size_t serial_len, time_t revoke_date,
int reason, time_t invalid_date, const uint8_t *cert_issuer, size_t cert_issuer_len,
uint8_t **out, size_t *outlen);
int x509_revoked_cert_from_der_ex(
const uint8_t **serial, size_t *serial_len, time_t *revoke_date,
int *reason, time_t *invalid_date, const uint8_t **cert_issuer, size_t *cert_issuer_len,
const uint8_t **in, size_t *inlen);
int x509_revoked_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_cert_revoke_to_der(const uint8_t *cert, size_t certlen,
time_t revoke_date, int reason, time_t invalid_date, const uint8_t *cert_issuer, size_t cert_issuer_len,
uint8_t **out, size_t *outlen);
/*
RevokedCertificates ::= SEQUENCE OF RevokedCertificate
*/
int x509_revoked_certs_find_revoked_cert_by_serial_number(const uint8_t *d, size_t dlen,
const uint8_t *serial, size_t serial_len, time_t *revoke_date,
const uint8_t **crl_entry_exts, size_t *crl_entry_exts_len);
int x509_revoked_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
CRL Extensions:
OID_ce_authority_key_identifier AuthorityKeyIdentifier critical or non-critical
OID_ce_issuer_alt_name GeneralNames SHOULD non-critical
OID_ce_crl_number INTEGER MUST non-critical
OID_ce_delta_crl_indicator INTEGER MUST critical
OID_ce_issuing_distribution_point IssuingDistributionPoint critical
OID_ce_freshest_crl CRLDistributionPoints MUST non-critical
OID_pe_authority_info_access AccessDescriptions MUST non-critical
*/
const char *x509_crl_ext_id_name(int oid);
int x509_crl_ext_id_from_name(const char *name);
int x509_crl_ext_id_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_crl_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen);
int x509_crl_ext_id_from_der_ex(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen);
/*
IssuingDistributionPoint ::= SEQUENCE {
distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL,
onlyContainsUserCerts [1] IMPLICIT BOOLEAN DEFAULT FALSE,
onlyContainsCACerts [2] IMPLICIT BOOLEAN DEFAULT FALSE,
onlySomeReasons [3] IMPLICIT ReasonFlags OPTIONAL,
indirectCRL [4] IMPLICIT BOOLEAN DEFAULT FALSE,
onlyContainsAttributeCerts [5] IMPLICIT BOOLEAN DEFAULT FALSE }
*/
int x509_issuing_distribution_point_to_der(
const char *dist_point_uri, size_t dist_point_uri_len,
int only_contains_user_certs,
int only_contains_ca_certs,
int only_some_reasons,
int indirect_crl,
int only_contains_attr_certs,
uint8_t **out, size_t *outlen);
int x509_issuing_distribution_point_from_der(
int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len,
int *only_contains_user_certs,
int *only_contains_ca_certs,
int *only_some_reasons,
int *indirect_crl,
int *only_contains_attr_certs,
const uint8_t **in, size_t *inlen);
int x509_issuing_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_crl_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen);
int x509_crl_ext_from_der_ex(int *oid, uint32_t *nodes, size_t *nodes_cnt,
int *critical, const uint8_t **val, size_t *vlen,
const uint8_t **in, size_t *inlen);
int x509_crl_ext_critical_check(int oid, int critical);
int x509_crl_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_crl_exts_add_authority_key_identifier(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
const uint8_t *keyid, size_t keyid_len,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len);
int x509_crl_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen,
const SM2_KEY *public_key);
int x509_crl_exts_add_issuer_alt_name(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
const uint8_t *d, size_t dlen);
int x509_crl_exts_add_crl_number_ex(
uint8_t *exts, size_t *extslen, size_t maxlen,
int oid, int critical, int num);
int x509_crl_exts_add_crl_number(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
int num);
int x509_crl_exts_add_delta_crl_indicator(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
int num);
int x509_crl_exts_add_issuing_distribution_point(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
const char *dist_point_uri, size_t dist_point_uri_len,
int only_contains_user_certs,
int only_contains_ca_certs,
int only_some_reasons,
int indirect_crl,
int only_contains_attr_certs);
int x509_crl_exts_add_freshest_crl(
uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
const char *http_uri, size_t http_urilen,
const char *ldap_uri, size_t ldap_urilen);
int x509_crl_exts_add_authority_info_acess(
uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
const char *ca_issuers_uri, size_t ca_issuers_urilen,
const char *ocsp_uri, size_t ocsp_urilen);
#define x509_crl_exts_to_der(d,dlen,out,outlen) x509_explicit_exts_to_der(0,d,dlen,out,outlen)
#define x509_crl_exts_from_der(d,dlen,in,inlen) x509_explicit_exts_from_der(0,d,dlen,in,inlen)
int x509_crl_exts_check(const uint8_t *d, size_t dlen);
int x509_crl_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
TBSCertList ::= SEQUENCE {
version INTEGER OPTIONAL, -- if present, MUST be v2
signature AlgorithmIdentifier,
issuer Name,
thisUpdate Time,
nextUpdate Time OPTIONAL,
revokedCertificates RevokedCertificates OPTIONAL,
crlExtensions [0] EXPLICIT Extensions OPTIONAL, -- if present, MUST be v2 }
*/
int x509_tbs_crl_to_der(
int version,
int signature_algor,
const uint8_t *issuer, size_t issuer_len,
time_t this_update,
time_t next_update,
const uint8_t *revoked_certs, size_t revoked_certs_len,
const uint8_t *exts, size_t exts_len,
uint8_t **out, size_t *outlen);
int x509_tbs_crl_from_der(
int *version,
int *signature_algor,
const uint8_t **issuer, size_t *issuer_len,
time_t *this_update,
time_t *next_update,
const uint8_t **revoked_certs, size_t *revoked_certs_len,
const uint8_t **exts, size_t *exts_len,
const uint8_t **in, size_t *inlen);
int x509_tbs_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
CertificateList ::= SEQUENCE {
tbsCertList TBSCertList,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING }
*/
int x509_crl_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen);
int x509_crl_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen);
int x509_crl_to_pem(const uint8_t *a, size_t alen, FILE *fp);
int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp);
int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
int x509_crl_sign_to_der(
int version, int sig_alg,
const uint8_t *issuer, size_t issuer_len,
time_t this_update, time_t next_update,
const uint8_t *revoked_certs, size_t revoked_certs_len,
const uint8_t *crl_exts, size_t crl_exts_len,
const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len,
uint8_t **out, size_t *outlen);
int x509_crl_from_der_ex(
int *version,
int *inner_sig_alg,
const uint8_t **issuer, size_t *issuer_len,
time_t *this_update, time_t *next_update,
const uint8_t **revoked_certs, size_t *revoked_certs_len,
const uint8_t **exts, size_t *exts_len,
int *sig_alg, const uint8_t **sig, size_t *siglen,
const uint8_t **in, size_t *inlen);
int x509_crl_check(const uint8_t *a, size_t alen, time_t now);
int x509_crl_verify(const uint8_t *a, size_t alen,
const SM2_KEY *sign_pub_key, const char *signer_id, size_t signer_id_len);
int x509_crl_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen,
const char *signer_id, size_t signer_id_len);
int x509_crl_get_details(const uint8_t *crl, size_t crl_len,
int *version,
int *inner_sig_alg,
const uint8_t **issuer, size_t *issuer_len,
time_t *this_update,
time_t *next_update,
const uint8_t **revoked_certs, size_t *revoked_certs_len,
const uint8_t **exts, size_t *exts_len,
int *signature_algor,
const uint8_t **sig, size_t *siglen);
int x509_crl_get_issuer(const uint8_t *crl, size_t crl_len,
const uint8_t **issuer, size_t *issuer_len);
int x509_crl_get_revoked_certs(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen);
int x509_crl_find_revoked_cert_by_serial_number(const uint8_t *a, size_t alen,
const uint8_t *serial, size_t serial_len, time_t *revoke_date,
const uint8_t **entry_exts, size_t *entry_exts_len);
int x509_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_crl_new_from_uri(uint8_t **crl, size_t *crl_len, const char *uri, size_t urilen);
int x509_crl_new_from_cert(uint8_t **crl, size_t *crl_len, const uint8_t *cert, size_t certlen);
int x509_cert_check_crl(const uint8_t *cert, size_t certlen, const uint8_t *cacert, size_t cacertlen,
const char *ca_signer_id, size_t ca_signer_id_len);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,641 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_X509_EXT_H
#define GMSSL_X509_EXT_H
#include <time.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm2.h>
#include <gmssl/oid.h>
#include <gmssl/asn1.h>
#ifdef __cplusplus
extern "C" {
#endif
enum {
X509_non_critical = 0,
X509_critical = 1,
};
/*
Extensions:
1. AuthorityKeyIdentifier SEQUENCE AuthorityKeyIdentifier MUST non-critical
2. SubjectKeyIdentifier OCTET STRING MUST non-critical
3. KeyUsage BIT STRING SHOULD critical
4. CertificatePolicies SEQUENCE OF SEQUENCE CertificatePolicies
5. PolicyMappings SEQUENCE OF SEQUENCE PolicyMappings SHOULD critical
6. SubjectAltName SEQUENCE OF SEQUENCE GeneralNames SHOULD non-critical
7. IssuerAltName SEQUENCE OF SEQUENCE GeneralNames SHOULD non-critical
8. SubjectDirectoryAttributes SEQUENCE OF SEQUENCE Attributes MUST non-critical
9. BasicConstraints SEQUENCE BasicConstraints CA: MUST critical, End-entity: MAY critical or non-critical
10. NameConstraints SEQUENCE NameConstraints
11. PolicyConstraints SEQUENCE PolicyConstraints MUST critical
12. ExtKeyUsageSyntax SEQUENCE OF OBJECT IDENTIFIER MAY critical or non-critical
13. CRLDistributionPoints SEQUENCE OF SEQUENCE DistributionPoints
14. InhibitAnyPolicy INTEGER MUST critical
15. FreshestCRL SEQUENCE OF SEQUENCE DistributionPoints MUST non-critical
*/
int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
const uint8_t *keyid, size_t keyid_len,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len);
int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen,
const SM2_KEY *public_key);
int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
int x509_exts_add_subject_key_identifier_ex(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const SM2_KEY *subject_key);
int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int bits);
int x509_exts_add_certificate_policies(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
int x509_exts_add_policy_mappings(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
int x509_exts_add_subject_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
int x509_exts_add_issuer_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
int x509_exts_add_subject_directory_attributes(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
int x509_exts_add_name_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
const uint8_t *permitted_subtrees, size_t permitted_subtrees_len,
const uint8_t *excluded_subtrees, size_t excluded_subtrees_len);
int x509_exts_add_policy_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
int require_explicit_policy, int inhibit_policy_mapping);
int x509_exts_add_basic_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int ca, int path_len_constraint);
int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const int *key_purposes, size_t key_purposes_cnt);
int x509_exts_add_crl_distribution_points_ex(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int oid,
const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen);
int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen);
int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int skip_certs);
int x509_exts_add_freshest_crl(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
int x509_exts_add_authority_info_access(uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
const char *ca_issuers_uri, size_t ca_issuers_urilen, // ca_issuers_uri is the URI (http://examaple.com/subCA.crt) of DER-encoded CA cert
const char *ocsp_uri, size_t ocsp_urilen);
int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen,
int oid, int critical, const uint8_t *d, size_t dlen);
/*
OtherName ::= SEQUENCE {
type-id OBJECT IDENTIFIER, -- known oid from x509_rdn_oid such as OID_at_common_name, or oid nodes
value [0] EXPLICIT ANY DEFINED BY type-id }
*/
int x509_other_name_to_der(
const uint32_t *nodes, size_t nodes_count,
const uint8_t *value, size_t value_len,
uint8_t **out, size_t *outlen);
int x509_other_name_from_der(
uint32_t *nodes, size_t *nodes_count,
const uint8_t **value, size_t *valuelen,
const uint8_t **in, size_t *inlen);
int x509_other_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
EDIPartyName ::= SEQUENCE {
nameAssigner [0] EXPLICIT DirectoryString OPTIONAL,
partyName [1] EXPLICIT DirectoryString }
*/
int x509_edi_party_name_to_der(
int assigner_tag, const uint8_t *assigner, size_t assigner_len,
int party_name_tag, const uint8_t *party_name, size_t party_name_len,
uint8_t **out, size_t *outlen);
int x509_edi_party_name_from_der(
int *assigner_tag, const uint8_t **assigner, size_t *assigner_len,
int *party_name_tag, const uint8_t **party_name, size_t *party_name_len,
const uint8_t **in, size_t *inlen);
int x509_edi_party_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
GeneralName ::= CHOICE {
otherName [0] IMPLICIT OtherName, -- Only in GeneralName
rfc822Name [1] IMPLICIT IA5String,
dNSName [2] IMPLICIT IA5String,
x400Address [3] IMPLICIT ORAddress,
directoryName [4] IMPLICIT Name, -- SEQENCE OF
ediPartyName [5] IMPLICIT EDIPartyName, -- Only in GeneralName
uniformResourceIdentifier [6] IMPLICIT IA5String,
iPAddress [7] IMPLICIT OCTET STRING, -- 4 bytes or string?
registeredID [8] IMPLICIT OBJECT IDENTIFIER }
*/
typedef enum {
X509_gn_other_name = 0,
X509_gn_rfc822_name = 1,
X509_gn_dns_name = 2,
X509_gn_x400_address = 3,
X509_gn_directory_name = 4,
X509_gn_edi_party_name = 5,
X509_gn_uniform_resource_identifier = 6,
X509_gn_ip_address = 7,
X509_gn_registered_id = 8,
} X509_GENERAL_NAME_CHOICE;
int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen);
/*
GeneralNames ::= SEQUENCE OF GeneralName
*/
#define x509_general_names_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_general_names_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t maxlen,
int choice, const uint8_t *d, size_t dlen);
int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_general_names_add_other_name(uint8_t *gns, size_t *gnslen, size_t maxlen,
const uint32_t *nodes, size_t nodes_count,
const uint8_t *value, size_t value_len);
#define x509_general_names_add_rfc822_name(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_rfc822_name,(uint8_t*)s,strlen(s))
#define x509_general_names_add_dns_name(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_dns_name,(uint8_t*)s,strlen(s))
#define x509_general_names_add_x400_address(a,alen,maxlen,d,dlen) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_x400_address,d,dlen)
#define x509_general_names_add_directory_name(a,alen,maxlen,d,dlen) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_directory_name,d,dlen)
int x509_general_names_add_edi_party_name(uint8_t *gns, size_t *gnslen, size_t maxlen,
int assigner_tag, const uint8_t *assigner, size_t assigner_len,
int party_name_tag, const uint8_t *party_name, size_t party_name_len);
#define x509_general_names_add_uniform_resource_identifier(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_uniform_resource_identifier,(uint8_t*)s,strlen(s))
#define x509_general_names_add_ip_address(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_ip_address,(uint8_t*)s,strlen(s))
int x509_general_names_add_registered_id(uint8_t *gns, size_t *gnslen, size_t maxlen,
const uint32_t *nodes, size_t nodes_cnt);
int x509_uri_as_general_names_to_der_ex(int tag, const char *uri, size_t urilen, uint8_t **out, size_t *outlen);
#define x509_uri_as_general_names_to_der(uri,urilen,out,outlen) x509_uri_as_general_names_to_der_ex(ASN1_TAG_SEQUENCE,uri,urilen,out,outlen)
/*
AuthorityKeyIdentifier ::= SEQUENCE {
keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL,
authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL,
authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL }
*/
int x509_authority_key_identifier_to_der(
const uint8_t *keyid, size_t keyid_len,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len,
uint8_t **out, size_t *outlen);
int x509_authority_key_identifier_from_der(
const uint8_t **keyid, size_t *keyid_len,
const uint8_t **issuer, size_t *issuer_len,
const uint8_t **serial, size_t *serial_len,
const uint8_t **in, size_t *inlen);
int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
SubjectKeyIdentifier ::= OCTET STRING
*/
#define X509_SUBJECT_KEY_IDENTIFIER_MIN_LEN 16
#define X509_SUBJECT_KEY_IDENTIFIER_MAX_LEN 64
/*
KeyUsage ::= BIT STRING {
digitalSignature (0),
nonRepudiation (1), -- recent renamed contentCommitment
keyEncipherment (2),
dataEncipherment (3),
keyAgreement (4),
keyCertSign (5),
cRLSign (6),
encipherOnly (7),
decipherOnly (8) }
*/
#define X509_KU_DIGITAL_SIGNATURE (1 << 0)
#define X509_KU_NON_REPUDIATION (1 << 1)
#define X509_KU_KEY_ENCIPHERMENT (1 << 2)
#define X509_KU_DATA_ENCIPHERMENT (1 << 3)
#define X509_KU_KEY_AGREEMENT (1 << 4)
#define X509_KU_KEY_CERT_SIGN (1 << 5)
#define X509_KU_CRL_SIGN (1 << 6)
#define X509_KU_ENCIPHER_ONLY (1 << 7)
#define X509_KU_DECIPHER_ONLY (1 << 8)
const char *x509_key_usage_name(int flag);
int x509_key_usage_from_name(int *flag, const char *name);
#define x509_key_usage_to_der(bits,out,outlen) asn1_bits_to_der(bits,out,outlen)
#define x509_key_usage_from_der(bits,in,inlen) asn1_bits_from_der(bits,in,inlen)
int x509_key_usage_check(int bits, int cert_type);
int x509_key_usage_print(FILE *fp, int fmt, int ind, const char *label, int bits);
/*
DisplayText ::= CHOICE {
ia5String IA5String (SIZE (1..200)),
visibleString VisibleString (SIZE (1..200)),
bmpString BMPString (SIZE (1..200)),
utf8String UTF8String (SIZE (1..200))
}
*/
#define X509_DISPLAY_TEXT_MIN_LEN 1
#define X509_DISPLAY_TEXT_MAX_LEN 200
int x509_display_text_check(int tag, const uint8_t *d, size_t dlen);
int x509_display_text_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int x509_display_text_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
int x509_display_text_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen);
/*
NoticeReference ::= SEQUENCE {
organization DisplayText,
noticeNumbers SEQUENCE OF INTEGER }
UserNotice ::= SEQUENCE {
noticeRef NoticeReference OPTIONAL,
explicitText DisplayText OPTIONAL }
*/
#define X509_MAX_NOTICE_NUMBERS 32
int x509_notice_reference_to_der(
int org_tag, const uint8_t *org, size_t org_len,
const int *notice_numbers, size_t notice_numbers_cnt,
uint8_t **out, size_t *outlen);
int x509_notice_reference_from_der(
int *org_tag, const uint8_t **org, size_t *org_len,
int *notice_numbers, size_t *notice_numbers_cnt, size_t max_notice_numbers,
const uint8_t **in, size_t *inlen);
int x509_notice_reference_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_user_notice_to_der(
int notice_ref_org_tag, const uint8_t *notice_ref_org, size_t notice_ref_org_len,
const int *notice_ref_notice_numbers, size_t notice_ref_notice_numbers_cnt,
int explicit_text_tag, const uint8_t *explicit_text, size_t explicit_text_len,
uint8_t **out, size_t *outlen);
int x509_user_notice_from_der(
int *notice_ref_org_tag, const uint8_t **notice_ref_org, size_t *notice_ref_org_len,
int *notice_ref_notice_numbers, size_t *notice_ref_notice_numbers_cnt, size_t max_notice_ref_notice_numbers,
int *explicit_text_tag, const uint8_t **explicit_text, size_t *explicit_text_len,
const uint8_t **in, size_t *inlen);
int x509_user_notice_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
PolicyQualifierInfo ::= SEQUENCE {
policyQualifierId PolicyQualifierId,
qualifier ANY DEFINED BY policyQualifierId }
id-qt
OID_qt_cps
OID_qt_unotice
switch(policyQualifierId)
case id-qt-cps : qualifier ::= IA5String
case id-qt-unotice : qualifier ::= UserNotice
*/
const char *x509_qualifier_id_name(int oid);
int x509_qualifier_id_from_name(const char *name);
int x509_qualifier_id_from_der(int *oid, const uint8_t **in, size_t *inlen);
int x509_qualifier_id_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_policy_qualifier_info_to_der(
int oid,
const uint8_t *qualifier, size_t qualifier_len,
uint8_t **out, size_t *outlen);
int x509_policy_qualifier_info_from_der(
int *oid,
const uint8_t **qualifier, size_t *qualifier_len,
const uint8_t **in, size_t *inlen);
int x509_policy_qualifier_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#define x509_policy_qualifier_infos_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_policy_qualifier_infos_from_der(d,dlen,in,ineln) asn1_sequence_from_der(d,dlen,in,inlen)
int x509_policy_qualifier_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
PolicyInformation ::= SEQUENCE {
policyIdentifier CertPolicyId,
policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL }
CertPolicyId ::= OBJECT IDENTIFIER -- undefined
OID_any_policy
*/
char *x509_cert_policy_id_name(int oid);
int x509_cert_policy_id_from_name(const char *name);
int x509_cert_policy_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen);
int x509_cert_policy_id_to_der(int oid, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen);
int x509_policy_information_to_der(
int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt,
const uint8_t *qualifiers, size_t qualifiers_len,
uint8_t **out, size_t *outlen);
int x509_policy_information_from_der(
int *policy_oid, uint32_t *policy_nodes, size_t *policy_nodes_cnt,
const uint8_t **qualifiers, size_t *qualifiers_len,
const uint8_t **in, size_t *inlen);
int x509_policy_information_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
*/
int x509_certificate_policies_add_policy_information(uint8_t *d, size_t *dlen, size_t maxlen,
int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt,
const uint8_t *qualifiers, size_t qualifiers_len);
int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#define x509_certificate_policies_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_certificate_policies_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
/*
PolicyMapping ::= SEQUENCE {
issuerDomainPolicy CertPolicyId, -- id-anyPolicy or other undefined
subjectDomainPolicy CertPolicyId }
*/
int x509_policy_mapping_to_der(
int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt,
int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt,
uint8_t **out, size_t *outlen);
int x509_policy_mapping_from_der(
int *issuer_policy_oid, uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_cnt,
int *subject_policy_oid, uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_cnt,
const uint8_t **in, size_t *inlen);
int x509_policy_mapping_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
PolicyMappings ::= SEQUENCE OF PolicyMapping
*/
int x509_policy_mappings_add_policy_mapping(uint8_t *d, size_t *dlen, size_t maxlen,
int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt,
int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt);
int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#define x509_policy_mappings_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_policy_mappings_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
/*
SubjectAltName ::= GeneralNames
*/
#define x509_subject_alt_name_print(fp,fmt,ind,label,d,dlen) x509_general_names_print(fp,fmt,ind,label,d,dlen)
/*
IssuerAltName ::= GeneralNames
*/
#define x509_issuer_alt_name_print(fp,fmt,ind,label,d,dlen) x509_general_names_print(fp,fmt,ind,label,d,dlen)
/*
SubjectDirectoryAttributes ::= SEQUENCE OF Attribute
Attribute ::= SEQUENCE {
type OBJECT IDENTIFIER,
values SET OF ANY }
*/
int x509_attribute_to_der(
const uint32_t *nodes, size_t nodes_cnt,
const uint8_t *values, size_t values_len,
uint8_t **out, size_t *outlen);
int x509_attribute_from_der(
int *oid, uint32_t *nodes, size_t *nodes_cnt,
const uint8_t **values, size_t *values_len,
const uint8_t **in, size_t *inlen);
int x509_attribute_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_attributes_add_attribute(uint8_t *d, size_t *dlen, size_t maxlen,
const uint32_t *nodes, size_t nodes_cnt,
const uint8_t *values, size_t values_len);
int x509_attributes_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#define x509_attributes_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_attributes_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
/*
BasicConstraints ::= SEQUENCE {
cA BOOLEAN DEFAULT FALSE,
pathLenConstraint INTEGER (0..MAX) OPTIONAL }
*/
#define X509_MAX_PATH_LEN_CONSTRAINT 6
int x509_basic_constraints_to_der(int ca, int path_len_cons, uint8_t **out, size_t *outlen);
int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t **in, size_t *inlen);
int x509_basic_constraints_check(int ca, int path_len_cons, int cert_type);
int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
GeneralSubtree ::= SEQUENCE {
base GeneralName,
minimum [0] IMPLICIT BaseDistance DEFAULT 0,
maximum [1] IMPLICIT BaseDistance OPTIONAL }
BaseDistance ::= INTEGER (0..MAX)
*/
int x509_general_subtree_to_der(
int base_choice, const uint8_t *base, size_t base_len,
int minimum, int maximum,
uint8_t **out, size_t *outlen);
int x509_general_subtree_from_der(
int *base_choice, const uint8_t **base, size_t *base_len,
int *minimum, int *maximum,
const uint8_t **in, size_t *inlen);
int x509_general_subtree_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
*/
int x509_general_subtrees_add_general_subtree(uint8_t *d, size_t *dlen, size_t maxlen,
int base_choice, const uint8_t *base, size_t base_len,
int minimum, int maximum);
int x509_general_subtrees_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#define x509_general_subtrees_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_general_subtrees_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
/*
NameConstraints ::= SEQUENCE {
permittedSubtrees [0] GeneralSubtrees OPTIONAL,
excludedSubtrees [1] GeneralSubtrees OPTIONAL }
*/
int x509_name_constraints_to_der(
const uint8_t *permitted_subtrees, size_t permitted_subtrees_len,
const uint8_t *excluded_subtrees, size_t excluded_subtrees_len,
uint8_t **out, size_t *outlen);
int x509_name_constraints_from_der(
const uint8_t **permitted_subtrees, size_t *permitted_subtrees_len,
const uint8_t **excluded_subtrees, size_t *excluded_subtrees_len,
const uint8_t **in, size_t *inlen);
int x509_name_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
PolicyConstraints ::= SEQUENCE {
requireExplicitPolicy [0] IMPLICIT SkipCerts OPTIONAL,
inhibitPolicyMapping [1] IMPLICIT SkipCerts OPTIONAL
}
SkipCerts ::= INTEGER (0..MAX)
*/
int x509_policy_constraints_to_der(int require_explicit_policy, int inhibit_policy_mapping, uint8_t **out, size_t *outlen);
int x509_policy_constraints_from_der(int *require_explicit_policy, int *inhibit_policy_mapping, const uint8_t **in, size_t *inlen);
int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
KeyPurposeId:
OID_any_extended_key_usage
id-kp
OID_kp_server_auth
OID_kp_client_auth
OID_kp_code_signing
OID_kp_email_protection
OID_kp_time_stamping
OID_kp_ocsp_signing
*/
#define X509_MAX_KEY_PURPOSES 7
const char *x509_key_purpose_name(int oid);
const char *x509_key_purpose_text(int oid);
int x509_key_purpose_from_name(const char *name);
int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen);
int x509_key_purpose_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_ext_key_usage_to_der(const int *oids, size_t oids_cnt, uint8_t **out, size_t *outlen);
int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, const uint8_t **in, size_t *inlen);
int x509_ext_key_usage_check(const int *oids, size_t oids_cnt, int cert_type);
int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
ReasonFlags ::= BIT STRING {
unused (0),
keyCompromise (1),
cACompromise (2),
affiliationChanged (3),
superseded (4),
cessationOfOperation (5),
certificateHold (6),
privilegeWithdrawn (7),
aACompromise (8) }
*/
#define X509_RF_UNUSED (1 << 0)
#define X509_RF_KEY_COMPROMISE (1 << 1)
#define X509_RF_CA_COMPROMISE (1 << 2)
#define X509_RF_AFFILIATION_CHANGED (1 << 3)
#define X509_RF_SUPERSEDED (1 << 4)
#define X509_RF_CESSATION_OF_OPERATION (1 << 5)
#define X509_RF_CERTIFICATE_HOLD (1 << 6)
#define X509_RF_PRIVILEGE_WITHDRAWN (1 << 7)
#define X509_RF_AA_COMPROMISE (1 << 8)
const char *x509_revoke_reason_flag_name(int flag);
int x509_revoke_reason_flag_from_name(int *flag, const char *name);
#define x509_revoke_reason_flags_to_der(bits,out,outlen) asn1_bits_to_der(bits,out,outlen)
#define x509_revoke_reason_flags_from_der(bits,in,inlen) asn1_bits_from_der(bits,in,inlen)
int x509_revoke_reason_flags_print(FILE *fp, int fmt, int ind, const char *label, int bits);
/*
DistributionPointName ::= CHOICE {
fullName [0] IMPLICIT GeneralNames, -- SEQUENCE OF
nameRelativeToCRLIssuer [1] IMPLICIT RelativeDistinguishedName } -- SET OF
*/
enum {
X509_full_name = 0,
X509_name_relative_to_crl_issuer = 1,
};
int x509_uri_as_distribution_point_name_to_der(const char *uri, size_t urilen, uint8_t **out, size_t *outlen);
int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
int x509_uri_as_distribution_point_name_from_der(const char **uri, size_t *urilen, const uint8_t **in, size_t *inlen);
int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label,const uint8_t *a, size_t alen);
int x509_uri_as_explicit_distribution_point_name_to_der(int index, const char *uri, size_t urilen, uint8_t **out, size_t *outlen);
int x509_uri_as_explicit_distribution_point_name_from_der(int index, const char **uri, size_t *urilen, const uint8_t **in, size_t *inlen);
/*
DistributionPoint ::= SEQUENCE {
distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL,
reasons [1] IMPLICIT ReasonFlags OPTIONAL,
cRLIssuer [2] IMPLICIT GeneralNames OPTIONAL }
*/
int x509_uri_as_distribution_point_to_der(const char *uri, size_t urilen,
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
uint8_t **out, size_t *outlen);
int x509_uri_as_distribution_point_from_der(const char **uri, size_t *urilen,
int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len,
const uint8_t **in, size_t *inlen);
int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
DistributionPoints ::= SEQUENCE OF DistributionPoint
*/
int x509_uri_as_distribution_points_to_der(const char *uri, size_t urilen,
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
uint8_t **out, size_t *outlen);
int x509_uri_as_distribution_points_from_der(const char **uri, size_t *urilen,
int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len,
const uint8_t **in, size_t *inlen);
int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
*/
#define x509_crl_distribution_points_to_der(d,dlen,out,outlen) x509_distribution_points_to_der(d,dlen,out,outlen)
#define x509_crl_distribution_points_from_der(d,dlen,in,inlen) x509_distribution_points_from_der(d,dlen,in,inlen)
#define x509_crl_distribution_points_print(fp,fmt,ind,label,d,dlen) x509_distribution_points_print(fp,fmt,ind,label,d,dlen)
/*
InhibitAnyPolicy ::= SkipCerts
SkipCerts ::= INTEGER (0..MAX)
*/
#define x509_inhibit_any_policy_to_der(val,out,outlen) asn1_int_to_der(val,out,outlen)
#define x509_inhibit_any_policy_from_der(val,in,inlen) asn1_int_from_der(val,in,inlen)
/*
FreshestCRL ::= CRLDistributionPoints
*/
#define x509_freshest_crl_to_der(d,dlen,out,outlen) x509_crl_distribution_points_to_der(d,dlen,out,outlen)
#define x509_freshest_crl_from_der(d,dlen,in,inlen) x509_crl_distribution_points_from_der(d,dlen,in,inlen)
#define x509_freshest_crl_print(fp,fmt,ind,label,d,dlen) x509_crl_distribution_points_print(fp,fmt,ind,label,d,dlen)
/*
Netscape-Defined Certificate Extensions
https://docs.oracle.com/cd/E19957-01/816-5533-10/ext.htm#1023061
NetscapeCertType ::= BIT STRING
bit 0: SSL Client certificate
bit 1: SSL Server certificate
bit 2: S/MIME certificate
bit 3: Object-signing certificate
bit 4: Reserved for future use
bit 5: SSL CA certificate
bit 6: S/MIME CA certificate
bit 7: Object-signing CA certificate
NetscapeCertComment ::= IA5String
*/
int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label, int bits);
int x509_exts_check(const uint8_t *exts, size_t extslen, int cert_type,
int *path_len_constraints);
/*
AuthorityInfoAccessSyntax ::= SEQUENCE OF AccessDescription
AccessDescription ::= SEQUENCE {
accessMethod OBJECT IDENTIFIER,
accessLocation GeneralName }
accessMethods:
OID_ad_ca_issuers
OID_ad_ocsp
*/
const char *x509_access_method_name(int oid);
int x509_access_method_from_name(const char *name);
int x509_access_method_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_access_method_from_der(int *oid, const uint8_t **in, size_t *inlen);
int x509_access_description_to_der(int oid, const char *uri, size_t urilen, uint8_t **out, size_t *outlen);
int x509_access_description_from_der(int *oid, const char **uri, size_t *urilen, const uint8_t **in, size_t *inlen);
int x509_access_description_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_authority_info_access_to_der(
const char *ca_issuers_uri, size_t ca_issuers_urilen,
const char *ocsp_uri, size_t ocsp_urilen,
uint8_t **out, size_t *outlen);
int x509_authority_info_access_from_der(
const char **ca_issuers_uri, size_t *ca_issuers_urilen,
const char **ocsp_uri, size_t *ocsp_urilen,
const uint8_t **in, size_t *inlen);
int x509_authority_info_access_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_X509_REQ_H
#define GMSSL_X509_REQ_H
#include <time.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm2.h>
#include <gmssl/oid.h>
#include <gmssl/asn1.h>
#include <gmssl/x509.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
from RFC 2986
CertificationRequestInfo ::= SEQUENCE {
version INTEGER { v1(0) },
subject Name,
subjectPKInfo SubjectPublicKeyInfo,
attributes [0] IMPLICIT SET OF Attribute }
*/
int x509_request_info_to_der(int version, const uint8_t *subject, size_t subject_len,
const SM2_KEY *subject_public_key, const uint8_t *attrs, size_t attrs_len,
uint8_t **out, size_t *outlen);
int x509_request_info_from_der(int *version, const uint8_t **subject, size_t *subject_len,
SM2_KEY *subject_public_key, const uint8_t **attrs, size_t *attrs_len,
const uint8_t **in, size_t *inlen);
int x509_request_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
CertificationRequest ::= SEQUENCE {
certificationRequestInfo CertificationRequestInfo,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING }
*/
int x509_req_sign_to_der(
int version,
const uint8_t *subject, size_t subject_len,
const SM2_KEY *subject_public_key,
const uint8_t *attrs, size_t attrs_len,
int signature_algor,
const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len,
uint8_t **out, size_t *outlen);
int x509_req_verify(const uint8_t *req, size_t reqlen,
const char *signer_id, size_t signer_id_len);
int x509_req_get_details(const uint8_t *req, size_t reqlen,
int *verison,
const uint8_t **subject, size_t *subject_len,
SM2_KEY *subject_public_key,
const uint8_t **attributes, size_t *attributes_len,
int *signature_algor,
const uint8_t **signature, size_t *signature_len);
int x509_req_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen);
int x509_req_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen);
int x509_req_to_pem(const uint8_t *req, size_t reqlen, FILE *fp);
int x509_req_from_pem(uint8_t *req, size_t *reqlen, size_t maxlen, FILE *fp);
int x509_req_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *req, size_t reqlen);
int x509_req_new_from_pem(uint8_t **req, size_t *reqlen, FILE *fp);
int x509_req_new_from_file(uint8_t **req, size_t *reqlen, const char *file);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,147 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_ZUC_H
#define GMSSL_ZUC_H
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
ZUC Public API
ZUC_KEY_SIZE
ZUC_IV_SIZE
ZUC_MAC_SIZE
ZUC_CTX
zuc_encrypt_init
zuc_encrypt_update
zuc_encrypt_finish
zuc_decrypt_init
zuc_decrypt_update
zuc_decrypt_finish
ZUC_MAC_CTX
zuc_mac_init
zuc_mac_update
zuc_mac_finish
zuc_eea_encrypt
zuc_eia_generate_mac
*/
# define ZUC_KEY_SIZE 16
# define ZUC_IV_SIZE 16
# define ZUC_MAC_SIZE 4
typedef uint32_t ZUC_BIT;
typedef uint32_t ZUC_UINT5;
typedef uint8_t ZUC_UINT6;
typedef uint32_t ZUC_UINT15;
typedef uint32_t ZUC_UINT31;
typedef uint32_t ZUC_UINT32;
typedef struct {
ZUC_UINT31 LFSR[16];
ZUC_UINT32 R1;
ZUC_UINT32 R2;
} ZUC_STATE;
void zuc_init(ZUC_STATE *state, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]);
void zuc_generate_keystream(ZUC_STATE *state, size_t nwords, ZUC_UINT32 *words);
ZUC_UINT32 zuc_generate_keyword(ZUC_STATE *state);
void zuc_encrypt(ZUC_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out);
typedef struct ZUC_MAC_CTX_st {
ZUC_UINT31 LFSR[16];
ZUC_UINT32 R1;
ZUC_UINT32 R2;
ZUC_UINT32 T;
ZUC_UINT32 K0;
uint8_t buf[4];
size_t buflen;
} ZUC_MAC_CTX;
void zuc_mac_init(ZUC_MAC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]);
void zuc_mac_update(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t len);
void zuc_mac_finish(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[ZUC_MAC_SIZE]);
#define ZUC_EEA_ENCRYPT_NWORDS(nbits) ((nbits + 31)/32)
#define ZUC_EEA_ENCRYPT_NBYTES(nbits) (ZUC_EEA_ENCRYPT_NWORDS(nbits)*4)
void zuc_eea_encrypt(const ZUC_UINT32 *in, ZUC_UINT32 *out, size_t nbits,
const uint8_t key[ZUC_KEY_SIZE], ZUC_UINT32 count, ZUC_UINT5 bearer,
ZUC_BIT direction);
ZUC_UINT32 zuc_eia_generate_mac(const ZUC_UINT32 *data, size_t nbits,
const uint8_t key[ZUC_KEY_SIZE], ZUC_UINT32 count, ZUC_UINT5 bearer,
ZUC_BIT direction);
# define ZUC256_KEY_SIZE 32
# define ZUC256_IV_SIZE 23
# define ZUC256_MAC32_SIZE 4
# define ZUC256_MAC64_SIZE 8
# define ZUC256_MAC128_SIZE 16
# define ZUC256_MIN_MAC_SIZE ZUC256_MAC32_SIZE
# define ZUC256_MAX_MAC_SIZE ZUC256_MAC128_SIZE
typedef ZUC_STATE ZUC256_STATE;
void zuc256_init(ZUC256_STATE *state, const uint8_t key[ZUC256_KEY_SIZE], const uint8_t iv[ZUC256_IV_SIZE]);
#define zuc256_generate_keystream(state,nwords,words) zuc_generate_keystream(state,nwords,words)
#define zuc256_generate_keyword(state) zuc_generate_keyword(state)
typedef struct ZUC256_MAC_CTX_st {
ZUC_UINT31 LFSR[16];
ZUC_UINT32 R1;
ZUC_UINT32 R2;
ZUC_UINT32 T[4];
ZUC_UINT32 K0[4];
uint8_t buf[4];
size_t buflen;
int macbits;
} ZUC256_MAC_CTX;
void zuc256_mac_init(ZUC256_MAC_CTX *ctx, const uint8_t key[ZUC256_KEY_SIZE],
const uint8_t iv[ZUC256_IV_SIZE], int macbits);
void zuc256_mac_update(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t len);
void zuc256_mac_finish(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[ZUC_MAC_SIZE]);
// Public API
typedef struct {
ZUC_STATE zuc_state;
uint8_t block[4];
size_t block_nbytes;
} ZUC_CTX;
int zuc_encrypt_init(ZUC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]);
int zuc_encrypt_update(ZUC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int zuc_encrypt_finish(ZUC_CTX *ctx, uint8_t *out, size_t *outlen);
#define zuc_decrypt_init(ctx,key,iv) zuc_encrypt_init(ctx,key,iv)
#define zuc_decrypt_update(ctx,in,inlen,out,outlen) zuc_encrypt_update(ctx,in,inlen,out,outlen)
#define zuc_decrypt_finish(ctx,out,outlen) zuc_encrypt_finish(ctx,out,outlen)
#ifdef __cplusplus
}
#endif
#endif

BIN
thirdparty/GmSSL-3.1.1/lib/gmssl.lib vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,63 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_OPENXLSX_HPP
#define OPENXLSX_OPENXLSX_HPP
#include "headers/XLCell.hpp"
#include "headers/XLCellRange.hpp"
#include "headers/XLCellReference.hpp"
#include "headers/XLCellValue.hpp"
#include "headers/XLColumn.hpp"
#include "headers/XLDateTime.hpp"
#include "headers/XLDocument.hpp"
#include "headers/XLException.hpp"
#include "headers/XLFormula.hpp"
#include "headers/XLRow.hpp"
#include "headers/XLSheet.hpp"
#include "headers/XLWorkbook.hpp"
#include "headers/XLZipArchive.hpp"
#endif // OPENXLSX_OPENXLSX_HPP

View File

@@ -0,0 +1,345 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2022, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_IZIPARCHIVE_HPP
#define OPENXLSX_IZIPARCHIVE_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include <memory>
#include <string>
namespace OpenXLSX
{
/**
* @brief This class functions as a wrapper around any class that provides the necessary functionality for
* a zip archive.
* @details This class works by applying 'type erasure'. This enables the use of objects of any class, the only
* requirement being that it provides the right interface. No inheritance from a base class is needed.
*/
class OPENXLSX_EXPORT IZipArchive
{
public:
/**
* @brief Default constructor
*/
IZipArchive() : m_zipArchive() {} // NOLINT
/**
* @brief Constructor, taking the target object as an argument.
* @tparam T The type of the target object (will be auto deducted)
* @param x The target object
* @note This method is deliberately not marked 'explicit', because as a templated constructor, it should be able
* to take any type as an argument. However, only objects that satisfy the required interface can be used.
*/
template<typename T>
IZipArchive(const T& zipArchive) : m_zipArchive { std::make_unique<Model<T>>(zipArchive) } {} // NOLINT
/**
* @brief Copy constructor
* @param other
*/
IZipArchive(const IZipArchive& other) : m_zipArchive(other.m_zipArchive ? other.m_zipArchive->clone() : nullptr) {}
/**
* @brief Move constructor
* @param other
*/
IZipArchive(IZipArchive&& other) noexcept = default;
/**
* @brief Destructor
*/
~IZipArchive() = default;
/**
* @brief
* @tparam T
* @param x
* @return
*/
template<typename T>
inline IZipArchive& operator=(const T& zipArchive)
{
m_zipArchive = std::make_unique<Model<T>>(zipArchive);
return *this;
}
/**
* @brief
* @param other
* @return
*/
inline IZipArchive& operator=(const IZipArchive& other)
{
IZipArchive copy(other);
*this = std::move(copy);
return *this;
}
/**
* @brief
* @param other
* @return
*/
inline IZipArchive& operator=(IZipArchive&& other) noexcept = default;
/**
* @brief
* @return
*/
inline explicit operator bool() const
{
return isValid();
}
inline bool isValid() const {
return m_zipArchive->isValid();
}
inline bool isOpen() const {
return m_zipArchive->isOpen();
}
inline void open(const std::string& fileName) {
m_zipArchive->open(fileName);
}
inline void close() const {
m_zipArchive->close();
}
inline void save(const std::string& path) {
m_zipArchive->save(path);
}
inline void addEntry(const std::string& name, const std::string& data) {
m_zipArchive->addEntry(name, data);
}
inline void deleteEntry(const std::string& entryName) {
m_zipArchive->deleteEntry(entryName);
}
inline std::string getEntry(const std::string& name) {
return m_zipArchive->getEntry(name);
}
inline bool hasEntry(const std::string& entryName) {
return m_zipArchive->hasEntry(entryName);
}
private:
/**
* @brief
*/
struct Concept
{
public:
/**
* @brief
*/
Concept() = default;
/**
* @brief
*/
Concept(const Concept&) = default;
/**
* @brief
*/
Concept(Concept&&) noexcept = default;
/**
* @brief
*/
virtual ~Concept() = default;
/**
* @brief
* @return
*/
inline Concept& operator=(const Concept&) = default;
/**
* @brief
* @return
*/
inline Concept& operator=(Concept&&) noexcept = default;
/**
* @brief
* @return
*/
inline virtual std::unique_ptr<Concept> clone() const = 0;
inline virtual bool isValid() const = 0;
inline virtual bool isOpen() const = 0;
inline virtual void open(const std::string& fileName) = 0;
inline virtual void close() = 0;
inline virtual void save (const std::string& path) = 0;
inline virtual void addEntry(const std::string& name, const std::string& data) = 0;
inline virtual void deleteEntry(const std::string& entryName) = 0;
inline virtual std::string getEntry(const std::string& name) = 0;
inline virtual bool hasEntry(const std::string& entryName) = 0;
};
/**
* @brief
* @tparam T
*/
template<typename T>
struct Model : Concept
{
public:
/**
* @brief
* @param x
*/
explicit Model(const T& x) : ZipType(x) {}
/**
* @brief
* @param other
*/
Model(const Model& other) = default;
/**
* @brief
* @param other
*/
Model(Model&& other) noexcept = default;
/**
* @brief
*/
~Model() override = default;
/**
* @brief
* @param other
* @return
*/
inline Model& operator=(const Model& other) = default;
/**
* @brief
* @param other
* @return
*/
inline Model& operator=(Model&& other) noexcept = default;
/**
* @brief
* @return
*/
inline std::unique_ptr<Concept> clone() const override
{
return std::make_unique<Model<T>>(ZipType);
}
inline bool isValid() const override {
return ZipType.isValid();
}
inline bool isOpen() const override {
return ZipType.isOpen();
}
inline void open(const std::string& fileName) override {
ZipType.open(fileName);
}
inline void close() override {
ZipType.close();
}
inline void save(const std::string& path) override {
ZipType.save(path);
}
inline void addEntry(const std::string& name, const std::string& data) override {
ZipType.addEntry(name, data);
}
inline void deleteEntry(const std::string& entryName) override {
ZipType.deleteEntry(entryName);
}
inline std::string getEntry(const std::string& name) override {
return ZipType.getEntry(name);
}
inline bool hasEntry(const std::string& entryName) override {
return ZipType.hasEntry(entryName);
}
private:
T ZipType;
};
std::unique_ptr<Concept> m_zipArchive;
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_IZIPARCHIVE_HPP

View File

@@ -0,0 +1,43 @@
#ifndef OPENXLSX_EXPORT_H
#define OPENXLSX_EXPORT_H
#ifdef OPENXLSX_STATIC_DEFINE
# define OPENXLSX_EXPORT
# define OPENXLSX_HIDDEN
#else
# ifndef OPENXLSX_EXPORT
# ifdef OpenXLSX_EXPORTS
/* We are building this library */
# define OPENXLSX_EXPORT
# else
/* We are using this library */
# define OPENXLSX_EXPORT
# endif
# endif
# ifndef OPENXLSX_HIDDEN
# define OPENXLSX_HIDDEN
# endif
#endif
#ifndef OPENXLSX_DEPRECATED
# define OPENXLSX_DEPRECATED __declspec(deprecated)
#endif
#ifndef OPENXLSX_DEPRECATED_EXPORT
# define OPENXLSX_DEPRECATED_EXPORT OPENXLSX_EXPORT OPENXLSX_DEPRECATED
#endif
#ifndef OPENXLSX_DEPRECATED_NO_EXPORT
# define OPENXLSX_DEPRECATED_NO_EXPORT OPENXLSX_HIDDEN OPENXLSX_DEPRECATED
#endif
/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef OPENXLSX_NO_DEPRECATED
# define OPENXLSX_NO_DEPRECATED
# endif
#endif
#endif /* OPENXLSX_EXPORT_H */

View File

@@ -0,0 +1,231 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLCELL_HPP
#define OPENXLSX_XLCELL_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
#include <memory>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLCellReference.hpp"
#include "XLCellValue.hpp"
#include "XLFormula.hpp"
#include "XLSharedStrings.hpp"
// ========== CLASS AND ENUM TYPE DEFINITIONS ========== //
namespace OpenXLSX
{
class XLCellRange;
class XLSharedStrings;
/**
* @brief An implementation class encapsulating the properties and behaviours of a spreadsheet cell.
*/
class OPENXLSX_EXPORT XLCell
{
friend class XLCellIterator;
friend class XLCellValueProxy;
friend class XLRowDataIterator;
friend bool operator==(const XLCell& lhs, const XLCell& rhs);
friend bool operator!=(const XLCell& lhs, const XLCell& rhs);
public:
//---------- Public Member Functions ----------//
/**
* @brief Default constructor. Constructs a null object.
*/
XLCell();
/**
* @brief
* @param cellNode
* @param sharedStrings
*/
XLCell(const XMLNode& cellNode, const XLSharedStrings& sharedStrings);
/**
* @brief Copy constructor
* @param other The XLCell object to be copied.
* @note The copy constructor has been deleted, as it makes no sense to copy a cell. If the objective is to
* copy the getValue, create the the target object and then use the copy assignment operator.
*/
XLCell(const XLCell& other);
/**
* @brief Move constructor
* @param other The XLCell object to be moved
* @note The move constructor has been deleted, as it makes no sense to move a cell.
*/
XLCell(XLCell&& other) noexcept;
/**
* @brief Destructor
* @note Using the default destructor
*/
~XLCell();
/**
* @brief Copy assignment operator
* @param other The XLCell object to be copy assigned
* @return A reference to the new object
* @note Copies only the cell contents, not the pointer to parent worksheet etc.
*/
XLCell& operator=(const XLCell& other);
/**
* @brief Move assignment operator [deleted]
* @param other The XLCell object to be move assigned
* @return A reference to the new object
* @note The move assignment constructor has been deleted, as it makes no sense to move a cell.
*/
XLCell& operator=(XLCell&& other) noexcept;
/**
* @brief
* @return
*/
explicit operator bool() const;
/**
* @brief
* @return
*/
XLCellValueProxy& value();
/**
* @brief
* @return
*/
const XLCellValueProxy& value() const;
/**
* @brief get the XLCellReference object for the cell.
* @return A reference to the cells' XLCellReference object.
*/
XLCellReference cellReference() const;
/**
* @brief get the XLCell object from the current cell offset
* @return A reference to the XLCell object.
*/
XLCell offset(uint16_t rowOffset, uint16_t colOffset) const;
/**
* @brief
* @return
*/
bool hasFormula() const;
/**
* @brief
* @return
*/
XLFormulaProxy& formula();
/**
* @brief
* @return
*/
const XLFormulaProxy& formula() const;
/**
* @brief
* @param newFormula
*/
private:
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
static bool isEqual(const XLCell& lhs, const XLCell& rhs);
//---------- Private Member Variables ---------- //
std::unique_ptr<XMLNode> m_cellNode; /**< A pointer to the root XMLNode for the cell. */
XLSharedStrings m_sharedStrings; /**< */
XLCellValueProxy m_valueProxy; /**< */
XLFormulaProxy m_formulaProxy; /**< */
};
} // namespace OpenXLSX
// ========== FRIEND FUNCTION IMPLEMENTATIONS ========== //
namespace OpenXLSX
{
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator==(const XLCell& lhs, const XLCell& rhs)
{
return XLCell::isEqual(lhs, rhs);
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator!=(const XLCell& lhs, const XLCell& rhs)
{
return !XLCell::isEqual(lhs, rhs);
}
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLCELL_HPP

View File

@@ -0,0 +1,179 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLCELLITERATOR_HPP
#define OPENXLSX_XLCELLITERATOR_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
#include <algorithm>
#include "OpenXLSX-Exports.hpp"
#include "XLCell.hpp"
#include "XLCellReference.hpp"
#include "XLIterator.hpp"
#include "XLXmlParser.hpp"
namespace OpenXLSX
{
class OPENXLSX_EXPORT XLCellIterator
{
public:
using iterator_category = std::forward_iterator_tag;
using value_type = XLCell;
using difference_type = int64_t;
using pointer = XLCell*;
using reference = XLCell&;
/**
* @brief
* @param cellRange
* @param loc
*/
explicit XLCellIterator(const XLCellRange& cellRange, XLIteratorLocation loc);
/**
* @brief
*/
~XLCellIterator();
/**
* @brief
* @param other
*/
XLCellIterator(const XLCellIterator& other);
/**
* @brief
* @param other
*/
[[maybe_unused]] XLCellIterator(XLCellIterator&& other) noexcept;
/**
* @brief
* @param other
* @return
*/
XLCellIterator& operator=(const XLCellIterator& other);
/**
* @brief
* @param other
* @return
*/
XLCellIterator& operator=(XLCellIterator&& other) noexcept;
/**
* @brief
* @return
*/
XLCellIterator& operator++();
/**
* @brief
* @return
*/
XLCellIterator operator++(int); // NOLINT
/**
* @brief
* @return
*/
reference operator*();
/**
* @brief
* @return
*/
pointer operator->();
/**
* @brief
* @param rhs
* @return
*/
bool operator==(const XLCellIterator& rhs) const;
/**
* @brief
* @param rhs
* @return
*/
bool operator!=(const XLCellIterator& rhs) const;
/**
* @brief
* @param last
* @return
*/
uint64_t distance(const XLCellIterator& last);
private:
std::unique_ptr<XMLNode> m_dataNode; /**< */
XLCellReference m_topLeft; /**< The cell reference of the first cell in the range */
XLCellReference m_bottomRight; /**< The cell reference of the last cell in the range */
XLCell m_currentCell; /**< */
XLSharedStrings m_sharedStrings; /**< */
bool m_endReached { false }; /**< */
};
} // namespace OpenXLSX
// ===== Template specialization for std::distance.
namespace std // NOLINT
{
using OpenXLSX::XLCellIterator;
template<>
inline typename std::iterator_traits<XLCellIterator>::difference_type distance<XLCellIterator>(XLCellIterator first,
XLCellIterator last)
{
return static_cast<typename std::iterator_traits<XLCellIterator>::difference_type>(first.distance(last));
}
} // namespace std
#pragma warning(pop)
#endif // OPENXLSX_XLCELLITERATOR_HPP

View File

@@ -0,0 +1,169 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLCELLRANGE_HPP
#define OPENXLSX_XLCELLRANGE_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <memory>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLCell.hpp"
#include "XLCellIterator.hpp"
#include "XLCellReference.hpp"
#include "XLXmlParser.hpp"
namespace OpenXLSX
{
/**
* @brief This class encapsulates the concept of a cell range, i.e. a square area
* (or subset) of cells in a spreadsheet.
*/
class OPENXLSX_EXPORT XLCellRange
{
friend class XLCellIterator;
//----------------------------------------------------------------------------------------------------------------------
// Public Member Functions
//----------------------------------------------------------------------------------------------------------------------
public:
/**
* @brief
* @param dataNode
* @param topLeft
* @param bottomRight
* @param sharedStrings
*/
explicit XLCellRange(const XMLNode& dataNode,
const XLCellReference& topLeft,
const XLCellReference& bottomRight,
const XLSharedStrings& sharedStrings);
/**
* @brief Copy constructor [default].
* @param other The range object to be copied.
* @note This implements the default copy constructor, i.e. memberwise copying.
*/
XLCellRange(const XLCellRange& other);
/**
* @brief Move constructor [default].
* @param other The range object to be moved.
* @note This implements the default move constructor, i.e. memberwise move.
*/
XLCellRange(XLCellRange&& other) noexcept;
/**
* @brief Destructor [default]
* @note This implements the default destructor.
*/
~XLCellRange();
/**
* @brief The copy assignment operator [default]
* @param other The range object to be copied and assigned.
* @return A reference to the new object.
* @throws A std::range_error if the source range and destination range are of different size and shape.
* @note This implements the default copy assignment operator.
*/
XLCellRange& operator=(const XLCellRange& other);
/**
* @brief The move assignment operator [default].
* @param other The range object to be moved and assigned.
* @return A reference to the new object.
* @note This implements the default move assignment operator.
*/
XLCellRange& operator=(XLCellRange&& other) noexcept;
/**
* @brief Get the number of rows in the range.
* @return The number of rows.
*/
uint32_t numRows() const;
/**
* @brief Get the number of columns in the range.
* @return The number of columns.
*/
uint16_t numColumns() const;
/**
* @brief
* @return
*/
XLCellIterator begin() const;
/**
* @brief
* @return
*/
XLCellIterator end() const;
/**
* @brief
*/
void clear();
//----------------------------------------------------------------------------------------------------------------------
// Private Member Variables
//----------------------------------------------------------------------------------------------------------------------
private:
std::unique_ptr<XMLNode> m_dataNode; /**< */
XLCellReference m_topLeft; /**< The cell reference of the first cell in the range */
XLCellReference m_bottomRight; /**< The cell reference of the last cell in the range */
XLSharedStrings m_sharedStrings;
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLCELLRANGE_HPP

View File

@@ -0,0 +1,323 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLCELLREFERENCE_HPP
#define OPENXLSX_XLCELLREFERENCE_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <string>
#include <utility>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
namespace OpenXLSX
{
/**
* @brief
*/
using XLCoordinates = std::pair<uint32_t, uint16_t>;
/**
* @brief
*/
class OPENXLSX_EXPORT XLCellReference final
{
friend bool operator==(const XLCellReference& lhs, const XLCellReference& rhs);
friend bool operator!=(const XLCellReference& lhs, const XLCellReference& rhs);
friend bool operator<(const XLCellReference& lhs, const XLCellReference& rhs);
friend bool operator>(const XLCellReference& lhs, const XLCellReference& rhs);
friend bool operator<=(const XLCellReference& lhs, const XLCellReference& rhs);
friend bool operator>=(const XLCellReference& lhs, const XLCellReference& rhs);
//----------------------------------------------------------------------------------------------------------------------
// Public Member Functions
//----------------------------------------------------------------------------------------------------------------------
public:
/**
* @brief Constructor taking a cell address as argument.
* @param cellAddress The address of the cell, e.g. 'A1'.
* @details The constructor creates a new XLCellReference from a string, e.g. 'A1'. If there's no input,
* the default reference will be cell A1.
*/
XLCellReference(const std::string& cellAddress = ""); // NOLINT
/**
* @brief Constructor taking the cell coordinates as arguments.
* @param row The row number of the cell.
* @param column The column number of the cell.
*/
XLCellReference(uint32_t row, uint16_t column);
/**
* @brief Constructor taking the row number and the column letter as arguments.
* @param row The row number of the cell.
* @param column The column letter of the cell.
*/
XLCellReference(uint32_t row, const std::string& column);
/**
* @brief Copy constructor
* @param other The object to be copied.
*/
XLCellReference(const XLCellReference& other);
/**
* @brief
* @param other
*/
XLCellReference(XLCellReference&& other) noexcept;
/**
* @brief Destructor. Default implementation used.
*/
~XLCellReference();
/**
* @brief Assignment operator.
* @param other The object to be copied/assigned.
* @return A reference to the new object.
*/
XLCellReference& operator=(const XLCellReference& other);
/**
* @brief
* @param other
* @return
*/
XLCellReference& operator=(XLCellReference&& other) noexcept;
/**
* @brief
* @return
*/
XLCellReference& operator++();
/**
* @brief
* @return
*/
XLCellReference operator++(int); // NOLINT
/**
* @brief
* @return
*/
XLCellReference& operator--();
/**
* @brief
* @return
*/
XLCellReference operator--(int); // NOLINT
/**
* @brief Get the row number of the XLCellReference.
* @return The row.
*/
uint32_t row() const;
/**
* @brief Set the row number for the XLCellReference.
* @param row The row number.
*/
void setRow(uint32_t row);
/**
* @brief Get the column number of the XLCellReference.
* @return The column number.
*/
uint16_t column() const;
/**
* @brief Set the column number of the XLCellReference.
* @param column The column number.
*/
void setColumn(uint16_t column);
/**
* @brief Set both row and column number of the XLCellReference.
* @param row The row number.
* @param column The column number.
*/
void setRowAndColumn(uint32_t row, uint16_t column);
/**
* @brief Get the address of the XLCellReference
* @return The address, e.g. 'A1'
*/
std::string address() const;
/**
* @brief Set the address of the XLCellReference
* @param address The address, e.g. 'A1'
* @pre The address input string must be a valid Excel cell reference. Otherwise the behaviour is undefined.
*/
void setAddress(const std::string& address);
//----------------------------------------------------------------------------------------------------------------------
// Private Member Functions
//----------------------------------------------------------------------------------------------------------------------
// private:
/**
* @brief
* @param row
* @return
*/
static std::string rowAsString(uint32_t row);
/**
* @brief
* @param row
* @return
*/
static uint32_t rowAsNumber(const std::string& row);
/**
* @brief Static helper function to convert column number to column letter (e.g. column 1 becomes 'A')
* @param column The column number.
* @return The column letter
*/
static std::string columnAsString(uint16_t column);
/**
* @brief Static helper function to convert column letter to column number (e.g. column 'A' becomes 1)
* @param column The column letter, e.g. 'A'
* @return The column number.
*/
static uint16_t columnAsNumber(const std::string& column);
/**
* @brief Static helper function to convert cell address to coordinates.
* @param address The address to be converted, e.g. 'A1'
* @return A std::pair<row, column>
*/
static XLCoordinates coordinatesFromAddress(const std::string& address);
//----------------------------------------------------------------------------------------------------------------------
// Private Member Variables
//----------------------------------------------------------------------------------------------------------------------
private:
uint32_t m_row { 1 }; /**< The row */
uint16_t m_column { 1 }; /**< The column */
std::string m_cellAddress {"A1"}; /**< The address, e.g. 'A1' */
};
/**
* @brief Helper function to check equality between two XLCellReferences.
* @param lhs The first XLCellReference
* @param rhs The second XLCellReference
* @return true if equal; otherwise false.
*/
inline bool operator==(const XLCellReference& lhs, const XLCellReference& rhs)
{
return lhs.row() == rhs.row() && lhs.column() == rhs.column();
}
/**
* @brief Helper function to check for in-equality between two XLCellReferences
* @param lhs The first XLCellReference
* @param rhs The second XLCellReference
* @return false if equal; otherwise true.
*/
inline bool operator!=(const XLCellReference& lhs, const XLCellReference& rhs)
{
return !(lhs == rhs);
}
/**
* @brief Helper function to check if one XLCellReference is smaller than another.
* @param lhs The first XLCellReference
* @param rhs The second XLCellReference
* @return true if lhs < rhs; otherwise false.
*/
inline bool operator<(const XLCellReference& lhs, const XLCellReference& rhs)
{
return lhs.row() < rhs.row() || (lhs.row() <= rhs.row() && lhs.column() < rhs.column());
}
/**
* @brief Helper function to check if one XLCellReference is larger than another.
* @param lhs The first XLCellReference
* @param rhs The second XLCellReference
* @return true if lhs > rhs; otherwise false.
*/
inline bool operator>(const XLCellReference& lhs, const XLCellReference& rhs)
{
return (rhs < lhs);
}
/**
* @brief Helper function to check if one XLCellReference is smaller than or equal to another.
* @param lhs The first XLCellReference
* @param rhs The second XLCellReference
* @return true if lhs <= rhs; otherwise false
*/
inline bool operator<=(const XLCellReference& lhs, const XLCellReference& rhs)
{
return !(lhs > rhs);
}
/**
* @brief Helper function to check if one XLCellReference is larger than or equal to another.
* @param lhs The first XLCellReference
* @param rhs The second XLCellReference
* @return true if lhs >= rhs; otherwise false.
*/
inline bool operator>=(const XLCellReference& lhs, const XLCellReference& rhs)
{
return !(lhs < rhs);
}
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLCELLREFERENCE_HPP

View File

@@ -0,0 +1,672 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLCELLVALUE_HPP
#define OPENXLSX_XLCELLVALUE_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <cmath>
#include <cstdint>
#include <iostream>
#include <string>
#include <variant>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLDateTime.hpp"
#include "XLException.hpp"
#include "XLXmlParser.hpp"
// ========== CLASS AND ENUM TYPE DEFINITIONS ========== //
namespace OpenXLSX
{
//---------- Forward Declarations ----------//
class XLCellValueProxy;
class XLCell;
/**
* @brief Enum defining the valid value types for a an Excel spreadsheet cell.
*/
enum class XLValueType { Empty, Boolean, Integer, Float, Error, String };
/**
* @brief Class encapsulating a cell value.
*/
class OPENXLSX_EXPORT XLCellValue
{
//---------- Friend Declarations ----------//
// TODO: Consider template functions to compare to ints, floats etc.
friend bool operator==(const XLCellValue& lhs, const XLCellValue& rhs);
friend bool operator!=(const XLCellValue& lhs, const XLCellValue& rhs);
friend bool operator<(const XLCellValue& lhs, const XLCellValue& rhs);
friend bool operator>(const XLCellValue& lhs, const XLCellValue& rhs);
friend bool operator<=(const XLCellValue& lhs, const XLCellValue& rhs);
friend bool operator>=(const XLCellValue& lhs, const XLCellValue& rhs);
friend std::ostream& operator<<(std::ostream& os, const XLCellValue& value);
friend std::hash<OpenXLSX::XLCellValue>;
public:
//---------- Public Member Functions ----------//
/**
* @brief Default constructor
*/
XLCellValue();
/**
* @brief A templated constructor. Any value convertible to a valid cell value can be used as argument.
* @tparam T The type of the argument (will be automatically deduced).
* @param value The value.
* @todo Consider changing the enable_if statement to check for objects with a .c_str() member function.
*/
template<
typename T,
typename std::enable_if<std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<std::decay_t<T>, std::string> ||
std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char*> ||
std::is_same_v<std::decay_t<T>, char*> || std::is_same_v<T, XLDateTime>>::type* = nullptr>
XLCellValue(T value) // NOLINT
{
// ===== If the argument is a bool, set the m_type attribute to Boolean.
if constexpr (std::is_integral_v<T> && std::is_same_v<T, bool>) {
m_type = XLValueType::Boolean;
m_value = value;
}
// ===== If the argument is an integral type, set the m_type attribute to Integer.
else if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>) {
m_type = XLValueType::Integer;
m_value = int64_t(value);
}
// ===== If the argument is a string type (i.e. is constructable from *char),
// ===== set the m_type attribute to String.
else if constexpr (std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> ||
std::is_same_v<std::decay_t<T>, const char*> ||
(std::is_same_v<std::decay_t<T>, char*> && !std::is_same_v<T, bool>))
{
m_type = XLValueType::String;
m_value = std::string(value);
}
// ===== If the argument is an XLDateTime, set the value to the date/time serial number.
else if constexpr (std::is_same_v<T, XLDateTime>) {
m_type = XLValueType::Float;
m_value = value.serial();
}
// ===== If the argument is a floating point type, set the m_type attribute to Float.
// ===== If not, a static_assert will result in compilation error.
else {
static_assert(std::is_floating_point_v<T>, "Invalid argument for constructing XLCellValue object");
if (std::isfinite(value)) {
m_type = XLValueType::Float;
m_value = double(value);
}
else {
m_type = XLValueType::Error;
m_value = std::string("#NUM!");
}
}
}
/**
* @brief Copy constructor.
* @param other The object to be copied.
*/
XLCellValue(const XLCellValue& other);
/**
* @brief Move constructor.
* @param other The object to be moved.
*/
XLCellValue(XLCellValue&& other) noexcept;
/**
* @brief Destructor
*/
~XLCellValue();
/**
* @brief Copy assignment operator.
* @param other Object to be copied.
* @return Reference to the copied-to object.
*/
XLCellValue& operator=(const XLCellValue& other);
/**
* @brief Move assignment operator.
* @param other Object to be moved.
* @return Reference to the moved-to object.
*/
XLCellValue& operator=(XLCellValue&& other) noexcept;
/**
* @brief Templated copy assignment operator.
* @tparam T The type of the value argument.
* @param value The value.
* @return A reference to the assigned-to object.
*/
template<
typename T,
typename std::enable_if<std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<std::decay_t<T>, std::string> ||
std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char*> ||
std::is_same_v<std::decay_t<T>, char*> || std::is_same_v<T, XLDateTime>>::type* = nullptr>
XLCellValue& operator=(T value)
{
// ===== Implemented using copy-and-swap.
XLCellValue temp(value);
std::swap(*this, temp);
return *this;
}
/**
* @brief Templated setter for integral and bool types.
* @tparam T The type of the value argument.
* @param numberValue The value
*/
template<
typename T,
typename std::enable_if<std::is_same_v<T, XLCellValue> || std::is_integral_v<T> || std::is_floating_point_v<T> ||
std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> ||
std::is_same_v<std::decay_t<T>, const char*> || std::is_same_v<std::decay_t<T>, char*> ||
std::is_same_v<T, XLDateTime>>::type* = nullptr>
void set(T numberValue)
{
// ===== Implemented using the assignment operator.
*this = numberValue;
}
/**
* @brief Templated getter.
* @tparam T The type of the value to be returned.
* @return The value as a type T object.
* @throws XLValueTypeError if the XLCellValue object does not contain a compatible type.
*/
template<
typename T,
typename std::enable_if<std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<std::decay_t<T>, std::string> ||
std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char*> ||
std::is_same_v<std::decay_t<T>, char*> || std::is_same_v<T, XLDateTime>>::type* = nullptr>
T get() const
{
try {
if constexpr (std::is_integral_v<T> && std::is_same_v<T, bool>) return std::get<bool>(m_value);
if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>) return static_cast<T>(std::get<int64_t>(m_value));
if constexpr (std::is_floating_point_v<T>) {
if (m_type == XLValueType::Error) return std::nan("1");
return static_cast<T>(std::get<double>(m_value));
}
if constexpr (std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> ||
std::is_same_v<std::decay_t<T>, const char*> ||
(std::is_same_v<std::decay_t<T>, char*> && !std::is_same_v<T, bool>))
return std::get<std::string>(m_value).c_str();
if constexpr (std::is_same_v<T, XLDateTime>) return XLDateTime(std::get<double>(m_value));
}
catch (const std::bad_variant_access& ) {
throw XLValueTypeError("XLCellValue object does not contain the requested type.");
}
}
/**
* @brief Explicit conversion operator for easy conversion to supported types.
* @tparam T The type to cast to.
* @return The XLCellValue object cast to requested type.
* @throws XLValueTypeError if the XLCellValue object does not contain a compatible type.
*/
template<
typename T,
typename std::enable_if<std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<std::decay_t<T>, std::string> ||
std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char*> ||
std::is_same_v<std::decay_t<T>, char*> || std::is_same_v<T, XLDateTime>>::type* = nullptr>
operator T() const
{
return this->get<T>();
}
/**
* @brief Clears the contents of the XLCellValue object.
* @return Returns a reference to the current object.
*/
XLCellValue& clear();
/**
* @brief Sets the value type to XLValueType::Error.
* @return Returns a reference to the current object.
*/
XLCellValue& setError(const std::string &error);
/**
* @brief Get the value type of the current object.
* @return An XLValueType for the current object.
*/
XLValueType type() const;
/**
* @brief Get the value type of the current object, as a string representation
* @return A std::string representation of the value type.
*/
std::string typeAsString() const;
private:
//---------- Private Member Variables ---------- //
std::variant<std::string, int64_t, double, bool> m_value { std::string("") }; /**< The value contained in the cell. */
XLValueType m_type { XLValueType::Empty }; /**< The value type of the cell. */
};
/**
* @brief The XLCellValueProxy class is used for proxy (or placeholder) objects for XLCellValue objects.
* @details The XLCellValueProxy class is used for proxy (or placeholder) objects for XLCellValue objects.
* The purpose is to enable implicit conversion during assignment operations. XLCellValueProxy objects
* can not be constructed manually by the user, only through XLCell objects.
*/
class OPENXLSX_EXPORT XLCellValueProxy
{
friend class XLCell;
friend class XLCellValue;
public:
//---------- Public Member Functions ----------//
/**
* @brief Destructor
*/
~XLCellValueProxy();
/**
* @brief Copy assignment operator.
* @param other XLCellValueProxy object to be copied.
* @return A reference to the current object.
*/
XLCellValueProxy& operator=(const XLCellValueProxy& other);
/**
* @brief Templated assignment operator
* @tparam T The type of numberValue assigned to the object.
* @param value The value.
* @return A reference to the current object.
*/
template<
typename T,
typename std::enable_if<std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<std::decay_t<T>, std::string> ||
std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char*> ||
std::is_same_v<std::decay_t<T>, char*> || std::is_same_v<T, XLCellValue> ||
std::is_same_v<T, XLDateTime>>::type* = nullptr>
XLCellValueProxy& operator=(T value)
{ // NOLINT
if constexpr (std::is_integral_v<T> && std::is_same_v<T, bool>) // if bool
setBoolean(value);
else if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>) // if integer
setInteger(value);
else if constexpr (std::is_floating_point_v<T>) // if floating point
setFloat(value);
else if constexpr (std::is_same_v<T, XLDateTime>)
setFloat(value.serial());
else if constexpr (std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> ||
std::is_same_v<std::decay_t<T>, const char*> ||
(std::is_same_v<std::decay_t<T>, char*> && !std::is_same_v<T, bool> && !std::is_same_v<T, XLCellValue>))
{
if constexpr (std::is_same_v<std::decay_t<T>, const char*> || std::is_same_v<std::decay_t<T>, char*>)
setString(value);
else if constexpr (std::is_same_v<std::decay_t<T>, std::string_view>)
setString(std::string(value).c_str());
else
setString(value.c_str());
}
if constexpr (std::is_same_v<T, XLCellValue>) {
switch (value.type()) {
case XLValueType::Boolean:
setBoolean(value.template get<bool>());
break;
case XLValueType::Integer:
setInteger(value.template get<int64_t>());
break;
case XLValueType::Float:
setFloat(value.template get<double>());
break;
case XLValueType::String:
setString(value.template get<const char*>());
break;
case XLValueType::Empty:
clear();
break;
default:
setError("#N/A");
break;
}
}
return *this;
}
/**
* @brief
* @tparam T
* @param value
*/
template<
typename T,
typename std::enable_if<std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<std::decay_t<T>, std::string> ||
std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char*> ||
std::is_same_v<std::decay_t<T>, char*> || std::is_same_v<T, XLCellValue> ||
std::is_same_v<T, XLDateTime>>::type* = nullptr>
void set(T value)
{
*this = value;
}
/**
* @brief
* @tparam T
* @return
* @todo Is an explicit conversion operator needed as well?
*/
template<
typename T,
typename std::enable_if<std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<std::decay_t<T>, std::string> ||
std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char*> ||
std::is_same_v<std::decay_t<T>, char*> || std::is_same_v<T, XLDateTime>>::type* = nullptr>
T get() const
{
return getValue().get<T>();
}
/**
* @brief Clear the contents of the cell.
* @return A reference to the current object.
*/
XLCellValueProxy& clear();
/**
* @brief Set the cell value to a error state.
* @return A reference to the current object.
*/
XLCellValueProxy& setError(const std::string & error);
/**
* @brief Get the value type for the cell.
* @return An XLCellValue corresponding to the cell value.
*/
XLValueType type() const;
/**
* @brief Get the value type of the current object, as a string representation
* @return A std::string representation of the value type.
*/
std::string typeAsString() const;
/**
* @brief Implicitly convert the XLCellValueProxy object to a XLCellValue object.
* @return An XLCellValue object, corresponding to the cell value.
*/
operator XLCellValue(); // NOLINT
/**
* @brief
* @tparam T
* @return
*/
template<
typename T,
typename std::enable_if<std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<std::decay_t<T>, std::string> ||
std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char*> ||
std::is_same_v<std::decay_t<T>, char*> || std::is_same_v<T, XLDateTime>>::type* = nullptr>
operator T() const
{
return getValue().get<T>();
}
private:
//---------- Private Member Functions ---------- //
/**
* @brief Constructor
* @param cell Pointer to the parent XLCell object.
* @param cellNode Pointer to the corresponding XMLNode object.
*/
XLCellValueProxy(XLCell* cell, XMLNode* cellNode);
/**
* @brief Copy constructor
* @param other Object to be copied.
*/
XLCellValueProxy(const XLCellValueProxy& other);
/**
* @brief Move constructor
* @param other Object to be moved.
*/
XLCellValueProxy(XLCellValueProxy&& other) noexcept;
/**
* @brief Move assignment operator
* @param other Object to be moved
* @return Reference to moved-to pbject.
*/
XLCellValueProxy& operator=(XLCellValueProxy&& other) noexcept;
/**
* @brief Set cell to an integer value.
* @param numberValue The value to be set.
*/
void setInteger(int64_t numberValue);
/**
* @brief Set the cell to a bool value.
* @param numberValue The value to be set.
*/
void setBoolean(bool numberValue);
/**
* @brief Set the cell to a floating point value.
* @param numberValue The value to be set.
*/
void setFloat(double numberValue);
/**
* @brief Set the cell to a string value.
* @param stringValue The value to be set.
*/
void setString(const char* stringValue);
/**
* @brief Get a copy of the XLCellValue object for the cell.
* @return An XLCellValue object.
*/
XLCellValue getValue() const;
//---------- Private Member Variables ---------- //
XLCell* m_cell; /**< Pointer to the owning XLCell object. */
XMLNode* m_cellNode; /**< Pointer to corresponding XML cell node. */
};
} // namespace OpenXLSX
// TODO: Consider comparison operators on fundamental datatypes
// ========== FRIEND FUNCTION IMPLEMENTATIONS ========== //
namespace OpenXLSX
{
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator==(const XLCellValue& lhs, const XLCellValue& rhs)
{
return lhs.m_value == rhs.m_value;
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator!=(const XLCellValue& lhs, const XLCellValue& rhs)
{
return lhs.m_value != rhs.m_value;
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator<(const XLCellValue& lhs, const XLCellValue& rhs)
{
return lhs.m_value < rhs.m_value;
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator>(const XLCellValue& lhs, const XLCellValue& rhs)
{
return lhs.m_value > rhs.m_value;
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator<=(const XLCellValue& lhs, const XLCellValue& rhs)
{
return lhs.m_value <= rhs.m_value;
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator>=(const XLCellValue& lhs, const XLCellValue& rhs)
{
return lhs.m_value >= rhs.m_value;
}
/**
* @brief
* @param os
* @param value
* @return
*/
inline std::ostream& operator<<(std::ostream& os, const XLCellValue& value)
{
switch (value.type()) {
case XLValueType::Empty:
return os << "";
case XLValueType::Boolean:
return os << value.get<bool>();
case XLValueType::Integer:
return os << value.get<int64_t>();
case XLValueType::Float:
return os << value.get<double>();
case XLValueType::String:
return os << value.get<std::string_view>();
default:
return os << "";
}
}
inline std::ostream& operator<<(std::ostream& os, const XLCellValueProxy& value)
{
switch (value.type()) {
case XLValueType::Empty:
return os << "";
case XLValueType::Boolean:
return os << value.get<bool>();
case XLValueType::Integer:
return os << value.get<int64_t>();
case XLValueType::Float:
return os << value.get<double>();
case XLValueType::String:
return os << value.get<std::string_view>();
default:
return os << "";
}
}
} // namespace OpenXLSX
namespace std
{
template<>
struct hash<OpenXLSX::XLCellValue> // NOLINT
{
std::size_t operator()(const OpenXLSX::XLCellValue& value) const noexcept
{
return std::hash<std::variant<std::string, int64_t, double, bool>> {}(value.m_value);
}
};
} // namespace std
#pragma warning(pop)
#endif // OPENXLSX_XLCELLVALUE_HPP

View File

@@ -0,0 +1,229 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLCOLOR_HPP
#define OPENXLSX_XLCOLOR_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <string>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
namespace OpenXLSX
{
/**
* @brief
*/
class OPENXLSX_EXPORT XLColor
{
//----------------------------------------------------------------------------------------------------------------------
// Public Member Functions
//----------------------------------------------------------------------------------------------------------------------
friend bool operator==(const XLColor& lhs, const XLColor& rhs);
friend bool operator!=(const XLColor& lhs, const XLColor& rhs);
public:
/**
* @brief
*/
XLColor();
/**
* @brief
* @param alpha
* @param red
* @param green
* @param blue
*/
XLColor(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue);
/**
* @brief
* @param red
* @param green
* @param blue
*/
XLColor(uint8_t red, uint8_t green, uint8_t blue);
/**
* @brief
* @param hexCode
*/
explicit XLColor(const std::string& hexCode);
/**
* @brief
* @param other
*/
XLColor(const XLColor& other);
/**
* @brief
* @param other
*/
XLColor(XLColor&& other) noexcept;
/**
* @brief
*/
~XLColor();
/**
* @brief
* @param other
* @return
*/
XLColor& operator=(const XLColor& other);
/**
* @brief
* @param other
* @return
*/
XLColor& operator=(XLColor&& other) noexcept;
/**
* @brief
* @param alpha
* @param red
* @param green
* @param blue
*/
void set(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue);
/**
* @brief
* @param red
* @param green
* @param blue
*/
void set(uint8_t red = 0, uint8_t green = 0, uint8_t blue = 0);
/**
* @brief
* @param hexCode
*/
void set(const std::string& hexCode);
/**
* @brief
* @return
*/
uint8_t alpha() const;
/**
* @brief
* @return
*/
uint8_t red() const;
/**
* @brief
* @return
*/
uint8_t green() const;
/**
* @brief
* @return
*/
uint8_t blue() const;
/**
* @brief
* @return
*/
std::string hex() const;
//----------------------------------------------------------------------------------------------------------------------
// Private Member Variables
//----------------------------------------------------------------------------------------------------------------------
private:
uint8_t m_alpha { 255 };
uint8_t m_red { 0 };
uint8_t m_green { 0 };
uint8_t m_blue { 0 };
};
} // namespace OpenXLSX
namespace OpenXLSX
{
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator==(const XLColor& lhs, const XLColor& rhs)
{
return lhs.alpha() == rhs.alpha() && lhs.red() == rhs.red() && lhs.green() == rhs.green() && lhs.blue() == rhs.blue();
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator!=(const XLColor& lhs, const XLColor& rhs)
{
return !(lhs == rhs);
}
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLCOLOR_HPP

View File

@@ -0,0 +1,139 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLCOLUMN_HPP
#define OPENXLSX_XLCOLUMN_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <memory>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLXmlParser.hpp"
namespace OpenXLSX
{
/**
* @brief
*/
class OPENXLSX_EXPORT XLColumn
{
public:
/**
* @brief Constructor
* @param columnNode A pointer to the XMLNode for the column.
*/
explicit XLColumn(const XMLNode& columnNode);
/**
* @brief Copy Constructor [deleted]
*/
XLColumn(const XLColumn& other);
/**
* @brief Move Constructor
* @note The move constructor has been explicitly deleted.
*/
XLColumn(XLColumn&& other) noexcept;
/**
* @brief Destructor
*/
~XLColumn();
/**
* @brief Copy assignment operator [deleted]
*/
XLColumn& operator=(const XLColumn& other);
/**
* @brief
* @param other
* @return
*/
XLColumn& operator=(XLColumn&& other) noexcept = default;
/**
* @brief Get the width of the column.
* @return The width of the column.
*/
float width() const;
/**
* @brief Set the width of the column
* @param width The width of the column
*/
void setWidth(float width);
/**
* @brief Is the column hidden?
* @return The state of the column.
*/
bool isHidden() const;
/**
* @brief Set the column to be shown or hidden.
* @param state The state of the column.
*/
void setHidden(bool state);
/**
* @brief Get the XMLNode object for the column.
* @return The XMLNode for the column
*/
XMLNode& columnNode() const;
private:
std::unique_ptr<XMLNode> m_columnNode; /**< A pointer to the XMLNode object for the column. */
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLCOLUMN_HPP

View File

@@ -0,0 +1,224 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLCOMMANDQUERY_HPP
#define OPENXLSX_XLCOMMANDQUERY_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <any>
#include <map>
#include <string>
#include <variant>
// ===== OpenXLSX Includes ===== //
#include "XLXmlData.hpp"
#include "XLSharedStrings.hpp"
namespace OpenXLSX
{
/**
* @brief
*/
enum class XLCommandType {
SetSheetName,
SetSheetColor,
SetSheetVisibility,
SetSheetIndex,
SetSheetActive,
ResetCalcChain,
AddSharedStrings,
AddWorksheet,
AddChartsheet,
DeleteSheet,
CloneSheet,
};
/**
* @brief
*/
class XLCommand
{
public:
/**
* @brief
* @param type
*/
explicit XLCommand(XLCommandType type) : m_type(type) {}
/**
* @brief
* @tparam T
* @param param
* @param value
* @return
*/
template<typename T>
XLCommand& setParam(const std::string& param, T value) {
m_params[param] = value;
return *this;
}
/**
* @brief
* @tparam T
* @param param
* @return
*/
template<typename T>
T getParam(const std::string& param) const {
return std::any_cast<T>(m_params.at(param));
}
/**
* @brief
* @return
*/
XLCommandType type() const {
return m_type;
}
private:
XLCommandType m_type; /*< */
std::map<std::string, std::any> m_params; /*< */
};
/**
* @brief
*/
enum class XLQueryType {
QuerySheetName,
QuerySheetIndex,
QuerySheetVisibility,
QuerySheetIsActive,
QuerySheetType,
QuerySheetID,
QuerySheetRelsID,
QuerySheetRelsTarget,
QuerySharedStrings,
QueryXmlData
};
/**
* @brief
*/
class XLQuery
{
public:
/**
* @brief
* @param type
*/
explicit XLQuery(XLQueryType type) : m_type(type) {}
/**
* @brief
* @tparam T
* @param param
* @param value
* @return
*/
template<typename T>
XLQuery& setParam(const std::string& param, T value) {
m_params[param] = value;
return *this;
}
/**
* @brief
* @tparam T
* @param param
* @return
*/
template<typename T>
T getParam(const std::string& param) const {
return std::any_cast<T>(m_params.at(param));
}
/**
* @brief
* @tparam T
* @param value
* @return
*/
template<typename T>
XLQuery& setResult(T value) {
m_result = value;
return *this;
}
/**
* @brief
* @tparam T
* @return
*/
template<typename T>
T result() const {
return std::any_cast<T>(m_result);
}
/**
* @brief
* @return
*/
XLQueryType type() const {
return m_type;
}
private:
XLQueryType m_type; /*< */
std::any m_result; /*< */
std::map<std::string, std::any> m_params; /*< */
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLCOMMANDQUERY_HPP

View File

@@ -0,0 +1,14 @@
//
// Created by Kenneth Balslev on 15/08/2021.
//
#ifndef OPENXLSX_XLCONSTANTS_HPP
#define OPENXLSX_XLCONSTANTS_HPP
namespace OpenXLSX
{
inline const uint16_t MAX_COLS = 16'384;
inline const uint32_t MAX_ROWS = 1'048'576;
} // namespace OpenXLSX
#endif // OPENXLSX_XLCONSTANTS_HPP

View File

@@ -0,0 +1,251 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLCONTENTTYPES_HPP
#define OPENXLSX_XLCONTENTTYPES_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <map>
#include <memory>
#include <string>
#include <vector>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLXmlFile.hpp"
#include "XLXmlParser.hpp"
namespace OpenXLSX
{
/**
* @brief
*/
enum class XLContentType {
Workbook,
WorkbookMacroEnabled,
Worksheet,
Chartsheet,
ExternalLink,
Theme,
Styles,
SharedStrings,
Drawing,
Chart,
ChartStyle,
ChartColorStyle,
ControlProperties,
CalculationChain,
VBAProject,
CoreProperties,
ExtendedProperties,
CustomProperties,
Comments,
Table,
VMLDrawing,
Unknown
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLContentItem
{
friend class XLContentTypes;
public: // ---------- Public Member Functions ---------- //
/**
* @brief
*/
XLContentItem();
/**
* @brief
* @param node
*/
explicit XLContentItem(const XMLNode& node);
/**
* @brief
*/
~XLContentItem();
/**
* @brief
* @param other
* @return
*/
XLContentItem(const XLContentItem& other);
/**
* @brief
* @param other
* @return
*/
XLContentItem(XLContentItem&& other) noexcept;
/**
* @brief
* @param other
* @return
*/
XLContentItem& operator=(const XLContentItem& other);
/**
* @brief
* @param other
* @return
*/
XLContentItem& operator=(XLContentItem&& other) noexcept;
/**
* @brief
* @return
*/
XLContentType type() const;
/**
* @brief
* @return
*/
std::string path() const;
private:
std::unique_ptr<XMLNode> m_contentNode; /**< */
};
// ================================================================================
// XLContentTypes Class
// ================================================================================
/**
* @brief The purpose of this class is to load, store add and save item in the [Content_Types].xml file.
*/
class OPENXLSX_EXPORT XLContentTypes : public XLXmlFile
{
public: // ---------- Public Member Functions ---------- //
/**
* @brief
*/
XLContentTypes();
/**
* @brief
* @param xmlData
*/
explicit XLContentTypes(XLXmlData* xmlData);
/**
* @brief Destructor
*/
~XLContentTypes();
/**
* @brief
* @param other
*/
XLContentTypes(const XLContentTypes& other);
/**
* @brief
* @param other
*/
XLContentTypes(XLContentTypes&& other) noexcept;
/**
* @brief
* @param other
* @return
*/
XLContentTypes& operator=(const XLContentTypes& other);
/**
* @brief
* @param other
* @return
*/
XLContentTypes& operator=(XLContentTypes&& other) noexcept;
/**
* @brief Add a new override key/getValue pair to the data store.
* @param path The key
* @param type The getValue
*/
void addOverride(const std::string& path, XLContentType type);
/**
* @brief
* @param path
*/
void deleteOverride(const std::string& path);
/**
* @brief
* @param item
*/
void deleteOverride(XLContentItem& item);
/**
* @brief
* @param path
* @return
*/
XLContentItem contentItem(const std::string& path);
/**
* @brief
* @return
*/
std::vector<XLContentItem> getContentItems();
// ---------- Protected Member Functions ---------- //
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLCONTENTTYPES_HPP

View File

@@ -0,0 +1,173 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLDATETIME_HPP
#define OPENXLSX_XLDATETIME_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <ctime>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLException.hpp"
// ========== CLASS AND ENUM TYPE DEFINITIONS ========== //
namespace OpenXLSX
{
class OPENXLSX_EXPORT XLDateTime
{
public:
/**
* @brief Constructor.
*/
XLDateTime();
/**
* @brief Constructor taking an Excel time point serial number as an argument.
* @param serial Excel time point serial number.
*/
explicit XLDateTime(double serial);
/**
* @brief Constructor taking a std::tm struct as an argument.
* @param timepoint A std::tm struct.
*/
explicit XLDateTime(const std::tm& timepoint);
/**
* @brief Constructor taking a unixtime format (seconds since 1/1/1970) as an argument.
* @param unixtime A time_t number.
*/
explicit XLDateTime(time_t unixtime);
/**
* @brief Copy constructor.
* @param other Object to be copied.
*/
XLDateTime(const XLDateTime& other);
/**
* @brief Move constructor.
* @param other Object to be moved.
*/
XLDateTime(XLDateTime&& other) noexcept;
/**
* @brief Destructor
*/
~XLDateTime();
/**
* @brief Copy assignment operator.
* @param other Object to be copied.
* @return Reference to the copied-to object.
*/
XLDateTime& operator=(const XLDateTime& other);
/**
* @brief Move assignment operator.
* @param other Object to be moved.
* @return Reference to the moved-to object.
*/
XLDateTime& operator=(XLDateTime&& other) noexcept;
/**
* @brief Assignment operator taking an Excel date/time serial number as an argument.
* @param serial A floating point value with the serial number.
* @return Reference to the copied-to object.
*/
XLDateTime& operator=(double serial);
/**
* @brief Assignment operator taking a std::tm object as an argument.
* @param timepoint std::tm object with the time point
* @return Reference to the copied-to object.
*/
XLDateTime& operator=(const std::tm& timepoint);
/**
* @brief Implicit conversion to Excel date/time serial number (any floating point type).
* @tparam T Type to convert to (any floating point type).
* @return Excel date/time serial number.
*/
template<typename T,
typename std::enable_if<std::is_floating_point_v<T> >::type* = nullptr>
operator T() const // NOLINT
{
return serial();
}
/**
* @brief Implicit conversion to std::tm object.
* @return std::tm object.
*/
operator std::tm() const; // NOLINT
/**
* @brief Get the date/time in the form of an Excel date/time serial number.
* @return A double with the serial number.
*/
double serial() const;
/**
* @brief Get the date/time in the form of a std::tm struct.
* @return A std::tm struct with the time point.
*/
std::tm tm() const;
private:
double m_serial {1.0}; /**< */
};
} // namespace OpenXLSX
#endif // OPENXLSX_XLDATETIME_HPP

View File

@@ -0,0 +1,320 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLDOCUMENT_HPP
#define OPENXLSX_XLDOCUMENT_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <algorithm>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <string>
// ===== OpenXLSX Includes ===== //
#include "IZipArchive.hpp"
#include "OpenXLSX-Exports.hpp"
#include "XLCommandQuery.hpp"
#include "XLContentTypes.hpp"
#include "XLException.hpp"
#include "XLProperties.hpp"
#include "XLRelationships.hpp"
#include "XLSharedStrings.hpp"
#include "XLWorkbook.hpp"
#include "XLXmlData.hpp"
#include "XLZipArchive.hpp"
namespace OpenXLSX
{
/**
* @brief The XLDocumentProperties class is an enumeration of the possible properties (metadata) that can be set
* for a XLDocument object (and .xlsx file)
*/
enum class XLProperty {
Title,
Subject,
Creator,
Keywords,
Description,
LastModifiedBy,
LastPrinted,
CreationDate,
ModificationDate,
Category,
Application,
DocSecurity,
ScaleCrop,
Manager,
Company,
LinksUpToDate,
SharedDoc,
HyperlinkBase,
HyperlinksChanged,
AppVersion
};
/**
* @brief This class encapsulates the concept of an excel file. It is different from the XLWorkbook, in that an
* XLDocument holds an XLWorkbook together with its metadata, as well as methods for opening,
* closing and saving the document.\n<b><em>The XLDocument is the entrypoint for clients
* using the RapidXLSX library.</em></b>
*/
class OPENXLSX_EXPORT XLDocument final
{
//----- Friends
friend class XLXmlFile;
friend class XLWorkbook;
friend class XLSheet;
friend class XLXmlData;
//---------- Public Member Functions
public:
/**
* @brief Constructor. The default constructor with no arguments.
*/
explicit XLDocument(const IZipArchive& zipArchive = XLZipArchive());
/**
* @brief Constructor. An alternative constructor, taking the path to the .xlsx file as an argument.
* @param docPath A std::string with the path to the .xlsx file.
*/
explicit XLDocument(const std::string& docPath, const IZipArchive& zipArchive = XLZipArchive());
/**
* @brief Copy constructor
* @param other The object to copy
* @note Copy constructor explicitly deleted.
*/
XLDocument(const XLDocument& other) = delete;
/**
* @brief
* @param other
*/
XLDocument(XLDocument&& other) noexcept = default;
/**
* @brief Destructor
*/
~XLDocument();
/**
* @brief
* @param other
* @return
*/
XLDocument& operator=(const XLDocument& other) = delete;
/**
* @brief
* @param other
* @return
*/
XLDocument& operator=(XLDocument&& other) noexcept = default;
/**
* @brief Open the .xlsx file with the given path
* @param fileName The path of the .xlsx file to open
*/
void open(const std::string& fileName);
/**
* @brief Create a new .xlsx file with the given name.
* @param fileName The path of the new .xlsx file.
*/
void create(const std::string& fileName);
/**
* @brief Close the current document
*/
void close();
/**
* @brief Save the current document using the current filename, overwriting the existing file.
* @return true if successful; otherwise false.
*/
void save();
/**
* @brief Save the document with a new name. If a file exists with that name, it will be overwritten.
* @param fileName The path of the file
* @return true if successful; otherwise false.
*/
void saveAs(const std::string& fileName);
/**
* @brief Get the filename of the current document, e.g. "spreadsheet.xlsx".
* @return A std::string with the filename.
*/
const std::string& name() const;
/**
* @brief Get the full path of the current document, e.g. "drive/blah/spreadsheet.xlsx"
* @return A std::string with the path.
*/
const std::string& path() const;
/**
* @brief Get the underlying workbook object, as a const object.
* @return A const pointer to the XLWorkbook object.
*/
XLWorkbook workbook() const;
/**
* @brief Get the requested document property.
* @param prop The name of the property to get.
* @return The property as a string
*/
std::string property(XLProperty prop) const;
/**
* @brief Set a property
* @param prop The property to set.
* @param value The getValue of the property, as a string
*/
void setProperty(XLProperty prop, const std::string& value);
/**
* @brief
* @return
*/
explicit operator bool() const;
/**
* @brief
* @return
*/
bool isOpen() const;
/**
* @brief Delete the property from the document
* @param theProperty The property to delete from the document
*/
void deleteProperty(XLProperty theProperty);
/**
* @brief
* @param command
*/
void execCommand(const XLCommand& command);
/**
* @brief
* @param query
* @return
*/
XLQuery execQuery(const XLQuery& query) const;
/**
* @brief
* @param query
* @return
*/
XLQuery execQuery(const XLQuery& query);
//----------------------------------------------------------------------------------------------------------------------
// Protected Member Functions
//----------------------------------------------------------------------------------------------------------------------
protected:
/**
* @brief Get an XML file from the .xlsx archive.
* @param path The relative path of the file.
* @return A std::string with the content of the file
*/
std::string extractXmlFromArchive(const std::string& path);
/**
* @brief
* @param path
* @return
*/
XLXmlData* getXmlData(const std::string& path);
/**
* @brief
* @param path
* @return
*/
const XLXmlData* getXmlData(const std::string& path) const;
/**
* @brief
* @param path
* @return
*/
bool hasXmlData(const std::string& path) const;
//----------------------------------------------------------------------------------------------------------------------
// Private Member Variables
//----------------------------------------------------------------------------------------------------------------------
private:
std::string m_filePath {}; /**< The path to the original file*/
std::string m_realPath {}; /**< */
mutable std::list<XLXmlData> m_data {}; /**< */
mutable std::deque<std::string> m_sharedStringCache {}; /**< */
mutable XLSharedStrings m_sharedStrings {}; /**< */
XLRelationships m_docRelationships {}; /**< A pointer to the document relationships object*/
XLRelationships m_wbkRelationships {}; /**< A pointer to the document relationships object*/
XLContentTypes m_contentTypes {}; /**< A pointer to the content types object*/
XLAppProperties m_appProperties {}; /**< A pointer to the App properties object */
XLProperties m_coreProperties {}; /**< A pointer to the Core properties object*/
XLWorkbook m_workbook {}; /**< A pointer to the workbook object */
IZipArchive m_archive {}; /**< */
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLDOCUMENT_HPP

View File

@@ -0,0 +1,155 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLEXCEPTION_HPP
#define OPENXLSX_XLEXCEPTION_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <stdexcept>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
namespace OpenXLSX
{
/**
* @brief
*/
class OPENXLSX_EXPORT XLException : public std::runtime_error
{
public:
inline explicit XLException(const std::string& err) : runtime_error(err) {};
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLOverflowError : public XLException
{
public:
inline explicit XLOverflowError(const std::string& err) : XLException(err) {};
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLValueTypeError : public XLException
{
public:
inline explicit XLValueTypeError(const std::string& err) : XLException(err) {};
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLCellAddressError : public XLException
{
public:
inline explicit XLCellAddressError(const std::string& err) : XLException(err) {};
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLInputError : public XLException
{
public:
inline explicit XLInputError(const std::string& err) : XLException(err) {};
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLInternalError : public XLException
{
public:
inline explicit XLInternalError(const std::string& err) : XLException(err) {};
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLPropertyError : public XLException
{
public:
inline explicit XLPropertyError(const std::string& err) : XLException(err) {};
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLSheetError : public XLException
{
public:
inline explicit XLSheetError(const std::string& err) : XLException(err) {};
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLDateTimeError : public XLException
{
public:
inline explicit XLDateTimeError(const std::string& err) : XLException(err) {};
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLFormulaError : public XLException
{
public:
inline explicit XLFormulaError(const std::string& err) : XLException(err) {};
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLEXCEPTION_HPP

View File

@@ -0,0 +1,365 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLFORMULA_HPP
#define OPENXLSX_XLFORMULA_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <cstdint>
#include <iostream>
#include <string>
#include <variant>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLException.hpp"
#include "XLXmlParser.hpp"
// ========== CLASS AND ENUM TYPE DEFINITIONS ========== //
namespace OpenXLSX
{
//---------- Forward Declarations ----------//
class XLFormulaProxy;
class XLCell;
/**
* @brief The XLFormula class encapsulates the concept of an Excel formula. The class is essentially
* a wrapper around a std::string.
* @warning This class currently only supports simple formulas. Array formulas and shared formulas are
* not supported. Unfortunately, many spreadsheets have shared formulas, so this class is probably
* best used for adding formulas, not reading them from an existing spreadsheet.
* @todo Enable handling of shared and array formulas.
*/
class OPENXLSX_EXPORT XLFormula
{
//---------- Friend Declarations ----------//
friend bool operator==(const XLFormula& lhs, const XLFormula& rhs);
friend bool operator!=(const XLFormula& lhs, const XLFormula& rhs);
friend std::ostream& operator<<(std::ostream& os, const XLFormula& value);
public:
/**
* @brief Constructor
*/
XLFormula();
/**
* @brief Constructor, taking a string-type argument
* @tparam T Type of argument used. Must be string-type.
* @param formula The formula to initialize the object with.
*/
template<typename T,
typename std::enable_if<
std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> ||
std::is_same_v<std::decay_t<T>, const char*> || std::is_same_v<std::decay_t<T>, char*>>::type* = nullptr>
explicit XLFormula(T formula)
{
// ===== If the argument is a const char *, use the argument directly; otherwise, assume it has a .c_str() function.
if constexpr (std::is_same_v<std::decay_t<T>, const char*> || std::is_same_v<std::decay_t<T>, char*>)
m_formulaString = formula;
else if constexpr (std::is_same_v<std::decay_t<T>, std::string_view>)
m_formulaString = std::string(formula);
else
m_formulaString = formula.c_str();
}
/**
* @brief Copy constructor.
* @param other Object to be copied.
*/
XLFormula(const XLFormula& other);
/**
* @brief Move constructor.
* @param other Object to be moved.
*/
XLFormula(XLFormula&& other) noexcept;
/**
* @brief Destructor.
*/
~XLFormula();
/**
* @brief Copy assignment operator.
* @param other Object to be copied.
* @return Reference to copied-to object.
*/
XLFormula& operator=(const XLFormula& other);
/**
* @brief Move assignment operator.
* @param other Object to be moved.
* @return Reference to moved-to object.
*/
XLFormula& operator=(XLFormula&& other) noexcept;
/**
* @brief Templated assignment operator, taking a string-type object as an argument.
* @tparam T Type of argument (only string-types are allowed).
* @param formula String containing the formula.
* @return Reference to the assigned-to object.
*/
template<typename T,
typename std::enable_if<
std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> ||
std::is_same_v<std::decay_t<T>, const char*> || std::is_same_v<std::decay_t<T>, char*>>::type* = nullptr>
XLFormula& operator=(T formula)
{
XLFormula temp(formula);
std::swap(*this, temp);
return *this;
}
/**
* @brief Templated setter function, taking a string-type object as an argument.
* @tparam T Type of argument (only string-types are allowed).
* @param formula String containing the formula.
*/
template<typename T,
typename std::enable_if<
std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> ||
std::is_same_v<std::decay_t<T>, const char*> || std::is_same_v<std::decay_t<T>, char*>>::type* = nullptr>
void set(T formula)
{
*this = formula;
}
/**
* @brief Get the forumla as a std::string.
* @return A std::string with the formula.
*/
std::string get() const;
/**
* @brief Conversion operator, for converting object to a std::string.
* @return The formula as a std::string.
*/
operator std::string() const; // NOLINT
/**
* @brief Clear the formula.
* @return Return a reference to the cleared object.
*/
XLFormula& clear();
private:
std::string m_formulaString; /**< A std::string, holding the formula string.*/
};
/**
* @brief The XLFormulaProxy serves as a placeholder for XLFormula objects. This enable
* getting and setting formulas through the same interface.
*/
class OPENXLSX_EXPORT XLFormulaProxy
{
friend class XLCell;
friend class XLFormula;
public:
/**
* @brief Destructor
*/
~XLFormulaProxy();
/**
* @brief Copy assignment operator.
* @param other Object to be copied.
* @return A reference to the copied-to object.
*/
XLFormulaProxy& operator=(const XLFormulaProxy& other);
/**
* @brief Templated assignment operator, taking a string-type argument.
* @tparam T Type of argument.
* @param formula The formula string to be assigned.
* @return A reference to the copied-to object.
*/
template<
typename T,
typename std::enable_if<std::is_same_v<std::decay_t<T>, XLFormula> || std::is_same_v<std::decay_t<T>, std::string> ||
std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char*> ||
std::is_same_v<std::decay_t<T>, char*>>::type* = nullptr>
XLFormulaProxy& operator=(T formula)
{
if constexpr (std::is_same_v<std::decay_t<T>, XLFormula>)
setFormulaString(formula.get().c_str());
else if constexpr (std::is_same_v<std::decay_t<T>, std::string>)
setFormulaString(formula.c_str());
else if constexpr (std::is_same_v<std::decay_t<T>, std::string_view>)
setFormulaString(std::string(formula).c_str());
else
setFormulaString(formula);
return *this;
}
/**
* @brief Templated setter, taking a string-type argument.
* @tparam T Type of argument.
* @param formula The formula string to be assigned.
*/
template<typename T,
typename std::enable_if<
std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> ||
std::is_same_v<std::decay_t<T>, const char*> || std::is_same_v<std::decay_t<T>, char*>>::type* = nullptr>
void set(T formula)
{
*this = formula;
}
/**
* @brief Get the forumla as a std::string.
* @return A std::string with the formula.
*/
std::string get() const;
/**
* @brief Clear the formula.
* @return Return a reference to the cleared object.
*/
XLFormulaProxy& clear();
/**
* @brief Conversion operator, for converting the object to a std::string.
* @return The formula as a std::string.
*/
operator std::string() const; // NOLINT
/**
* @brief Implicit conversion to XLFormula object.
* @return Returns the corresponding XLFormula object.
*/
operator XLFormula() const; // NOLINT
private:
/**
* @brief Constructor, taking pointers to the cell and cell node objects.
* @param cell Pointer to the associated cell object.
* @param cellNode Pointer to the associated cell node object.
*/
XLFormulaProxy(XLCell* cell, XMLNode* cellNode);
/**
* @brief Copy constructor.
* @param other Object to be copied.
*/
XLFormulaProxy(const XLFormulaProxy& other);
/**
* @brief Move constructor.
* @param other Object to be moved.
*/
XLFormulaProxy(XLFormulaProxy&& other) noexcept;
/**
* @brief Move assignment operator.
* @param other Object to be moved.
* @return A reference to the moved-to object.
*/
XLFormulaProxy& operator=(XLFormulaProxy&& other) noexcept;
/**
* @brief Set the formula to the given string.
* @param formulaString String holding the formula.
*/
void setFormulaString(const char* formulaString);
/**
* @brief Get the underlying XLFormula object.
* @return A XLFormula object.
* @throw XLFormulaError if the formula is of 'shared' or 'array' types.
*/
XLFormula getFormula() const;
//---------- Private Member Variables ---------- //
XLCell* m_cell; /**< Pointer to the owning XLCell object. */
XMLNode* m_cellNode; /**< Pointer to corresponding XML cell node. */
};
} // namespace OpenXLSX
// ========== FRIEND FUNCTION IMPLEMENTATIONS ========== //
namespace OpenXLSX
{
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator==(const XLFormula& lhs, const XLFormula& rhs)
{
return lhs.m_formulaString == rhs.m_formulaString;
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator!=(const XLFormula& lhs, const XLFormula& rhs)
{
return lhs.m_formulaString != rhs.m_formulaString;
}
/**
* @brief
* @param os
* @param value
* @return
*/
inline std::ostream& operator<<(std::ostream& os, const XLFormula& value)
{
return os << value.m_formulaString;
}
} // namespace OpenXLSX
#endif // OPENXLSX_XLFORMULA_HPP

View File

@@ -0,0 +1,15 @@
//
// Created by Kenneth Balslev on 22/08/2020.
//
#ifndef OPENXLSX_XLITERATOR_HPP
#define OPENXLSX_XLITERATOR_HPP
namespace OpenXLSX
{
enum class XLIteratorDirection { Forward, Reverse };
enum class XLIteratorLocation { Begin, End };
} // namespace OpenXLSX
#endif // OPENXLSX_XLITERATOR_HPP

View File

@@ -0,0 +1,298 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLPROPERTIES_HPP
#define OPENXLSX_XLPROPERTIES_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <map>
#include <string>
#include <vector>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLXmlFile.hpp"
namespace OpenXLSX
{
/**
* @brief
*/
class OPENXLSX_EXPORT XLProperties : public XLXmlFile
{
//----------------------------------------------------------------------------------------------------------------------
// Public Member Functions
//----------------------------------------------------------------------------------------------------------------------
public:
/**
* @brief
*/
XLProperties() = default;
/**
* @brief
* @param xmlData
*/
explicit XLProperties(XLXmlData* xmlData);
/**
* @brief
* @param other
*/
XLProperties(const XLProperties& other) = default;
/**
* @brief
* @param other
*/
XLProperties(XLProperties&& other) noexcept = default;
/**
* @brief
*/
~XLProperties();
/**
* @brief
* @param other
* @return
*/
XLProperties& operator=(const XLProperties& other) = default;
/**
* @brief
* @param other
* @return
*/
XLProperties& operator=(XLProperties&& other) = default;
/**
* @brief
* @param name
* @param value
* @return
*/
void setProperty(const std::string& name, const std::string& value);
/**
* @brief
* @param name
* @param value
* @return
*/
void setProperty(const std::string& name, int value);
/**
* @brief
* @param name
* @param value
* @return
*/
void setProperty(const std::string& name, double value);
/**
* @brief
* @param name
* @return
*/
std::string property(const std::string& name) const;
/**
* @brief
* @param name
*/
void deleteProperty(const std::string& name);
//----------------------------------------------------------------------------------------------------------------------
// Protected Member Functions
//----------------------------------------------------------------------------------------------------------------------
};
/**
* @brief This class is a specialization of the XLAbstractXMLFile, with the purpose of the representing the
* document app properties in the app.xml file (docProps folder) in the .xlsx package.
*/
class OPENXLSX_EXPORT XLAppProperties : public XLXmlFile
{
//--------------------------------------------------------------------------------------------------------------
// Public Member Functions
//--------------------------------------------------------------------------------------------------------------
public:
/**
* @brief
*/
XLAppProperties() = default;
/**
* @brief
* @param xmlData
*/
explicit XLAppProperties(XLXmlData* xmlData);
/**
* @brief
* @param other
*/
XLAppProperties(const XLAppProperties& other) = default;
/**
* @brief
* @param other
*/
XLAppProperties(XLAppProperties&& other) noexcept = default;
/**
* @brief
*/
~XLAppProperties();
/**
* @brief
* @param other
* @return
*/
XLAppProperties& operator=(const XLAppProperties& other) = default;
/**
* @brief
* @param other
* @return
*/
XLAppProperties& operator=(XLAppProperties&& other) noexcept = default;
/**
* @brief
* @param title
* @return
*/
void addSheetName(const std::string& title);
/**
* @brief
* @param title
*/
void deleteSheetName(const std::string& title);
/**
* @brief
* @param oldTitle
* @param newTitle
*/
void setSheetName(const std::string& oldTitle, const std::string& newTitle);
/**
* @brief
* @param name
* @param value
*/
void addHeadingPair(const std::string& name, int value);
/**
* @brief
* @param name
*/
void deleteHeadingPair(const std::string& name);
/**
* @brief
* @param name
* @param newValue
*/
void setHeadingPair(const std::string& name, int newValue);
/**
* @brief
* @param name
* @param value
* @return
*/
void setProperty(const std::string& name, const std::string& value);
/**
* @brief
* @param name
* @return
*/
std::string property(const std::string& name) const;
/**
* @brief
* @param name
*/
void deleteProperty(const std::string& name);
/**
* @brief
* @param sheetName
* @return
*/
void appendSheetName(const std::string& sheetName);
/**
* @brief
* @param sheetName
* @return
*/
void prependSheetName(const std::string& sheetName);
/**
* @brief
* @param sheetName
* @param index
* @return
*/
void insertSheetName(const std::string& sheetName, unsigned int index);
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLPROPERTIES_HPP

View File

@@ -0,0 +1,278 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLRELATIONSHIPS_HPP
#define OPENXLSX_XLRELATIONSHIPS_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <string>
#include <vector>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLXmlFile.hpp"
#include "XLXmlParser.hpp"
namespace OpenXLSX
{
class XLRelationships;
class XLRelationshipItem;
/**
* @brief An enum of the possible relationship (or XML document) types used in relationship (.rels) XML files.
*/
enum class XLRelationshipType {
CoreProperties,
ExtendedProperties,
CustomProperties,
Workbook,
Worksheet,
Chartsheet,
Dialogsheet,
Macrosheet,
CalculationChain,
ExternalLink,
ExternalLinkPath,
Theme,
Styles,
Chart,
ChartStyle,
ChartColorStyle,
Image,
Drawing,
VMLDrawing,
SharedStrings,
PrinterSettings,
VBAProject,
ControlProperties,
Unknown
};
/**
* @brief An encapsulation of a relationship item, i.e. an XML file in the document, its type and an ID number.
*/
class OPENXLSX_EXPORT XLRelationshipItem
{
public: // ---------- Public Member Functions ---------- //
/**
* @brief
*/
XLRelationshipItem();
/**
* @brief Constructor. New items should only be created through an XLRelationship object.
* @param node An XMLNode object with the relationship item. If no input is provided, a null node is used.
*/
explicit XLRelationshipItem(const XMLNode& node);
/**
* @brief Copy Constructor.
* @param other Object to be copied.
*/
XLRelationshipItem(const XLRelationshipItem& other);
/**
* @brief Move Constructor.
* @param other Object to be moved.
*/
XLRelationshipItem(XLRelationshipItem&& other) noexcept = default;
/**
* @brief
*/
~XLRelationshipItem();
/**
* @brief Copy assignment operator.
* @param other Right hand side of assignment operation.
* @return A reference to the lhs object.
*/
XLRelationshipItem& operator=(const XLRelationshipItem& other);
/**
* @brief Move assignment operator.
* @param other Right hand side of assignment operation.
* @return A reference to lhs object.
*/
XLRelationshipItem& operator=(XLRelationshipItem&& other) noexcept = default;
/**
* @brief Get the type of the current relationship item.
* @return An XLRelationshipType enum object, corresponding to the type.
*/
XLRelationshipType type() const;
/**
* @brief Get the target, i.e. the path to the XML file the relationship item refers to.
* @return An XMLAttribute object containing the Target getValue.
*/
std::string target() const;
/**
* @brief Get the id of the relationship item.
* @return An XMLAttribute object containing the Id getValue.
*/
std::string id() const;
private: // ---------- Private Member Variables ---------- //
std::unique_ptr<XMLNode> m_relationshipNode; /**< An XMLNode object with the relationship item */
};
// ================================================================================
// XLRelationships Class
// ================================================================================
/**
* @brief An encapsulation of relationship files (.rels files) in an Excel document package.
*/
class OPENXLSX_EXPORT XLRelationships : public XLXmlFile
{
public: // ---------- Public Member Functions ---------- //
/**
* @brief
*/
XLRelationships() = default;
/**
* @brief
* @param xmlData
*/
explicit XLRelationships(XLXmlData* xmlData);
/**
* @brief Destructor
*/
~XLRelationships();
/**
* @brief
* @param other
*/
XLRelationships(const XLRelationships& other) = default;
/**
* @brief
* @param other
*/
XLRelationships(XLRelationships&& other) noexcept = default;
/**
* @brief
* @param other
* @return
*/
XLRelationships& operator=(const XLRelationships& other) = default;
/**
* @brief
* @param other
* @return
*/
XLRelationships& operator=(XLRelationships&& other) noexcept = default;
/**
* @brief Look up a relationship item by ID.
* @param id The ID string of the relationship item to retrieve.
* @return An XLRelationshipItem object.
*/
XLRelationshipItem relationshipById(const std::string& id) const;
/**
* @brief Look up a relationship item by Target.
* @param target The Target string of the relationship item to retrieve.
* @return An XLRelationshipItem object.
*/
XLRelationshipItem relationshipByTarget(const std::string& target) const;
/**
* @brief Get the std::map with the relationship items, ordered by ID.
* @return A const reference to the std::map with relationship items.
*/
std::vector<XLRelationshipItem> relationships() const;
/**
* @brief
* @param relID
*/
void deleteRelationship(const std::string& relID);
/**
* @brief Delete an item from the Relationships register
* @param item The XLRelationshipItem object to delete.
*/
void deleteRelationship(const XLRelationshipItem& item);
/**
* @brief Add a new relationship item to the XLRelationships object.
* @param type The type of the new relationship item.
* @param target The target (or path) of the XML file for the relationship item.
*/
XLRelationshipItem addRelationship(XLRelationshipType type, const std::string& target);
/**
* @brief Check if a XLRelationshipItem with the given Target string exists.
* @param target The Target string to look up.
* @return true if the XLRelationshipItem exists; otherwise false.
*/
bool targetExists(const std::string& target) const;
/**
* @brief Check if a XLRelationshipItem with the given Id string exists.
* @param id The Id string to look up.
* @return true if the XLRelationshipItem exists; otherwise false.
*/
bool idExists(const std::string& id) const;
// ---------- Protected Member Functions ---------- //
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLRELATIONSHIPS_HPP

View File

@@ -0,0 +1,496 @@
/*
____ ____ ___ ____ ____ ____ ___
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
8P Y8 `MM. d' MM 6M' ` `MM. d'
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
MM
MM
_MM_
Copyright (c) 2018, Kenneth Troldal Balslev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the author nor the
names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENXLSX_XLROW_HPP
#define OPENXLSX_XLROW_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLRowData.hpp"
// ========== CLASS AND ENUM TYPE DEFINITIONS ========== //
namespace OpenXLSX
{
class XLRowRange;
/**
* @brief The XLRow class represent a row in an Excel spreadsheet. Using XLRow objects, various row formatting
* options can be set and modified.
*/
class OPENXLSX_EXPORT XLRow
{
friend class XLRowIterator;
friend class XLRowDataProxy;
friend bool operator==(const XLRow& lhs, const XLRow& rhs);
friend bool operator!=(const XLRow& lhs, const XLRow& rhs);
friend bool operator<(const XLRow& lhs, const XLRow& rhs);
friend bool operator>(const XLRow& lhs, const XLRow& rhs);
friend bool operator<=(const XLRow& lhs, const XLRow& rhs);
friend bool operator>=(const XLRow& lhs, const XLRow& rhs);
//---------- PUBLIC MEMBER FUNCTIONS ----------//
public:
/**
* @brief Default constructor
*/
XLRow();
/**
* @brief
* @param rowNode
* @param sharedStrings
*/
XLRow(const XMLNode& rowNode, const XLSharedStrings& sharedStrings);
/**
* @brief Copy Constructor
* @note The copy constructor is explicitly deleted
*/
XLRow(const XLRow& other);
/**
* @brief Move Constructor
* @note The move constructor has been explicitly deleted.
*/
XLRow(XLRow&& other) noexcept;
/**
* @brief Destructor
* @note The destructor has a default implementation.
*/
~XLRow();
/**
* @brief Copy assignment operator.
* @note The copy assignment operator is explicitly deleted.
*/
XLRow& operator=(const XLRow& other);
/**
* @brief Move assignment operator.
* @note The move assignment operator has been explicitly deleted.
*/
XLRow& operator=(XLRow&& other) noexcept;
/**
* @brief Get the height of the row.
* @return the row height.
*/
double height() const;
/**
* @brief Set the height of the row.
* @param height The height of the row.
*/
void setHeight(float height);
/**
* @brief Get the descent of the row, which is the vertical distance in pixels from the bottom of the cells
* in the current row to the typographical baseline of the cell content.
* @return The row descent.
*/
float descent() const;
/**
* @brief Set the descent of the row, which is he vertical distance in pixels from the bottom of the cells
* in the current row to the typographical baseline of the cell content.
* @param descent The row descent.
*/
void setDescent(float descent);
/**
* @brief Is the row hidden?
* @return The state of the row.
*/
bool isHidden() const;
/**
* @brief Set the row to be hidden or visible.
* @param state The state of the row.
*/
void setHidden(bool state);
/**
* @brief
* @return
*/
uint64_t rowNumber() const;
/**
* @brief Get the number of cells in the row.
* @return The number of cells in the row.
*/
unsigned int cellCount() const;
/**
* @brief
* @return
*/
XLRowDataProxy& values();
/**
* @brief
* @return
*/
const XLRowDataProxy& values() const;
/**
* @brief
* @tparam T
* @return
*/
template<typename T>
T values() const
{
return static_cast<T>(values());
}
/**
* @brief
* @return
*/
XLRowDataRange cells() const;
/**
* @brief
* @param cellCount
* @return
*/
XLRowDataRange cells(uint16_t cellCount) const;
/**
* @brief
* @param firstCell
* @param lastCell
* @return
*/
XLRowDataRange cells(uint16_t firstCell, uint16_t lastCell) const;
private:
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
static bool isEqual(const XLRow& lhs, const XLRow& rhs);
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
static bool isLessThan(const XLRow& lhs, const XLRow& rhs);
//---------- PRIVATE MEMBER VARIABLES ----------//
std::unique_ptr<XMLNode> m_rowNode; /**< The XMLNode object for the row. */
XLSharedStrings m_sharedStrings; /**< */
XLRowDataProxy m_rowDataProxy; /**< */
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLRowIterator
{
public:
using iterator_category = std::forward_iterator_tag;
using value_type = XLRow;
using difference_type = int64_t;
using pointer = XLRow*;
using reference = XLRow&;
/**
* @brief
* @param rowRange
* @param loc
*/
explicit XLRowIterator(const XLRowRange& rowRange, XLIteratorLocation loc);
/**
* @brief
*/
~XLRowIterator();
/**
* @brief
* @param other
*/
XLRowIterator(const XLRowIterator& other);
/**
* @brief
* @param other
*/
XLRowIterator(XLRowIterator&& other) noexcept;
/**
* @brief
* @param other
* @return
*/
XLRowIterator& operator=(const XLRowIterator& other);
/**
* @brief
* @param other
* @return
*/
XLRowIterator& operator=(XLRowIterator&& other) noexcept;
/**
* @brief
* @return
*/
XLRowIterator& operator++();
/**
* @brief
* @return
*/
XLRowIterator operator++(int); // NOLINT
/**
* @brief
* @return
*/
reference operator*();
/**
* @brief
* @return
*/
pointer operator->();
/**
* @brief
* @param rhs
* @return
*/
bool operator==(const XLRowIterator& rhs) const;
/**
* @brief
* @param rhs
* @return
*/
bool operator!=(const XLRowIterator& rhs) const;
/**
* @brief
* @return
*/
explicit operator bool() const;
private:
std::unique_ptr<XMLNode> m_dataNode; /**< */
uint32_t m_firstRow { 1 }; /**< The cell reference of the first cell in the range */
uint32_t m_lastRow { 1 }; /**< The cell reference of the last cell in the range */
XLRow m_currentRow; /**< */
XLSharedStrings m_sharedStrings; /**< */
};
/**
* @brief
*/
class OPENXLSX_EXPORT XLRowRange
{
friend class XLRowIterator;
//----------------------------------------------------------------------------------------------------------------------
// Public Member Functions
//----------------------------------------------------------------------------------------------------------------------
public:
/**
* @brief
* @param dataNode
* @param first
* @param last
* @param sharedStrings
*/
explicit XLRowRange(const XMLNode& dataNode, uint32_t first, uint32_t last, const XLSharedStrings& sharedStrings);
/**
* @brief
* @param other
*/
XLRowRange(const XLRowRange& other);
/**
* @brief
* @param other
*/
XLRowRange(XLRowRange&& other) noexcept;
/**
* @brief
*/
~XLRowRange();
/**
* @brief
* @param other
* @return
*/
XLRowRange& operator=(const XLRowRange& other);
/**
* @brief
* @param other
* @return
*/
XLRowRange& operator=(XLRowRange&& other) noexcept;
/**
* @brief
* @return
*/
uint32_t rowCount() const;
/**
* @brief
* @return
*/
XLRowIterator begin();
/**
* @brief
* @return
*/
XLRowIterator end();
//----------------------------------------------------------------------------------------------------------------------
// Private Member Variables
//----------------------------------------------------------------------------------------------------------------------
private:
std::unique_ptr<XMLNode> m_dataNode; /**< */
uint32_t m_firstRow; /**< The cell reference of the first cell in the range */
uint32_t m_lastRow; /**< The cell reference of the last cell in the range */
XLSharedStrings m_sharedStrings; /**< */
};
} // namespace OpenXLSX
// ========== FRIEND FUNCTION IMPLEMENTATIONS ========== //
namespace OpenXLSX
{
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator==(const XLRow& lhs, const XLRow& rhs)
{
return XLRow::isEqual(lhs, rhs);
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator!=(const XLRow& lhs, const XLRow& rhs)
{
return !(lhs.m_rowNode == rhs.m_rowNode);
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator<(const XLRow& lhs, const XLRow& rhs)
{
return XLRow::isLessThan(lhs, rhs);
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator>(const XLRow& lhs, const XLRow& rhs)
{
return (rhs < lhs);
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator<=(const XLRow& lhs, const XLRow& rhs)
{
return !(lhs > rhs);
}
/**
* @brief
* @param lhs
* @param rhs
* @return
*/
inline bool operator>=(const XLRow& lhs, const XLRow& rhs)
{
return !(lhs < rhs);
}
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLROW_HPP

View File

@@ -0,0 +1,427 @@
//
// Created by Kenneth Balslev on 24/08/2020.
//
#ifndef OPENXLSX_XLROWDATA_HPP
#define OPENXLSX_XLROWDATA_HPP
#pragma warning(push)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
// ===== External Includes ===== //
#include <deque>
#include <iterator>
#include <list>
#include <memory>
#include <vector>
// ===== OpenXLSX Includes ===== //
#include "OpenXLSX-Exports.hpp"
#include "XLCell.hpp"
#include "XLConstants.hpp"
#include "XLException.hpp"
#include "XLIterator.hpp"
#include "XLXmlParser.hpp"
// ========== CLASS AND ENUM TYPE DEFINITIONS ========== //
namespace OpenXLSX
{
class XLRow;
class XLRowDataRange;
/**
* @brief This class encapsulates a (non-const) iterator, for iterating over the cells in a row.
* @todo Consider implementing a const iterator also
*/
class OPENXLSX_EXPORT XLRowDataIterator
{
friend class XLRowDataRange;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = XLCell;
using difference_type = int64_t;
using pointer = XLCell*;
using reference = XLCell&;
/**
* @brief Destructor.
*/
~XLRowDataIterator();
/**
* @brief Copy constructor.
* @param other Object to be copied.
*/
XLRowDataIterator(const XLRowDataIterator& other);
/**
* @brief Move constructor.
* @param other Object to be moved.
*/
XLRowDataIterator(XLRowDataIterator&& other) noexcept;
/**
* @brief Copy assignment operator.
* @param other Object to be copied.
* @return Reference to the copied-to object.
*/
XLRowDataIterator& operator=(const XLRowDataIterator& other);
/**
* @brief Move assignment operator.
* @param other Object to be moved.
* @return Reference to the moved-to object.
*/
XLRowDataIterator& operator=(XLRowDataIterator&& other) noexcept;
/**
* @brief Pre-increment of the iterator.
* @return Reference to the iterator object.
*/
XLRowDataIterator& operator++();
/**
* @brief Post-increment of the iterator.
* @return Reference to the iterator object.
*/
XLRowDataIterator operator++(int); // NOLINT
/**
* @brief Dereferencing operator.
* @return Reference to the object pointed to by the iterator.
*/
reference operator*();
/**
* @brief Arrow operator.
* @return Pointer to the object pointed to by the iterator.
*/
pointer operator->();
/**
* @brief Equality operator.
* @param rhs XLRowDataIterator to compare to.
* @return true if equal, otherwise false.
*/
bool operator==(const XLRowDataIterator& rhs) const;
/**
* @brief Non-equality operator.
* @param rhs XLRowDataIterator to compare to.
* @return false if equal, otherwise true.
*/
bool operator!=(const XLRowDataIterator& rhs) const;
private:
/**
* @brief Constructor.
* @param rowDataRange The range to iterate over.
* @param loc The location of the iterator (begin or end).
*/
XLRowDataIterator(const XLRowDataRange& rowDataRange, XLIteratorLocation loc);
std::unique_ptr<XLRowDataRange> m_dataRange; /**< A pointer to the range to iterate over. */
std::unique_ptr<XMLNode> m_cellNode; /**< The XML node representing the cell currently pointed at. */
XLCell m_currentCell; /**< The XLCell currently pointed at. */
};
/**
* @brief This class encapsulates the concept of a contiguous range of cells in a row.
*/
class OPENXLSX_EXPORT XLRowDataRange
{
friend class XLRowDataIterator;
friend class XLRowDataProxy;
friend class XLRow;
public:
/**
* @brief Copy constructor.
* @param other Object to be copied.
*/
XLRowDataRange(const XLRowDataRange& other);
/**
* @brief Move constructor.
* @param other Object to be moved.
*/
XLRowDataRange(XLRowDataRange&& other) noexcept;
/**
* @brief Destructor.
*/
~XLRowDataRange();
/**
* @brief Copy assignment operator.
* @param other Object to be copied.
* @return A reference to the copied-to object.
*/
XLRowDataRange& operator=(const XLRowDataRange& other);
/**
* @brief Move assignment operator.
* @param other Object to be moved.
* @return A reference to the moved-to object.
*/
XLRowDataRange& operator=(XLRowDataRange&& other) noexcept;
/**
* @brief Get the size (length) of the range.
* @return The size of the range.
*/
uint16_t size() const;
/**
* @brief Get an iterator to the first element.
* @return An XLRowDataIterator pointing to the first element.
*/
XLRowDataIterator begin();
/**
* @brief Get an iterator to (one-past) the last element.
* @return An XLRowDataIterator pointing to (one past) the last element.
*/
XLRowDataIterator end();
private:
/**
* @brief Constructor.
* @param rowNode XMLNode representing the row of the range.
* @param firstColumn The index of the first column.
* @param lastColumn The index of the last column.
* @param sharedStrings A pointer to the shared strings repository.
*/
explicit XLRowDataRange(const XMLNode& rowNode, uint16_t firstColumn, uint16_t lastColumn, const XLSharedStrings& sharedStrings);
std::unique_ptr<XMLNode> m_rowNode; /**< */
uint16_t m_firstCol { 1 }; /**< The cell reference of the first cell in the range */
uint16_t m_lastCol { 1 }; /**< The cell reference of the last cell in the range */
XLSharedStrings m_sharedStrings; /**< */
};
/**
* @brief The XLRowDataProxy is used as a proxy object when getting or setting row data. The class facilitates easy conversion
* to/from containers.
*/
class OPENXLSX_EXPORT XLRowDataProxy
{
friend class XLRow;
public:
/**
* @brief Destructor
*/
~XLRowDataProxy();
/**
* @brief Copy assignment operator.
* @param other Object to be copied.
* @return A reference to the copied-to object.
*/
XLRowDataProxy& operator=(const XLRowDataProxy& other);
/**
* @brief Assignment operator taking a std::vector of XLCellValues as an argument.
* @param values A std::vector of XLCellValues representing the values to be assigned.
* @return A reference to the copied-to object.
*/
XLRowDataProxy& operator=(const std::vector<XLCellValue>& values);
/**
* @brief Assignment operator taking a std::vector of bool values as an argument.
* @param values A std::vector of bool values representing the values to be assigned.
* @return A reference to the copied-to object.
*/
XLRowDataProxy& operator=(const std::vector<bool>& values);
/**
* @brief Templated assignment operator taking any container supporting bidirectional iterators.
* @tparam T The container and value type (will be auto deducted by the compiler).
* @param values The container of the values to be assigned.
* @return A reference to the copied-to object.
* @throws XLOverflowError if size of container exceeds maximum number of columns.
*/
template<typename T,
typename std::enable_if<!std::is_same_v<T, XLRowDataProxy> &&
std::is_base_of_v<typename std::bidirectional_iterator_tag,
typename std::iterator_traits<typename T::iterator>::iterator_category>,
T>::type* = nullptr>
XLRowDataProxy& operator=(const T& values)
{
if (values.size() > MAX_COLS) throw XLOverflowError("Container size exceeds maximum number of columns.");
if (values.size() == 0) return *this;
// ===== If the container value_type is XLCellValue, the values can be copied directly.
if constexpr (std::is_same_v<typename T::value_type, XLCellValue>) {
// ===== First, delete the values in the first N columns.
deleteCellValues(values.size());
// ===== Then, prepend new cell nodes to current row node
auto colNo = values.size();
for (auto value = values.rbegin(); value != values.rend(); ++value) { // NOLINT
prependCellValue(*value, colNo);
--colNo;
}
}
// ===== If the container value_type is a POD type, use the overloaded operator= on each cell.
else {
auto range = XLRowDataRange(*m_rowNode, 1, values.size(), getSharedStrings());
auto dst = range.begin();
auto src = values.begin();
while (true) {
dst->value() = *src;
++src;
if (src == values.end()) break;
++dst;
}
}
return *this;
}
/**
* @brief Implicit conversion to std::vector of XLCellValues.
* @return A std::vector of XLCellValues.
*/
operator std::vector<XLCellValue>() const; // NOLINT
/**
* @brief Implicit conversion to std::deque of XLCellValues.
* @return A std::deque of XLCellValues.
*/
operator std::deque<XLCellValue>() const; // NOLINT
/**
* @brief Implicit conversion to std::list of XLCellValues.
* @return A std::list of XLCellValues.
*/
operator std::list<XLCellValue>() const; // NOLINT
/**
* @brief Explicit conversion operator.
* @details This function calls the convertContainer template function to convert the row data to the container
* stipulated by the client. The reason that this function is marked explicit is that the implicit conversion operators
* above will be ambiguous.
* @tparam Container The container (and value) type to convert the row data to.
* @return The required container with the row data.
*/
template<
typename Container,
typename std::enable_if<!std::is_same_v<Container, XLRowDataProxy> &&
std::is_base_of_v<typename std::bidirectional_iterator_tag,
typename std::iterator_traits<typename Container::iterator>::iterator_category>,
Container>::type* = nullptr>
explicit operator Container() const
{
return convertContainer<Container>();
}
/**
* @brief Clears all values for the current row.
*/
void clear();
private:
//---------- Private Member Functions ---------- //
/**
* @brief Constructor.
* @param row Pointer to the parent XLRow object.
* @param rowNode Pointer to the underlying XML node representing the row.
*/
XLRowDataProxy(XLRow* row, XMLNode* rowNode);
/**
* @brief Copy constructor.
* @param other Object to be copied.
* @note The copy constructor is private in order to prevent use of the auto keyword in client code.
*/
XLRowDataProxy(const XLRowDataProxy& other);
/**
* @brief Move constructor.
* @param other Object to be moved.
* @note Made private, as move construction should only be allowed when the parent object is moved. Disallowed for client code.
*/
XLRowDataProxy(XLRowDataProxy&& other) noexcept;
/**
* @brief Move assignment operator.
* @param other Object to be moved.
* @return Reference to the moved-to object.
* @note Made private, as move assignment is disallowed for client code.
*/
XLRowDataProxy& operator=(XLRowDataProxy&& other) noexcept;
/**
* @brief Get the cell values for the row.
* @return A std::vector of XLCellValues.
*/
std::vector<XLCellValue> getValues() const;
/**
* @brief Helper function for getting a pointer to the shared strings repository.
* @return A pointer to an XLSharedStrings object.
*/
XLSharedStrings getSharedStrings() const;
/**
* @brief Convenience function for erasing the first 'count' numbers of values in the row.
* @param count The number of values to erase.
*/
void deleteCellValues(uint16_t count);
/**
* @brief Convenience function for prepending a row value with a given column number.
* @param value The XLCellValue object.
* @param col The column of the value.
*/
void prependCellValue(const XLCellValue& value, uint16_t col);
/**
* @brief Convenience function for converting the row data to a user-supplied container.
* @details This function can convert row data to any user-supplied container that adheres to the design
* of STL containers and supports bidirectional iterators. This could be std::vector, std::deque, or
* std::list, but any container with the same interface should work.
* @tparam Container The container (and value) type to be returned.
* @return The row data in the required format.
* @throws bad_variant_access if Container::value type is not XLCellValue and does not match the type contained.
*/
template<
typename Container,
typename std::enable_if<!std::is_same_v<Container, XLRowDataProxy> &&
std::is_base_of_v<typename std::bidirectional_iterator_tag,
typename std::iterator_traits<typename Container::iterator>::iterator_category>,
Container>::type* = nullptr>
Container convertContainer() const
{
Container c;
auto it = std::inserter(c, c.end());
for (const auto& v : getValues()) {
// ===== If the value_type of the container is XLCellValue, the value can be assigned directly.
if constexpr (std::is_same_v<typename Container::value_type, XLCellValue>) *it++ = v;
// ===== If the value_type is something else, the underlying value has to be extracted from the XLCellValue object.
// ===== Note that if the type contained in the XLCellValue object does not match the value_type, a bad_variant_access
// ===== exception will be thrown.
else
*it++ = v.get<typename Container::value_type>();
}
return c;
}
//---------- Private Member Variables ---------- //
XLRow* m_row { nullptr }; /**< Pointer to the parent XLRow object. */
XMLNode* m_rowNode { nullptr }; /**< Pointer the the XML node representing the row. */
};
} // namespace OpenXLSX
#pragma warning(pop)
#endif // OPENXLSX_XLROWDATA_HPP

Some files were not shown because too many files have changed in this diff Show More