Developing

This commit is contained in:
Oleg Korshul
2023-07-01 00:39:13 +03:00
parent 571a6f897b
commit 50e0538f06
6 changed files with 235 additions and 15 deletions

View File

@ -624,7 +624,7 @@ namespace NSFile
}
}
lOutputCount = pUnicodeString - pStart;
lOutputCount = (LONG)(pUnicodeString - pStart);
*pUnicodeString++ = 0;
}
void CUtf8Converter::GetUnicodeStringFromUTF8WithHHHH( const BYTE* pBuffer, LONG lCount, wchar_t*& pUnicodes, LONG& lOutputCount )

View File

@ -51,6 +51,7 @@ namespace OSign
void AddInt(const size_t& size);
void Add(const unsigned char* data, const size_t& size);
void Add(const CStorageBuffer* buffer);
void AddSkip(const size_t& size);
// read
void Seek(const size_t& pos);
@ -71,6 +72,7 @@ namespace OSign
CCertificate();
CCertificate(const std::map<std::wstring, std::wstring>& props);
~CCertificate();
void Generate();
public:
std::map<std::wstring, std::wstring> GetProperties();

View File

@ -248,10 +248,11 @@ namespace OSign
bool CStorageBuffer::FromBase64(const std::string& base64)
{
m_internal->Destroy();
m_internal->AddSize(base64.length());
int nLenDst = NSBase64::Base64DecodeGetRequiredLength((int)base64.length());
m_internal->Destroy();
m_internal->AddSize((size_t)nLenDst);
int nLenDst = 0;
if (FALSE == NSBase64::Base64Decode(base64.c_str(), (int)base64.length(), m_internal->m_data->m_data, &nLenDst))
{
m_internal->Destroy();
@ -293,6 +294,11 @@ namespace OSign
Add(buffer->m_internal->m_data->m_data, buffer->m_internal->m_data->m_size);
}
void CStorageBuffer::AddSkip(const size_t& size)
{
m_internal->m_data->m_size += size;
}
// READ
void CStorageBuffer::Skip(const size_t& size)
{

View File

@ -3,17 +3,92 @@
#include "../../../../../../Common/3dParty/openssl/common/common_openssl.h"
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/sha.h>
#include <openssl/ssl.h>
#include <openssl/crypto.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/conf.h>
#include <ctime>
namespace OSign
{
class CCertificate_private
{
public:
X509* m_cert = nullptr;
EVP_PKEY* m_key = nullptr;
public:
CCertificate_private()
{
}
~CCertificate_private()
{
Destroy();
}
void Destroy()
{
if (nullptr != m_cert)
X509_free(m_cert);
m_cert = nullptr;
if (NULL != m_key)
EVP_PKEY_free(m_key);
m_key = nullptr;
}
bool Create()
{
EVP_PKEY_CTX* pctx = nullptr;
const std::string& alg = "ed25519";
if (alg == "ed25519")
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
else if (alg == "x25519")
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
else
return false;
EVP_PKEY_keygen_init(pctx);
EVP_PKEY_keygen(pctx, &m_key);
EVP_PKEY_CTX_free(pctx);
m_cert = X509_new();
ASN1_INTEGER_set(X509_get_serialNumber(m_cert), 420);
X509_time_adj_ex(X509_getm_notBefore(m_cert), 0, 0, 0);
time_t exp;
time(&exp);
exp += 315360000;
X509_time_adj_ex(X509_getm_notAfter(m_cert), 0, 0, &exp);
if (X509_set_pubkey(m_cert, m_key) == 0)
{
EVP_PKEY_CTX_free(pctx);
Destroy();
return false;
}
if (false)
{
if (X509_sign(m_cert, m_key, EVP_sha512()) == 0)
{
EVP_PKEY_CTX_free(pctx);
Destroy();
return false;
}
}
EVP_PKEY_CTX_free(pctx);
return true;
}
};
@ -30,6 +105,11 @@ namespace OSign
delete m_internal;
}
void CCertificate::Generate()
{
m_internal->Create();
}
std::map<std::wstring, std::wstring> CCertificate::GetProperties()
{
std::map<std::wstring, std::wstring> props;
@ -38,21 +118,102 @@ namespace OSign
bool CCertificate::Load(CStorageBuffer* buffer)
{
int nLenCert = buffer->ReadInt();
unsigned char* pDataCert = buffer->ReadData((size_t)nLenCert);
int nLenKey = buffer->ReadInt();
unsigned char* pDataKey = buffer->ReadData((size_t)nLenKey);
BIO* bio = BIO_new_mem_buf((void*)pDataCert, (int)nLenCert);
if (!PEM_read_bio_X509(bio, &m_internal->m_cert, NULL, NULL))
{
BIO_free(bio);
return false;
}
BIO_free(bio);
bio = BIO_new_mem_buf((void*)pDataKey, (int)nLenKey);
if (!PEM_read_bio_PrivateKey(bio, &m_internal->m_key, NULL, NULL))
{
BIO_free(bio);
return false;
}
BIO_free(bio);
return true;
}
bool CCertificate::Save(CStorageBuffer* buffer)
{
if (!m_internal->m_cert || !m_internal->m_key)
return false;
if (true)
{
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_X509(bio, m_internal->m_cert);
BIO_flush(bio);
unsigned char* data = NULL;
int size = (int)BIO_get_mem_data(bio, &data);
buffer->AddInt(size);
buffer->Add(data, size);
BIO_free(bio);
}
if (true)
{
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(bio, m_internal->m_key, NULL, NULL, 0, 0, NULL);
BIO_flush(bio);
unsigned char* data = NULL;
int size = (int)BIO_get_mem_data(bio, &data);
buffer->AddInt(size);
buffer->Add(data, size);
BIO_free(bio);
}
return true;
}
CStorageBuffer CCertificate::Sign(const CStorageBuffer& data)
{
CStorageBuffer buffer;
if (!m_internal->m_cert || !m_internal->m_key)
return buffer;
//https://www.openssl.org/docs/manmaster/man7/Ed25519.html
EVP_MD_CTX* pCtx = EVP_MD_CTX_new();
EVP_DigestSignInit(pCtx, NULL, NULL, NULL, m_internal->m_key);
size_t nSize = data.GetLength();
/* Calculate the requires size for the signature by passing a NULL buffer */
size_t nSignatureLen = 0;
unsigned char* pData = data.GetData();
EVP_DigestSign(pCtx, NULL, &nSignatureLen, pData, (size_t)nSize);
buffer.CheckAlloc(nSignatureLen);
EVP_DigestSign(pCtx, buffer.GetData(), &nSignatureLen, pData, (size_t)nSize);
EVP_MD_CTX_free(pCtx);
buffer.AddSkip(nSignatureLen);
return buffer;
}
bool CCertificate::Verify(const CStorageBuffer& data, const CStorageBuffer& signature)
{
return false;
EVP_PKEY* pubkey = X509_get_pubkey(m_internal->m_cert);
EVP_MD_CTX* pCtx = EVP_MD_CTX_new();
EVP_DigestVerifyInit(pCtx, NULL, NULL, NULL, pubkey);
/* Calculate the requires size for the signature by passing a NULL buffer */
int nResult = EVP_DigestVerify(pCtx, signature.GetData(), signature.GetLength(), data.GetData(), data.GetLength());
EVP_MD_CTX_free(pCtx);
EVP_PKEY_free(pubkey);
return (1 == nResult) ? true : false;
}
}

View File

@ -76,15 +76,13 @@ namespace OSign
for (unsigned int i = 0; i < nCount; ++i)
{
int nLen = buffer->ReadInt();
oCertBuffer.LoadExternal(buffer->GetCurrentData(), nLen);
oCertBuffer.LoadExternal(buffer->ReadData((size_t)nLen), nLen);
CCertificate* pCert = new CCertificate();
if (pCert->Load(&oCertBuffer))
m_internal->m_certs.push_back(pCert);
else
delete pCert;
buffer->Skip((size_t)nLen);
}
return true;
}

View File

@ -2,16 +2,69 @@
int main()
{
OSign::CStorageBuffer oPassword = OSign::Crypt::GeneratePassword(100);
if (false)
{
// test crypt/decrypt
OSign::CStorageBuffer oPassword = OSign::Crypt::GeneratePassword(100);
std::string sDataCrypt = "Hello, world!";
OSign::CStorageBuffer oBuffer;
oBuffer.Add((const unsigned char*)sDataCrypt.c_str(), sDataCrypt.length());
std::string sDataCrypt = "Hello, world!";
OSign::CStorageBuffer oBuffer;
oBuffer.Add((const unsigned char*)sDataCrypt.c_str(), sDataCrypt.length());
OSign::CStorageBuffer oCryptBuffer = OSign::Crypt::Encrypt(oBuffer, oPassword);
OSign::CStorageBuffer oDecryptBuffer = OSign::Crypt::Decrypt(oCryptBuffer, oPassword);
OSign::CStorageBuffer oCryptBuffer = OSign::Crypt::Encrypt(oBuffer, oPassword);
OSign::CStorageBuffer oDecryptBuffer = OSign::Crypt::Decrypt(oCryptBuffer, oPassword);
std::string sDecryptData((char*)oDecryptBuffer.GetData(), oDecryptBuffer.GetLength());
std::string sDecryptData((char*)oDecryptBuffer.GetData(), oDecryptBuffer.GetLength());
return 0;
}
if (false)
{
// test serialize buffer
std::string sDataBuffer = "Hello, world!";
OSign::CStorageBuffer oBuffer;
oBuffer.Add((const unsigned char*)sDataBuffer.c_str(), sDataBuffer.length());
std::string sBase64 = oBuffer.ToBase64();
OSign::CStorageBuffer oDecodeBuffer;
oDecodeBuffer.FromBase64(sBase64);
std::string sDecryptData((char*)oDecodeBuffer.GetData(), oDecodeBuffer.GetLength());
return 0;
}
if (true)
{
OSign::CCertificate* pCert = new OSign::CCertificate();
pCert->Generate();
std::string sDataBuffer = "Hello, world!";
OSign::CStorageBuffer oBuffer;
oBuffer.Add((const unsigned char*)sDataBuffer.c_str(), sDataBuffer.length());
OSign::CStorageBuffer oBufferSign = pCert->Sign(oBuffer);
bool bIsValid = pCert->Verify(oBuffer, oBufferSign);
if (!bIsValid)
return 1;
OSign::CStorage oStorage;
oStorage.Add(pCert);
OSign::CStorageBuffer oStorageBuffer;
oStorage.Save(&oStorageBuffer);
OSign::CStorage oStorageLoad;
oStorageLoad.Load(&oStorageBuffer);
OSign::CCertificate* pCert2 = oStorage.Get(0);
bool bIsValid2 = pCert2->Verify(oBuffer, oBufferSign);
if (!bIsValid2)
return 1;
return 0;
}
return 0;
}