Developing

This commit is contained in:
Oleg Korshul
2023-06-29 23:14:25 +03:00
parent bf6d4b00e3
commit 571a6f897b
10 changed files with 833 additions and 21 deletions

View File

@ -694,17 +694,14 @@ namespace NSOpenSSL
return key;
}
bool AES_Decrypt_desktop_GCM(const unsigned char* key, const std::string& input, std::string& output, const int header_offset)
bool AES_Decrypt_desktop_GCM(const unsigned char* key, const unsigned char* input, const int& input_len, CMemoryData& buffer)
{
unsigned char* input_ptr = NULL;
int input_ptr_len = 0;
bool bBase64 = NSFile::CBase64Converter::Decode(input.c_str() + header_offset, (int)input.length() - header_offset, input_ptr, input_ptr_len);
if (!bBase64)
return false;
const unsigned char* input_ptr = input;
int input_ptr_len = input_len;
unsigned char* iv_ptr = input_ptr;
unsigned char* tag_ptr = input_ptr + GCM_IV_LENGTH;
unsigned char* ciphertext_ptr = tag_ptr + GCM_TAG_LENGHT;
const unsigned char* iv_ptr = input_ptr;
const unsigned char* tag_ptr = input_ptr + GCM_IV_LENGTH;
const unsigned char* ciphertext_ptr = tag_ptr + GCM_TAG_LENGHT;
int ciphertext_len = input_ptr_len - (GCM_IV_LENGTH + GCM_TAG_LENGHT);
unsigned char* output_ptr = NULL;
int output_len = 0;
@ -729,7 +726,7 @@ namespace NSOpenSSL
if (!EVP_DecryptUpdate(ctx, output_ptr, &output_len, ciphertext_ptr, ciphertext_len))
goto end;
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, GCM_TAG_LENGHT, tag_ptr))
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, GCM_TAG_LENGHT, (void*)tag_ptr))
goto end;
if (EVP_DecryptFinal_ex(ctx, output_ptr + output_len, &final_len))
@ -739,24 +736,44 @@ namespace NSOpenSSL
}
end:
RELEASEARRAYOBJECTS(input_ptr);
if (ctx)
EVP_CIPHER_CTX_free(ctx);
if (bResult)
{
output = std::string((char*)output_ptr, output_len);
buffer.Data = output_ptr;
buffer.Size = output_len;
}
if (output_ptr)
else
openssl_free(output_ptr);
return bResult;
}
bool AES_Encrypt_desktop_GCM(const unsigned char* key, const std::string& input, std::string& output)
bool AES_Decrypt_desktop_GCM(const unsigned char* key, const std::string& input, std::string& output, const int header_offset)
{
const unsigned char* input_ptr = (const unsigned char*)input.c_str();
int input_len = (int)input.length();
unsigned char* input_ptr = NULL;
int input_ptr_len = 0;
bool bBase64 = NSFile::CBase64Converter::Decode(input.c_str() + header_offset, (int)input.length() - header_offset, input_ptr, input_ptr_len);
if (!bBase64)
return false;
CMemoryData oBuffer;
bool bResult = AES_Decrypt_desktop_GCM(key, input_ptr, input_ptr_len, oBuffer);
RELEASEARRAYOBJECTS(input_ptr);
if (bResult)
{
output = std::string((char*)oBuffer.Data, oBuffer.Size);
}
return bResult;
}
bool AES_Encrypt_desktop_GCM(const unsigned char* key, const unsigned char* input, const int& input_len, CMemoryData& buffer)
{
const unsigned char* input_ptr = input;
int output_buffer_all_offset = GCM_IV_LENGTH + GCM_TAG_LENGHT;
int output_buffer_len = input_len + output_buffer_all_offset;
@ -807,12 +824,29 @@ end:
if (ctx)
EVP_CIPHER_CTX_free(ctx);
if (bResult)
{
buffer.Data = output_ptr;
buffer.Size = (size_t)(ciphertext_len + output_buffer_all_offset);
}
else
{
openssl_free(output_ptr);
}
return bResult;
}
bool AES_Encrypt_desktop_GCM(const unsigned char* key, const std::string& input, std::string& output)
{
CMemoryData buffer;
bool bResult = AES_Encrypt_desktop_GCM(key, (const unsigned char*)input.c_str(), (int)input.length(), buffer);
if (bResult)
{
// header + base64
char* pDataDst = NULL;
int nDataDst = 0;
NSFile::CBase64Converter::Encode(output_ptr, ciphertext_len + output_buffer_all_offset, pDataDst, nDataDst, NSBase64::B64_BASE64_FLAG_NOCRLF);
NSFile::CBase64Converter::Encode(buffer.Data, (int)buffer.Size, pDataDst, nDataDst, NSBase64::B64_BASE64_FLAG_NOCRLF);
output = "";
output.reserve(g_aes_header.length() + (size_t)nDataDst + 1);
output.append(g_aes_header);
@ -820,9 +854,6 @@ end:
RELEASEARRAYOBJECTS(pDataDst);
}
if (output_ptr)
openssl_free(output_ptr);
return bResult;
}

View File

@ -110,8 +110,11 @@ namespace NSOpenSSL
// GCM
OPENSSL_DECL unsigned char* PBKDF2_desktop_GCM(const std::string& pass, const std::string& salt = "");
OPENSSL_DECL bool AES_Decrypt_desktop_GCM(const unsigned char* key, const unsigned char* input, const int& input_len, CMemoryData& buffer);
OPENSSL_DECL bool AES_Decrypt_desktop_GCM(const unsigned char* key, const std::string& input, std::string& output, const int header_offset = 0);
OPENSSL_DECL bool AES_Decrypt_desktop_GCM(const std::string& pass, const std::string& input, std::string& output, const std::string& salt = "", const int header_offset = 0);
OPENSSL_DECL bool AES_Encrypt_desktop_GCM(const unsigned char* key, const unsigned char* input, const int& input_len, CMemoryData& buffer);
OPENSSL_DECL bool AES_Encrypt_desktop_GCM(const unsigned char* key, const std::string& input, std::string& output);
OPENSSL_DECL bool AES_Encrypt_desktop_GCM(const std::string& pass, const std::string& input, std::string& output, const std::string& salt = "");
}

View File

@ -0,0 +1,119 @@
#ifndef _OSIGN_H_
#define _OSIGN_H_
#include <stddef.h>
#include <string>
#include <vector>
#include <map>
#include "../../../../../common/base_export.h"
#ifdef OSIGN_BUILDING_INTERNAL
#define OSIGN_DECL
#else
#ifdef OSIGN_BUILDING
#define OSIGN_DECL Q_DECL_EXPORT
#else
#define OSIGN_DECL Q_DECL_IMPORT
#endif
#endif
namespace OSign
{
class CStorageBuffer_private;
class OSIGN_DECL CStorageBuffer
{
public:
CStorageBuffer();
CStorageBuffer(const CStorageBuffer& src);
~CStorageBuffer();
public:
unsigned char* GetData();
unsigned char* GetData() const;
size_t GetLength() const;
unsigned char* GetCurrentData();
unsigned char* GetCurrentData() const;
void Alloc(const size_t& size);
void CheckAlloc(const size_t& size);
void Free();
void FreeNoAttack();
bool Save(const std::wstring& filePath);
bool Load(const std::wstring& filePath);
std::string ToBase64();
bool FromBase64(const std::string& base64);
// write
void AddInt(const size_t& size);
void Add(const unsigned char* data, const size_t& size);
void Add(const CStorageBuffer* buffer);
// read
void Seek(const size_t& pos);
void Skip(const size_t& size);
unsigned char* ReadData(const size_t& size);
int ReadInt();
void LoadExternal(unsigned char* data, size_t len);
private:
CStorageBuffer_private* m_internal;
};
class CCertificate_private;
class OSIGN_DECL CCertificate
{
public:
CCertificate();
CCertificate(const std::map<std::wstring, std::wstring>& props);
~CCertificate();
public:
std::map<std::wstring, std::wstring> GetProperties();
bool Load(CStorageBuffer* buffer);
bool Save(CStorageBuffer* buffer);
CStorageBuffer Sign(const CStorageBuffer& data);
bool Verify(const CStorageBuffer& data, const CStorageBuffer& signature);
private:
CCertificate_private* m_internal;
};
class CStorage_private;
class OSIGN_DECL CStorage
{
public:
CStorage();
~CStorage();
public:
int GetCount();
CCertificate* Get(const int& index);
void Add(CCertificate* cert);
bool Load(CStorageBuffer* buffer);
bool Save(CStorageBuffer* buffer);
private:
CStorage_private* m_internal;
};
namespace Crypt
{
OSIGN_DECL CStorageBuffer GeneratePassword(const size_t& size = 32);
// version;salt;encoded_buffer
OSIGN_DECL CStorageBuffer Encrypt(CStorageBuffer& buffer, CStorageBuffer& password);
OSIGN_DECL CStorageBuffer Decrypt(CStorageBuffer& buffer, CStorageBuffer& password);
}
}
#endif // _XMLSIGNER_OFORM_H_

View File

@ -0,0 +1,58 @@
QT -= core
QT -= gui
VERSION = 1.0.0.1
TARGET = osign
TEMPLATE = lib
CONFIG += shared
CONFIG += plugin
CORE_ROOT_DIR = $$PWD/../../../../..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
DEFINES += OSIGN_BUILDING
HEADERS += \
include/osign.h
HEADERS += \
src/utils.h
SOURCES += \
src/buffer.cpp \
src/storage.cpp \
src/certificate.cpp
core_windows {
LIBS += -lcrypt32
LIBS += -lcryptui
LIBS += -lAdvapi32
LIBS += -lws2_32
LIBS += -lUser32
}
DEFINES += SUPPORT_OPENSSL
HEADERS += src/Certificate_openssl.h
support_oform {
DEFINES += SUPPORT_OFORM
HEADERS += src/Certificate_oform.h
}
CONFIG += open_ssl_common
include($$CORE_ROOT_DIR/Common/3dParty/openssl/openssl.pri)
# KERNEL ---
DEFINES += KERNEL_NO_USE_DYNAMIC_LIBRARY
# BASE64
HEADERS += $$CORE_ROOT_DIR/DesktopEditor/common/Base64.h
SOURCES += $$CORE_ROOT_DIR/DesktopEditor/common/Base64.cpp
# FILE
HEADERS += $$CORE_ROOT_DIR/DesktopEditor/common/File.h
SOURCES += $$CORE_ROOT_DIR/DesktopEditor/common/File.cpp
# ----------
build_xp:DESTDIR=$$DESTDIR/xp

View File

@ -0,0 +1,328 @@
#include "../include/osign.h"
#include "./utils.h"
#include <memory>
namespace OSign
{
class CMemory
{
public:
unsigned char* m_data = nullptr;
size_t m_max_size = 0;
size_t m_size = 0;
bool m_external = false;
public:
CMemory()
{
}
~CMemory()
{
Destroy();
}
void Clear()
{
m_data = nullptr;
m_max_size = 0;
m_size = 0;
m_external = false;
}
void Destroy()
{
if (nullptr != m_data && !m_external)
free(m_data);
Clear();
}
void Attach(unsigned char* data, const size_t& size)
{
m_data = data;
m_max_size = size;
m_size = size;
m_external = true;
}
void AddSize(size_t size)
{
if (m_external)
return;
if (nullptr == m_data)
{
m_max_size = (std::max)((int)size, 1000);
m_data = (unsigned char*)malloc(m_max_size * sizeof(unsigned char));
m_size = 0;
return;
}
if ((m_size + size) > m_max_size)
{
while ((m_size + size) > m_max_size)
{
if (m_max_size > 10485760/*10 * 1024 * 1024*/)
{
m_max_size += (std::max)((int)size * 10, 1048576/*1024 * 1024*/);
}
else
{
m_max_size *= 2;
}
}
unsigned char* pRealloc = (unsigned char*)realloc(m_data, m_max_size * sizeof(unsigned char));
if (NULL != pRealloc)
{
// реаллок сработал
m_data = pRealloc;
}
else
{
unsigned char* pMalloc = (unsigned char*)malloc(m_max_size * sizeof(unsigned char));
memcpy(pMalloc, m_data, m_size * sizeof(char));
free(m_data);
m_data = pMalloc;
}
}
}
};
class CStorageBuffer_private
{
public:
std::shared_ptr<CMemory> m_data;
size_t m_pos = 0;
public:
CStorageBuffer_private()
{
}
~CStorageBuffer_private()
{
Destroy();
}
void Destroy()
{
m_data.reset();
}
void AddSize(size_t size)
{
if (!m_data)
m_data = std::make_shared<CMemory>();
m_data->AddSize(size);
}
};
CStorageBuffer::CStorageBuffer()
{
m_internal = new CStorageBuffer_private();
}
CStorageBuffer::CStorageBuffer(const CStorageBuffer& src)
{
m_internal = new CStorageBuffer_private();
m_internal->m_data = src.m_internal->m_data;
// всегда сначала
m_internal->m_pos = 0;
}
CStorageBuffer::~CStorageBuffer()
{
delete m_internal;
}
unsigned char* CStorageBuffer::GetData()
{
if (m_internal->m_data)
return m_internal->m_data->m_data;
return nullptr;
}
unsigned char* CStorageBuffer::GetData() const
{
if (m_internal->m_data)
return m_internal->m_data->m_data;
return nullptr;
}
unsigned char* CStorageBuffer::GetCurrentData()
{
if (m_internal->m_data)
return m_internal->m_data->m_data + m_internal->m_data->m_size;
return nullptr;
}
unsigned char* CStorageBuffer::GetCurrentData() const
{
if (m_internal->m_data)
return m_internal->m_data->m_data + m_internal->m_data->m_size;
return nullptr;
}
size_t CStorageBuffer::GetLength() const
{
if (m_internal->m_data)
return m_internal->m_data->m_size;
return 0;
}
void CStorageBuffer::Alloc(const size_t& size)
{
m_internal->Destroy();
m_internal->AddSize(size);
}
void CStorageBuffer::CheckAlloc(const size_t& size)
{
m_internal->AddSize(size);
}
void CStorageBuffer::Free()
{
m_internal->Destroy();
}
void CStorageBuffer::FreeNoAttack()
{
if (m_internal->m_data)
m_internal->m_data->m_size = 0;
}
bool CStorageBuffer::Save(const std::wstring& filePath)
{
if (!m_internal->m_data && 0 == m_internal->m_data->m_size)
return false;
NSFile::CFileBinary oFile;
if (!oFile.CreateFile(filePath))
return false;
bool bRes = oFile.WriteFile(m_internal->m_data->m_data, (DWORD)m_internal->m_data->m_size);
oFile.CloseFile();
return bRes;
}
bool CStorageBuffer::Load(const std::wstring& filePath)
{
m_internal->Destroy();
NSFile::CFileBinary oFile;
if (!oFile.OpenFile(filePath))
return false;
size_t size = (size_t)oFile.GetFileSize();
m_internal->AddSize(size);
bool bRes = oFile.ReadFile(m_internal->m_data->m_data, (DWORD)size);
if (!bRes)
m_internal->Destroy();
else
m_internal->m_data->m_size = size;
return bRes;
}
std::string CStorageBuffer::ToBase64()
{
if (!m_internal->m_data && 0 == m_internal->m_data->m_size)
return "";
int nLenDst = NSBase64::Base64EncodeGetRequiredLength((int)m_internal->m_data->m_size, NSBase64::B64_BASE64_FLAG_NOCRLF);
char* pDataDst = new char[nLenDst];
if (FALSE == NSBase64::Base64Encode(m_internal->m_data->m_data, (int)m_internal->m_data->m_size, (BYTE*)pDataDst, &nLenDst, NSBase64::B64_BASE64_FLAG_NOCRLF))
{
RELEASEARRAYOBJECTS(pDataDst);
return "";
}
std::string sRes(pDataDst, nLenDst);
RELEASEARRAYOBJECTS(pDataDst);
return sRes;
}
bool CStorageBuffer::FromBase64(const std::string& base64)
{
m_internal->Destroy();
m_internal->AddSize(base64.length());
int nLenDst = 0;
if (FALSE == NSBase64::Base64Decode(base64.c_str(), (int)base64.length(), m_internal->m_data->m_data, &nLenDst))
{
m_internal->Destroy();
return false;
}
m_internal->m_data->m_size = (size_t)nLenDst;
return true;
}
// WRITE
void CStorageBuffer::AddInt(const size_t& size)
{
m_internal->AddSize(4);
unsigned char* output = GetCurrentData();
output[0] = size & 0xFF;
output[1] = (size >> 8) & 0xFF;
output[2] = (size >> 16) & 0xFF;
output[3] = (size >> 24) & 0xFF;
m_internal->m_data->m_size += 4;
}
void CStorageBuffer::Add(const unsigned char* data, const size_t& size)
{
if (size == 0)
return;
m_internal->AddSize(size);
memcpy(GetCurrentData(), data, size);
m_internal->m_data->m_size += size;
}
void CStorageBuffer::Add(const CStorageBuffer* buffer)
{
if (buffer->GetLength() == 0)
return;
Add(buffer->m_internal->m_data->m_data, buffer->m_internal->m_data->m_size);
}
// READ
void CStorageBuffer::Skip(const size_t& size)
{
m_internal->m_pos += size;
}
void CStorageBuffer::Seek(const size_t& pos)
{
m_internal->m_pos = pos;
}
unsigned char* CStorageBuffer::ReadData(const size_t& size)
{
unsigned char* data = m_internal->m_data->m_data + m_internal->m_pos;
m_internal->m_pos += size;
return data;
}
int CStorageBuffer::ReadInt()
{
const unsigned char* data = m_internal->m_data->m_data + m_internal->m_pos;
m_internal->m_pos += 4;
return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
}
void CStorageBuffer::LoadExternal(unsigned char* data, size_t len)
{
m_internal->Destroy();
m_internal->m_data = std::make_shared<CMemory>();
m_internal->m_data->Attach(data, len);
m_internal->m_pos = 0;
}
}

View File

@ -0,0 +1,120 @@
#include "../include/osign.h"
#include "./utils.h"
#include "../../../../../../Common/3dParty/openssl/common/common_openssl.h"
#include <openssl/rand.h>
namespace OSign
{
class CCertificate_private
{
public:
CCertificate_private()
{
}
~CCertificate_private()
{
}
};
CCertificate::CCertificate()
{
m_internal = new CCertificate_private();
}
CCertificate::CCertificate(const std::map<std::wstring, std::wstring>& props)
{
m_internal = new CCertificate_private();
}
CCertificate::~CCertificate()
{
delete m_internal;
}
std::map<std::wstring, std::wstring> CCertificate::GetProperties()
{
std::map<std::wstring, std::wstring> props;
return props;
}
bool CCertificate::Load(CStorageBuffer* buffer)
{
return true;
}
bool CCertificate::Save(CStorageBuffer* buffer)
{
return true;
}
CStorageBuffer CCertificate::Sign(const CStorageBuffer& data)
{
CStorageBuffer buffer;
return buffer;
}
bool CCertificate::Verify(const CStorageBuffer& data, const CStorageBuffer& signature)
{
return false;
}
}
namespace OSign
{
namespace Crypt
{
CStorageBuffer GeneratePassword(const size_t& size)
{
CStorageBuffer buffer;
buffer.Alloc(size);
RAND_priv_bytes(buffer.GetData(), (int)size);
buffer.Skip(size);
return buffer;
}
// version;salt;encoded_buffer
CStorageBuffer Encrypt(CStorageBuffer& buffer, CStorageBuffer& password)
{
const int salt_len = 32;
unsigned char salt[salt_len];
RAND_bytes(salt, salt_len);
unsigned char* key = NSOpenSSL::PBKDF2((const char*)password.GetData(), (int)password.GetLength(), salt, salt_len, OPENSSL_HASH_ALG_SHA256, 32);
NSOpenSSL::CMemoryData oBufferData;
AES_Encrypt_desktop_GCM(key, buffer.GetData(), (int)buffer.GetLength(), oBufferData);
CStorageBuffer result;
result.CheckAlloc(4 + 4 + salt_len + 4 + oBufferData.Size);
result.AddInt(OSIGN_SHARE_VERSION);
result.AddInt(salt_len);
result.Add(salt, salt_len);
result.AddInt(oBufferData.Size);
result.Add(oBufferData.Data, oBufferData.Size);
result.Seek(0);
NSOpenSSL::openssl_free(key);
return result;
}
CStorageBuffer Decrypt(CStorageBuffer& buffer, CStorageBuffer& password)
{
int nVersion = buffer.ReadInt();
OSIGN_UNUSED(nVersion);
int salt_len = buffer.ReadInt();
unsigned char* salt = buffer.ReadData(salt_len);
int data_len = buffer.ReadInt();
unsigned char* key = NSOpenSSL::PBKDF2((const char*)password.GetData(), (int)password.GetLength(), salt, salt_len, OPENSSL_HASH_ALG_SHA256, 32);
NSOpenSSL::CMemoryData oBufferData;
NSOpenSSL::AES_Decrypt_desktop_GCM(key, buffer.ReadData(data_len), data_len, oBufferData);
CStorageBuffer result;
result.Alloc(oBufferData.Size);
result.Add(oBufferData.Data, oBufferData.Size);
NSOpenSSL::openssl_free(key);
return result;
}
}
}

View File

@ -0,0 +1,115 @@
#include "../include/osign.h"
#include "./utils.h"
#define OSIGN_STORAGE_VERSION 1
namespace OSign
{
class CStorage_private
{
public:
std::vector<CCertificate*> m_certs;
public:
CStorage_private()
{
}
~CStorage_private()
{
Destroy();
}
public:
void Destroy()
{
for (std::vector<CCertificate*>::const_iterator iter = m_certs.begin(); iter != m_certs.end(); iter++)
{
CCertificate* cert = *iter;
delete cert;
}
m_certs.clear();
}
};
CStorage::CStorage()
{
m_internal = new CStorage_private();
}
CStorage::~CStorage()
{
delete m_internal;
}
int CStorage::GetCount()
{
return (int)m_internal->m_certs.size();
}
CCertificate* CStorage::Get(const int& index)
{
if (0 > index || index >= GetCount())
return nullptr;
return m_internal->m_certs[index];
}
void CStorage::Add(CCertificate* cert)
{
m_internal->m_certs.push_back(cert);
}
bool CStorage::Load(CStorageBuffer* buffer)
{
size_t len = buffer->GetLength();
if (len < 4)
return false;
unsigned int nVersion = buffer->ReadInt();
OSIGN_UNUSED(nVersion);
unsigned int nCount = buffer->ReadInt();
CStorageBuffer oCertBuffer;
for (unsigned int i = 0; i < nCount; ++i)
{
int nLen = buffer->ReadInt();
oCertBuffer.LoadExternal(buffer->GetCurrentData(), 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;
}
bool CStorage::Save(CStorageBuffer* buffer)
{
buffer->CheckAlloc(1000);
buffer->AddInt(OSIGN_STORAGE_VERSION);
size_t nCount = m_internal->m_certs.size();
buffer->AddInt(nCount);
if (0 == nCount)
return true;
CStorageBuffer oBuffer;
oBuffer.Alloc(1000);
for (size_t i = 0; i < nCount; ++i)
{
oBuffer.FreeNoAttack();
if (m_internal->m_certs[i]->Save(&oBuffer))
{
buffer->AddInt(oBuffer.GetLength());
buffer->Add(&oBuffer);
}
}
return true;
}
}

View File

@ -0,0 +1,7 @@
#include <algorithm>
#include "../../../../../common/File.h"
#define OSIGN_STORAGE_VERSION 1
#define OSIGN_SHARE_VERSION 1
#define OSIGN_UNUSED( x ) (x) = (x)

View File

@ -0,0 +1,17 @@
#include "../lib/include/osign.h"
int main()
{
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());
OSign::CStorageBuffer oCryptBuffer = OSign::Crypt::Encrypt(oBuffer, oPassword);
OSign::CStorageBuffer oDecryptBuffer = OSign::Crypt::Decrypt(oCryptBuffer, oPassword);
std::string sDecryptData((char*)oDecryptBuffer.GetData(), oDecryptBuffer.GetLength());
return 0;
}

View File

@ -0,0 +1,14 @@
QT -= core gui
TARGET = test
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
CORE_ROOT_DIR = $$PWD/../../../../..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(osign)
SOURCES += main.cpp