﻿#include "algorithm.h"
#include "openssl/sha.h"
#include "openssl/des.h"
#include "openssl/pem.h"
#include "openssl/err.h"
#include "openssl/pkcs12.h"
#include "openssl/aes.h"
#include <openssl/rsa.h>  
#include <openssl/pem.h>  
#include <string.h>  
#include <stdlib.h>  
#include <openssl/bio.h>  
#include <openssl/evp.h>
#include "tracer.h"
#include <string.h>
#include <vector>
#include <string>
#include <mutex>
#include "aes/aes.h"
#include "MyStringUtils.h"
#include "sole.hpp"
#pragma warning(disable:4996)



static std::recursive_mutex m_mutex;
inline void InvertUint8(unsigned char* dBuf, unsigned char* srcBuf)
{
	int i;
	unsigned char tmp = 0;
	for (i = 0; i < 8; i++)
	{
		if (srcBuf[0] & (1 << i))
			tmp |= 1 << (7 - i);
	}
	dBuf[0] = tmp;
}
inline void InvertUint16(unsigned short* dBuf, unsigned short* srcBuf)
{
	int i;
	unsigned short tmp = 0;
	for (i = 0; i < 16; i++)
	{
		if (srcBuf[0] & (1 << i))
			tmp |= 1 << (15 - i);
	}
	dBuf[0] = tmp;
}

unsigned short crc16_ibm(unsigned char* inParams, unsigned int inLen) {
	unsigned short wCRCin = 0x0000;
	unsigned short wCPoly = 0x8005;
	unsigned char wChar = 0;

	while (inLen--)
	{
		wChar = *(inParams++);
		InvertUint8(&wChar, &wChar);
		wCRCin ^= (wChar << 8);
		for (int i = 0; i < 8; i++)
		{
			if (wCRCin & 0x8000)
				wCRCin = (wCRCin << 1) ^ wCPoly;
			else
				wCRCin = wCRCin << 1;
		}
	}
	InvertUint16(&wCRCin, &wCRCin);
	return (wCRCin);
}

uint8_t* utf82unicode(const uint8_t* uft8_in, uint8_t** uni_out)
{
	if ((uft8_in) && (*uft8_in))
	{
		if (uft8_in[0] < 0x80)
		{
			(*uni_out)[0] = 0;
			(*uni_out)[1] = *uft8_in;
			(*uni_out) += 2;
			return (uint8_t*)uft8_in + 1;
		}
		else
		{
			(*uni_out)[0] = uft8_in[0] << 4;
			(*uni_out)[0] |= (uft8_in[1] >> 2) & 0x0f;
			(*uni_out)[1] = (uft8_in[1] << 6);
			(*uni_out)[1] |= (uft8_in[2]) & 0x3f;
			(*uni_out) += 2;
			return (uint8_t*)uft8_in + 3;
		}
	}
	return 0;
}

int sha256(unsigned char* inParams, unsigned int inLen, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	if (outBufferSize < 32) {
		Tracer::error("sha256", "buffer size too small");
		return -1;
	}
	SHA256_CTX context;

	SHA256_Init(&context);
	SHA256_Update(&context, inParams, inLen);
	SHA256_Final((unsigned char*)outBuffer, &context);

	return 32;
}

//加密 cbc pkcs5padding 自己实现  //pkcs7padding 跟 pkcs5padding是一样的
int des_cbc_pkcs5_encrypt(uint8_t* clearText, int inLen, char* key, char* outBuffer, unsigned int outBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	static unsigned char cbc_iv[8] = { 'j', 'k', 't', '1', '2', '3', '4', '5' };
	//初始化IV向量
	std::string cipherText;
	DES_cblock keyEncrypt, ivec;
	memset(keyEncrypt, 0, 8);

	int keyLen = (int)strlen(key);
	memcpy(keyEncrypt, key, (keyLen > 8) ? 8 : keyLen);

	DES_key_schedule keySchedule;  //密钥表
	DES_set_key_unchecked(&keyEncrypt, &keySchedule);   //设置密钥，且不检测密钥奇偶性

	memcpy(ivec, cbc_iv, sizeof(cbc_iv));

	// 循环加密，每8字节一次
	const_DES_cblock inputText;
	DES_cblock outputText;
	std::vector<unsigned char> vecCiphertext;
	unsigned char tmp[8];
	int clearLen = inLen;
	for (int i = 0; i < clearLen / 8; i++)
	{
		memcpy(inputText, clearText + i * 8, 8);
		DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密
		memcpy(tmp, outputText, 8);

		for (int j = 0; j < 8; j++)
			vecCiphertext.push_back(tmp[j]);

		//重置ivec
		memcpy(ivec, outputText, 8);
	}

	if (clearLen % 8 != 0)
	{
		int tmp1 = clearLen / 8 * 8;
		int tmp2 = clearLen - tmp1;
		memset(inputText, (8 - tmp2), 8);
		memcpy(inputText, clearText + tmp1, tmp2);
	}
	else
	{
		memset(inputText, 8, 8);
	}
	// 加密函数
	DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密
	memcpy(tmp, outputText, 8);

	for (int j = 0; j < 8; j++)
		vecCiphertext.push_back(tmp[j]);

	cipherText.clear();
	cipherText.assign(cipherText.begin(), cipherText.end());
	if (outBufferSize < cipherText.length()) {
		Tracer::error("des_encrypt", "buffer size too small");
		return -1;
	}
	memcpy(outBuffer, cipherText.c_str(), cipherText.length());
	return (int)cipherText.length();
}

int des_cbc_pkcs5_decrypt(uint8_t* cipherText, int inLen, char* key, char* outBuffer, unsigned int outBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	static unsigned char cbc_iv[8] = { 's', 'i', 'u', 'h', 'u', 'a', 'l', 'i' };
	DES_cblock keyEncrypt, ivec;
	memset(keyEncrypt, 0, 8);
	int keyLen = (int)strlen(key);
	memcpy(keyEncrypt, key, (keyLen > 8) ? 8 : keyLen);
	DES_key_schedule keySchedule;
	DES_set_key_unchecked(&keyEncrypt, &keySchedule);
	memcpy(ivec, cbc_iv, sizeof(cbc_iv));
	DES_cblock outputText;
	unsigned int bytesProcessed = 0;

	while (bytesProcessed < inLen) {
		DES_cblock inputText;
		unsigned int bytesToDecrypt = (inLen - bytesProcessed >= 8) ? 8 : (inLen - bytesProcessed);
		memcpy(inputText, cipherText + bytesProcessed, bytesToDecrypt);
		DES_ncbc_encrypt(inputText, outputText, bytesToDecrypt, &keySchedule, &ivec, DES_DECRYPT);
		memcpy(outBuffer + bytesProcessed, outputText, bytesToDecrypt);
		bytesProcessed += bytesToDecrypt;
	}

	if (outBufferSize < bytesProcessed) {
		Tracer::error("des_decrypt", "buffer size too small");
		return -1;
	}

	return bytesProcessed;
}

int base64_encode(unsigned char* str, uint32_t str_len, char* out, unsigned int outBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	unsigned int len;
	unsigned int i, j;
	//定义base64编码表
	const char* base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

	//计算经过base64编码后的字符串长度
	if (str_len % 3 == 0)
		len = str_len / 3 * 4;
	else
		len = (str_len / 3 + 1) * 4;

	if (outBufferSize < len) {
		Tracer::error("base64_encode", "buffer size too small");
		return -1;
	}

	//以3个8位字符为一组进行编码
	for (i = 0, j = 0; i < len - 2; j += 3, i += 4)
	{
		out[i] = base64_table[str[j] >> 2]; //取出第一个字符的前6位并找出对应的结果字符
		out[i + 1] = base64_table[(str[j] & 0x3) << 4 | (str[j + 1] >> 4)]; //将第一个字符的后位与第二个字符的前4位进行组合并找到对应的结果字符
		out[i + 2] = base64_table[(str[j + 1] & 0xf) << 2 | (str[j + 2] >> 6)]; //将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符
		out[i + 3] = base64_table[str[j + 2] & 0x3f]; //取出第三个字符的后6位并找出结果字符
	}

	switch (str_len % 3)
	{
	case 1:
		out[i - 2] = '=';
		out[i - 1] = '=';
		break;
	case 2:
		out[i - 1] = '=';
		break;
	}

	return len;
}

int base64_decode(const char* code, uint32_t inLen, unsigned char* out, unsigned int outBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	//根据base64表，以字符找到对应的十进制数据
	int table[] = { 0,0,0,0,0,0,0,0,0,0,0,0,
			 0,0,0,0,0,0,0,0,0,0,0,0,
			 0,0,0,0,0,0,0,0,0,0,0,0,
			 0,0,0,0,0,0,0,62,0,0,0,
			 63,52,53,54,55,56,57,58,
			 59,60,61,0,0,0,0,0,0,0,0,
			 1,2,3,4,5,6,7,8,9,10,11,12,
			 13,14,15,16,17,18,19,20,21,
			 22,23,24,25,0,0,0,0,0,0,26,
			 27,28,29,30,31,32,33,34,35,
			 36,37,38,39,40,41,42,43,44,
			 45,46,47,48,49,50,51
	};
	unsigned int str_len;
	//判断编码后的字符串后是否有=
	if (strstr(code, "=="))
		str_len = inLen / 4 * 3 - 2;
	else if (strstr(code, "="))
		str_len = inLen / 4 * 3 - 1;
	else
		str_len = inLen / 4 * 3;

	if (outBufferSize < str_len) {
		Tracer::error("bae64_decode", "buffer size too small");
		return -1;
	}

	//以4个字符为一位进行解码
	for (uint32_t i = 0, j = 0; i < inLen - 2; j += 3, i += 4)
	{
		out[j] = ((unsigned char)table[code[i]]) << 2 | (((unsigned char)table[code[i + 1]]) >> 4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的后2位进行组合
		out[j + 1] = (((unsigned char)table[code[i + 1]]) << 4) | (((unsigned char)table[code[i + 2]]) >> 2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应bas464表的十进制数的后4位进行组合
		out[j + 2] = (((unsigned char)table[code[i + 2]]) << 6) | ((unsigned char)table[code[i + 3]]); //取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合
	}

	return str_len;
}
uint32_t calcKey(uint8_t* inBuffer, int inLen)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	uint8_t v2[4] = { 0 };
	int v3;
	signed int v4;
	int v5;
	signed int v6;
	signed int v7;
	int v8;
	int v9;
	char v10;
	uint32_t result = 0;
	uint8_t* v12;

	v12 = inBuffer;
	v3 = 0xC541A9;
	v4 = 0;
	do
	{
		v5 = (uint8_t)v12[v4];
		v6 = 0;
		do
		{
			v7 = 0;
			if (v5 << 31 != v3 << 31)
			{
				v3 |= 0x1000000u;
				v7 = 1085480;
			}
			v5 = v5 >> 1;
			v8 = ((v3 >> 1) ^ v7) & 0x109028;
			v9 = v3 >> 1;
			v3 = (v9 & 0xFFEF6FD7 | v8) & 0xFFFFFF;
			++v6;
		} while (v6 < 8);
		++v4;
	} while (v4 < 8);

	v2[0] = ((v9 & 0xFFEF6FD7 | v8) & 0xFFFFFF) >> 4;
	v10 = (v3 >> 20) & 0xF;
	v2[1] = ((v3 >> 8) & 0xF0) + v10;
	result = ((v3 >> 16) & 0xF) + 16 * v3;
	v2[2] = result;
	result = ((((v9 & 0xFFEF6FD7 | v8) & 0xFFFFFF) >> 4) & 0xFF) << 16 | ((((v3 >> 8) & 0xF0) + ((v3 >> 20) & 0xF)) & 0xFF) << 8 | (result & 0xFF);
	result = v2[0] << 16 | v2[1] << 8 | v2[2];

	return result;
}

int seedToKey(uint8_t* binSeed, int seedLen, uint8_t* binMask, int maskLen, uint8_t* outBuffer, int ourBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	int sumLen = seedLen + maskLen;
	if (sumLen >= 1024) {
		Tracer::error("internal err", "need buffer size: " + to_string(sumLen));
		return -1;
	}
	uint8_t tempBuffer[1024] = { 0 };

	memcpy(tempBuffer, binSeed, seedLen);
	memcpy(tempBuffer + seedLen, binMask, maskLen);
	uint32_t dwKey = calcKey(tempBuffer, seedLen + maskLen);
	if (ourBufferSize < 3) {
		return -1;
	}
	outBuffer[0] = (dwKey >> 16) & 0xFF;
	outBuffer[1] = (dwKey >> 8) & 0xFF;
	outBuffer[2] = (dwKey >> 0) & 0xFF;

	return 3;
}

int ver_calc(int iType, uint8_t* inParams, int inLen, char* outBuffer, int outBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	string tempString;
	switch (iType)
	{
	case 1://5 BYTE BCD +3 BYTE ASCII
	{
		char tempBuffer[32] = { 0 };
		sprintf(tempBuffer, "%02X%02X%02X%02X%02X%c%c%c", inParams[3], inParams[4], inParams[5], inParams[6], inParams[7], inParams[8], inParams[9], inParams[10]);
		tempString = tempBuffer;
		break;
	}

	case 2://HEX
	{
		for (int i = 0; i < inLen; i++)
		{
			char tempBuffer[4] = { 0 };
			sprintf(tempBuffer, "%02X", inParams[i]);
			tempString.append(tempBuffer);
		}
		break;
	}

	case 4://ASCII码
	{
		for (int i = 0; i < inLen; i++)
		{
			if ((inParams[i] == 0) || (inParams[i] == 0xFF))
			{
				break;
			}
			tempString += inParams[i];
		}
		break;
	}

	case 5://5 BYTE BCD +3 BYTE ASCII
	{
		uint8_t binTem00[10] = "\x00\x00\x00\x00\x00\x00\x00\x00";
		uint8_t binTemFF[10] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";

		//过滤异常命令
		if (0 == memcmp(inParams, binTem00, 8) || 0 == memcmp(inParams, binTemFF, 8))
		{
			return -1;
		}

		char tempBuffer[32] = { 0 };
		sprintf(tempBuffer, "%02X%02X%02X%02X%02X%c%c%c", inParams[0], inParams[1], inParams[2], inParams[3], inParams[4], inParams[5], inParams[6], inParams[7]);
		tempString = tempBuffer;
		break;
	}

	case 6:// 1 + N*13, ASCII码输出
	{
		int nGroupCnt = inParams[3];
		if (inLen != (nGroupCnt * 13 + 4))
		{
			return -1;
		}

		for (int i = 0; i < nGroupCnt; i++)
		{
			for (int j = 0; j < 13; j++)
			{
				tempString += inParams[4 + j + i * 13];
			}
			if (i < nGroupCnt - 1)
			{
				tempString += ",";
			}
		}
		break;
	}

	default:
		Tracer::error("invalid iType: ", to_string(iType));
		return -1;
	}

	if (tempString.length() > outBufferSize) {
		return -1;
	}
	memset(outBuffer, 0, outBufferSize);

	for (size_t i = 0; i < tempString.length(); ++i)
	{
		if ((tempString[i] >= 0x2D && tempString[i] <= 0x7A) || tempString[i] == 0x20)//超出这个范围的，不做计算
		{
			outBuffer[i] = tempString[i];
		}
	}

	return (int)tempString.length();
}

int ext_printf(char* outBuffer, unsigned int outBufferSize, char* format, ...)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);
	memset(outBuffer, 0, outBufferSize);

	va_list arg;
	va_start(arg, format);
	int rLen = vsnprintf(outBuffer, outBufferSize, format, arg);
	va_end(arg);

	return rLen;
}

int ext_strcmp(char* str1, char* str2)
{
	return strcmp(str1, str2);
}

int ext_strncmp(char* str1, char* str2, int maxCount)
{
	return strncmp(str1, str2, maxCount);
}

int ext_replace(const char* src, const char* strOld, const char* strNew, char* outBuffer, unsigned int outBufferSize)
{
	string tempString = src;
	MyStringUtils::replace(tempString, strOld, strNew);

	if (outBufferSize > tempString.size()) {
		memset(outBuffer, 0, outBufferSize);
		memcpy(outBuffer, tempString.c_str(), tempString.length());
		return tempString.length();
	}
	return -1;
}

int aes_cipher(unsigned char* input, int inLen, unsigned char* key, unsigned char* outBuffer) {
	AES aes(key);
	unsigned char tempBuffer[16] = { 0 };
	for (int i = 0; i < (inLen <= 16 ? inLen : 16); i++) {
		tempBuffer[i] = input[i];
	}
	aes.Cipher(tempBuffer);
	memcpy(outBuffer, tempBuffer, 16);
	return 16;
}

int radix_hex2Array(const char* hex, int hexLen, uint8_t* outBuffer, int outBufferSize) {
	std::lock_guard<std::recursive_mutex> lk(m_mutex);
	if (hexLen < 0 || (outBufferSize < hexLen / 2)) {
		return -1;
	}

	if (0 == strncmp(hex, "0x", 2) || 0 == strncmp(hex, "0X", 2)) {
		hexLen -= 2;
		memmove((void*)(hex), hex + 2, hexLen);
	}

	char* newHexBuffer = (char*)malloc(hexLen + 2);
	memset(newHexBuffer, 0, hexLen + 2);
	if (hexLen % 2 != 0) {
		hexLen += 1;
		newHexBuffer[0] = '0';
		strncpy(newHexBuffer + 1, hex, hexLen);
	}
	else {
		strncpy(newHexBuffer, hex, hexLen);
	}

	memset(outBuffer, 0, outBufferSize);
	for (size_t i = 0; i < hexLen; i += 2)
	{
		uint8_t highByte = toupper(newHexBuffer[i]);
		uint8_t lowByte = toupper(newHexBuffer[i + 1]);

		if (highByte >= 'A' && highByte <= 'F')
			highByte = highByte - 'A' + 10;
		else if (highByte >= '0' && highByte <= '9')
			highByte = highByte - '0';
		else {
			free(newHexBuffer);
			return -1;
		}

		if (lowByte >= 'A' && lowByte <= 'F')
			lowByte = lowByte - 'A' + 10;
		else if (lowByte >= '0' && lowByte <= '9')
			lowByte = lowByte - '0';
		else {
			free(newHexBuffer);
			return -1;
		}

		outBuffer[i / 2] = (highByte << 4) | lowByte;
	}


	free(newHexBuffer);
	return hexLen / 2;
}

int radix_array2Hex(uint8_t* inParams, int inLen, char* outBuffer, int outBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	if (outBufferSize < inLen * 2) {
		return -1;
	}

	for (size_t i = 0; i < inLen; i++)
	{
		uint8_t highByte = inParams[i] >> 4;
		uint8_t lowByte = inParams[i] & 0x0F;

		if (highByte >= 0x0A && highByte <= 0x0F)
			outBuffer[2 * i] = 'A' + highByte - 10;
		else if (highByte >= 0x00 && highByte <= 0x09)
			outBuffer[2 * i] = '0' + highByte;
		else {
			return -1;
		}

		if (lowByte >= 0x0A && lowByte <= 0x0F)
			outBuffer[2 * i + 1] = 'A' + lowByte - 10;
		else if (lowByte >= 0x00 && lowByte <= 0x09)
			outBuffer[2 * i + 1] = '0' + lowByte;
		else {
			return -1;
		}
	}

	return int();
}

int radix_array2Uint32(uint8_t* inParams, int inLen)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	uint32_t rVal = 0;
	if (inLen >= 4) {

		rVal += (inParams[0] << 24);
		rVal += (inParams[1] << 16);
		rVal += (inParams[2] << 8);
		rVal += (inParams[3] << 0);
		return rVal;
	}
	else {
		for (int i = 0; i < inLen; i++) {
			if (i >= 1) {
				rVal = rVal << 8;
			}
			rVal += inParams[i];
		}
		return rVal;
	}
}

int radix_hex2Integer(char* hex, int radix)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	try {
		string src = hex;
		return MyStringUtils::toLong(src, radix);
	}
	catch (exception e) {
		Tracer::error("radix_hex2Integer", e.what());
	}
	return -1;
}

int radix_string2Integer(char* inParams, int radix)
{
	string src = inParams;

	return MyStringUtils::toLong(src, radix);
}

int radix_int2ByteArray(uint32_t val, uint8_t* outBuffer, int outBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	if (outBufferSize >= 4) {

		outBuffer[0] = (val >> 24) & 0xFF;
		outBuffer[1] = (val >> 16) & 0xFF;
		outBuffer[2] = (val >> 8) & 0xFF;
		outBuffer[3] = (val >> 0) & 0xFF;
		return 4;
	}

	return -1;
}

int radix_decimalStringToHex(char* inParams, char* outBuffer, int outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);
	long long decimalValue = std::stoll(inParams, nullptr, 10);

	std::stringstream ss;
	ss << std::hex << std::uppercase << decimalValue;
	string tempString = ss.str();
	if (outBufferSize > tempString.length())
	{
		memcpy(outBuffer, tempString.c_str(), tempString.length());
		return tempString.length();
	}
	return -1;
}

int appendBytefield(uint8_t* inParams_1, int inLen_1, uint8_t* inParams_2, int inLen_2, uint8_t* outBuffer, int outBufferSize)
{
	memcpy(outBuffer, inParams_1, inLen_1);
	memcpy(outBuffer + inLen_1, inParams_2, inLen_2);
	return inLen_1 + inLen_2;
}


int sendCAData(uint8_t* binGetPKI, int iLen, uint8_t bKeyId, uint8_t* outBuffer, int outBufferSize)
{
	std::lock_guard<std::recursive_mutex> lk(m_mutex);

	if (outBufferSize < 2044 + 5) {
		return -1;
	}

	memcpy(outBuffer, binGetPKI, iLen);
	for (int i = iLen; i < 2044; i++)
	{
		outBuffer[i] = 0xFF;
	}

	unsigned short uCRC16 = crc16_ibm(outBuffer, 2044);
	outBuffer[2044] = (uCRC16 >> 8) & 0xFF;
	outBuffer[2044 + 1] = uCRC16 & 0xFF;

	memmove(outBuffer + 3, outBuffer, 2044 + 2);

	outBuffer[0] = bKeyId;
	outBuffer[1] = (iLen >> 8) & 0xFF;
	outBuffer[2] = iLen & 0xFF;

	return 2044 + 5;
}

/***************************************************************
* 函数: 将P12证书导出为pem格式的证书
* 参数: p12Path P12证书的路径
* 参数：pemBuffer 接收pem证书的buffer
* 参数: passwd P12证书的密码
* 返回: 0，成功
/***************************************************************/
int parse_cert_p12(char* p12Path, char* passwd, char* pemBuffer, char* keyBuffer)
{
	EVP_PKEY* pkey = NULL;
	X509* cert = NULL;
	STACK_OF(X509)* ca = NULL;
	PKCS12* p12 = NULL;
	int ret = EXIT_FAILURE;

	BIO* in = BIO_new(BIO_s_file());
	BIO_read_filename(in, p12Path);
	d2i_PKCS12_bio(in, &p12);
	BIO_free(in);

	if (p12 == NULL) {
		fprintf(stderr, "Error reading PKCS#12 file\n");
		ERR_print_errors_fp(stderr);

		X509_free(cert);
		EVP_PKEY_free(pkey);
		sk_X509_pop_free(ca, X509_free);

		return ret;
	}

	if (!PKCS12_parse(p12, passwd, &pkey, &cert, &ca)) {
		fprintf(stderr, "Error parsing PKCS#12 file\n");
		ERR_print_errors_fp(stderr);

		X509_free(cert);
		EVP_PKEY_free(pkey);
		sk_X509_pop_free(ca, X509_free);

		return ret;
	}
	PKCS12_free(p12);
	if (cert != NULL) {
		BIO* bio = BIO_new(BIO_s_mem());
		PEM_write_bio_X509(bio, cert);
		BUF_MEM* buffer;
		BIO_get_mem_ptr(bio, &buffer);
		memcpy(pemBuffer, buffer->data, buffer->length);
		BIO_free(bio);

		//FILE* fp = fopen("temp.pem", "w");
		//fwrite(pemBuffer, 1, strlen(pemBuffer), fp);
		//fclose(fp);
	}
	if (pkey != NULL) {
		BIO* bio = BIO_new(BIO_s_mem());
		PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL);

		BUF_MEM* buffer;
		BIO_get_mem_ptr(bio, &buffer);
		memcpy(keyBuffer, buffer->data, buffer->length);
		BIO_free(bio);

		//FILE* fp = fopen("temp.key", "w");
		//fwrite(keyBuffer, 1, strlen(keyBuffer), fp);
		//fclose(fp);
	}

	ret = EXIT_SUCCESS;
	return ret;
}

//TODO 计算售后代理服务的签名
bool ecdsa_signature(string msg, string key, string& signature) {
	BIO* in = BIO_new_mem_buf(key.c_str(), -1);
	EC_KEY* ekey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL);
	BIO_free(in);

	unsigned char hash[SHA256_DIGEST_LENGTH];
	SHA256((uint8_t*)msg.c_str(), msg.length(), hash);

	uint32_t sig_len = 0;
	uint8_t sig[128] = { 0 };
	ECDSA_sign(0, hash, SHA256_DIGEST_LENGTH, sig, &sig_len, ekey);

	char oBuffer[128] = { 0 };
	base64_encode(sig, sig_len, oBuffer, 128);
	signature = std::string(oBuffer);

	return true;
}

int getUUID(char* outBuffer, int outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);
	sole::uuid u4 = sole::uuid4();
	string guid = u4.str();
	guid.erase(std::remove(guid.begin(), guid.end(), '-'), guid.end());

	if (outBufferSize > guid.size()) {

		memcpy(outBuffer, guid.c_str(), guid.length());
		return guid.size();
	}
	return -1;
}

int pow_calc(int base, int exponent, char* outBuffer, int outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	long result = (long)pow(base, exponent) - 1;
	string tempString = std::to_string(result);
	if (outBufferSize > tempString.length()) {
		memcpy(outBuffer, tempString.c_str(), tempString.length());
		return tempString.length();
	}
	return -1;
}

int utf8toGbk(char* src, char* outBuffer, int outBufferSize)
{
	string strUTF8 = src;

	string strGbk = MyStringUtils::UTF8ToGBK(strUTF8);

	if (outBufferSize > strGbk.length()) {
		memcpy(outBuffer, strGbk.c_str(), strGbk.length());
		return strGbk.length();
	}

	return -1;
}
