Merge remote-tracking branch 'origin/develop' into feature/pdfForms

# Conflicts:
#	DesktopEditor/xmlsec/src/src/Certificate_mscrypto.h
#	PdfFile/PdfFile.cpp
#	PdfFile/PdfFile.h
#	PdfFile/PdfReader.cpp
#	PdfFile/PdfReader.h
This commit is contained in:
Kulikova Svetlana
2023-07-27 16:55:09 +03:00
309 changed files with 36491 additions and 29047 deletions

View File

@ -1,19 +0,0 @@
SET SCRIPTPATH=%~dp0
CD /D %~dp0
call hg clone https://hg.mozilla.org/projects/nspr
call hg clone https://hg.mozilla.org/projects/nss
cd nss
export USE_64=1
make nss_build_all
git clone https://github.com/openssl/openssl.git openssl
cd openssl
perl ./Configure linux-64
./config
make
#call git clone -b master https://github.com/lsh123/xmlsec.git
#download from http://www.aleksey.com/xmlsec/download/xmlsec1-1.2.23.tar.gz
# get from our git repository

View File

@ -1,312 +0,0 @@
#-------------------------------------------------
#
# Project created by QtCreator 2014-10-10T14:24:04
#
#-------------------------------------------------
QT -= core gui
TARGET = libxmlsec
TEMPLATE = lib
QMAKE_CXXFLAGS += -Wall -g
#CONFIG += shared
#CONFIG += plugin
CONFIG += staticlib
CORE_ROOT_DIR = $$PWD/../..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
INCLUDEPATH += \
$$PWD_ROOT_DIR/xmlsec/include \
$$CORE_ROOT_DIR/DesktopEditor/xml/build/qt
DEFINES += \
LIBXML_READER_ENABLED \
LIBXML_PUSH_ENABLED \
LIBXML_HTML_ENABLED \
LIBXML_XPATH_ENABLED \
LIBXML_OUTPUT_ENABLED \
LIBXML_C14N_ENABLED \
LIBXML_SAX1_ENABLED \
LIBXML_TREE_ENABLED \
LIBXML_XPTR_ENABLED \
IN_LIBXML \
LIBXML_STATIC
include($$CORE_ROOT_DIR/DesktopEditor/xml/build/qt/libxml2_src.pri)
DEFINES += PACKAGE=\\\"xmlsec1\\\"
DEFINES += VERSION=\\\"1.2.23\\\"
DEFINES += XMLSEC_DEFAULT_CRYPTO=\\\"openssl\\\"
DEFINES += \
IN_XMLSEC \
XMLSEC_STATIC
core_linux {
#CONFIG += use_gcrypt
#CONFIG += use_gnutls
#CONFIG += use_mscrypto
#CONFIG += use_nss
CONFIG += use_openssl
#CONFIG += use_skeleton
#CONFIG += use_xslt
}
core_windows {
CONFIG += use_mscrypto
}
HEADERS += \
xmlsec/include/xmlsec/app.h \
xmlsec/include/xmlsec/base64.h \
xmlsec/include/xmlsec/bn.h \
xmlsec/include/xmlsec/buffer.h \
xmlsec/include/xmlsec/crypto.h \
xmlsec/include/xmlsec/dl.h \
xmlsec/include/xmlsec/errors.h \
xmlsec/include/xmlsec/exports.h \
xmlsec/include/xmlsec/io.h \
xmlsec/include/xmlsec/keyinfo.h \
xmlsec/include/xmlsec/keys.h \
xmlsec/include/xmlsec/keysdata.h \
xmlsec/include/xmlsec/keysmngr.h \
xmlsec/include/xmlsec/list.h \
xmlsec/include/xmlsec/membuf.h \
xmlsec/include/xmlsec/nodeset.h \
xmlsec/include/xmlsec/parser.h \
xmlsec/include/xmlsec/private.h \
xmlsec/include/xmlsec/soap.h \
xmlsec/include/xmlsec/strings.h \
xmlsec/include/xmlsec/templates.h \
xmlsec/include/xmlsec/transforms.h \
xmlsec/include/xmlsec/version.h \
xmlsec/include/xmlsec/version.h.in \
xmlsec/include/xmlsec/x509.h \
xmlsec/include/xmlsec/xmldsig.h \
xmlsec/include/xmlsec/xmlenc.h \
xmlsec/include/xmlsec/xmlsec.h \
xmlsec/include/xmlsec/xmltree.h \
xmlsec/src/globals.h \
xmlsec/src/kw_aes_des.h
SOURCES += \
xmlsec/src/app.c \
xmlsec/src/base64.c \
xmlsec/src/bn.c \
xmlsec/src/buffer.c \
xmlsec/src/c14n.c \
xmlsec/src/dl.c \
xmlsec/src/enveloped.c \
xmlsec/src/errors.c \
xmlsec/src/io.c \
xmlsec/src/keyinfo.c \
xmlsec/src/keys.c \
xmlsec/src/keysdata.c \
xmlsec/src/keysmngr.c \
xmlsec/src/kw_aes_des.c \
xmlsec/src/list.c \
xmlsec/src/membuf.c \
xmlsec/src/nodeset.c \
xmlsec/src/parser.c \
xmlsec/src/relationship.c \
xmlsec/src/soap.c \
xmlsec/src/strings.c \
xmlsec/src/templates.c \
xmlsec/src/transforms.c \
xmlsec/src/x509.c \
xmlsec/src/xmldsig.c \
xmlsec/src/xmlenc.c \
xmlsec/src/xmlsec.c \
xmlsec/src/xmltree.c \
xmlsec/src/xpath.c
use_gcrypt {
HEADERS += \
xmlsec/include/xmlsec/gcrypt/app.h \
xmlsec/include/xmlsec/gcrypt/crypto.h \
xmlsec/include/xmlsec/gcrypt/symbols.h \
\
xmlsec/src/gcrypt/asn1.h \
xmlsec/src/gcrypt/globals.h
SOURCES += \
xmlsec/src/gcrypt/app.c \
xmlsec/src/gcrypt/asn1.c \
xmlsec/src/gcrypt/asymkeys.c \
xmlsec/src/gcrypt/ciphers.c \
xmlsec/src/gcrypt/crypto.c \
xmlsec/src/gcrypt/digests.c \
xmlsec/src/gcrypt/hmac.c \
xmlsec/src/gcrypt/kw_aes.c \
xmlsec/src/gcrypt/kw_des.c \
xmlsec/src/gcrypt/signatures.c \
xmlsec/src/gcrypt/symkeys.c
}
use_gnutls {
HEADERS += \
xmlsec/include/xmlsec/gnutls/app.h \
xmlsec/include/xmlsec/gnutls/crypto.h \
xmlsec/include/xmlsec/gnutls/symbols.h \
xmlsec/include/xmlsec/gnutls/x509.h \
\
xmlsec/src/gnutls/globals.h \
xmlsec/src/gnutls/x509utils.h
SOURCES += \
xmlsec/src/gnutls/app.c \
xmlsec/src/gnutls/asymkeys.c \
xmlsec/src/gnutls/ciphers.c \
xmlsec/src/gnutls/crypto.c \
xmlsec/src/gnutls/digests.c \
xmlsec/src/gnutls/hmac.c \
xmlsec/src/gnutls/kw_aes.c \
xmlsec/src/gnutls/kw_des.c \
xmlsec/src/gnutls/signatures.c \
xmlsec/src/gnutls/symkeys.c \
xmlsec/src/gnutls/x509.c \
xmlsec/src/gnutls/x509utils.c \
xmlsec/src/gnutls/x509vfy.c
}
use_mscrypto {
DEFINES += XMLSEC_CRYPTO_MSCRYPTO
HEADERS += \
xmlsec/include/xmlsec/mscrypto/app.h \
xmlsec/include/xmlsec/mscrypto/certkeys.h \
xmlsec/include/xmlsec/mscrypto/crypto.h \
xmlsec/include/xmlsec/mscrypto/keysstore.h \
xmlsec/include/xmlsec/mscrypto/symbols.h \
xmlsec/include/xmlsec/mscrypto/x509.h \
\
xmlsec/src/mscrypto/csp_calg.h \
xmlsec/src/mscrypto/csp_oid.h \
xmlsec/src/mscrypto/globals.h \
xmlsec/src/mscrypto/private.h \
xmlsec/src/mscrypto/xmlsec-mingw.h
SOURCES += \
xmlsec/src/mscrypto/app.c \
xmlsec/src/mscrypto/certkeys.c \
xmlsec/src/mscrypto/ciphers.c \
xmlsec/src/mscrypto/crypto.c \
xmlsec/src/mscrypto/digests.c \
xmlsec/src/mscrypto/hmac.c \
xmlsec/src/mscrypto/keysstore.c \
xmlsec/src/mscrypto/kt_rsa.c \
xmlsec/src/mscrypto/kw_aes.c \
xmlsec/src/mscrypto/kw_des.c \
xmlsec/src/mscrypto/signatures.c \
xmlsec/src/mscrypto/symkeys.c \
xmlsec/src/mscrypto/x509.c \
xmlsec/src/mscrypto/x509vfy.c
}
use_nss {
HEADERS += \
xmlsec/include/xmlsec/nss/app.h \
xmlsec/include/xmlsec/nss/bignum.h \
xmlsec/include/xmlsec/nss/crypto.h \
xmlsec/include/xmlsec/nss/keysstore.h \
xmlsec/include/xmlsec/nss/pkikeys.h \
xmlsec/include/xmlsec/nss/symbols.h \
xmlsec/include/xmlsec/nss/x509.h \
\
xmlsec/src/nss/globals.h
SOURCES += \
xmlsec/src/nss/app.c \
xmlsec/src/nss/bignum.c \
xmlsec/src/nss/ciphers.c \
xmlsec/src/nss/crypto.c \
xmlsec/src/nss/digests.c \
xmlsec/src/nss/hmac.c \
xmlsec/src/nss/keysstore.c \
xmlsec/src/nss/keytrans.c \
xmlsec/src/nss/kw_aes.c \
xmlsec/src/nss/kw_des.c \
xmlsec/src/nss/pkikeys.c \
xmlsec/src/nss/signatures.c \
xmlsec/src/nss/symkeys.c \
xmlsec/src/nss/x509.c \
xmlsec/src/nss/x509vfy.c
}
use_openssl {
DEFINES += XMLSEC_OPENSSL_110
INCLUDEPATH += $$PWD/openssl/include
HEADERS += \
xmlsec/include/xmlsec/openssl/app.h \
xmlsec/include/xmlsec/openssl/bn.h \
xmlsec/include/xmlsec/openssl/crypto.h \
xmlsec/include/xmlsec/openssl/evp.h \
xmlsec/include/xmlsec/openssl/symbols.h \
xmlsec/include/xmlsec/openssl/x509.h \
\
xmlsec/src/openssl/globals.h \
xmlsec/src/openssl/openssl11_wrapper.h
SOURCES += \
xmlsec/src/openssl/_app.c \
xmlsec/src/openssl/_bn.c \
xmlsec/src/openssl/_ciphers.c \
xmlsec/src/openssl/_crypto.c \
xmlsec/src/openssl/_digests.c \
xmlsec/src/openssl/_evp.c \
xmlsec/src/openssl/_evp_signatures.c \
xmlsec/src/openssl/_hmac.c \
xmlsec/src/openssl/_kt_rsa.c \
xmlsec/src/openssl/_kw_aes.c \
xmlsec/src/openssl/_kw_des.c \
xmlsec/src/openssl/_signatures.c \
xmlsec/src/openssl/_symkeys.c \
xmlsec/src/openssl/_x509.c \
xmlsec/src/openssl/_x509vfy.c
}
use_skeleton {
HEADERS += \
xmlsec/include/xmlsec/skeleton/app.h \
xmlsec/include/xmlsec/skeleton/crypto.h \
xmlsec/include/xmlsec/skeleton/symbols.h \
\
xmlsec/src/skeleton/globals.h
SOURCES += \
xmlsec/src/skeleton/app.c \
xmlsec/src/skeleton/crypto.c
}
use_xslt {
HEADERS += \
xmlsec/include/xmlsec/private/xslt.h
SOURCES += \
xmlsec/src/xslt.c
} else {
DEFINES += \
XMLSEC_NO_XSLT
}

View File

@ -7,23 +7,23 @@ class COOXMLSigner_private;
class OPENSSL_DECL COOXMLSigner
{
public:
COOXMLSigner(const std::wstring& sFolder, ICertificate* pContext);
COOXMLSigner(unsigned char* data, unsigned long length, ICertificate* pContext);
~COOXMLSigner();
COOXMLSigner(const std::wstring& sFolder, ICertificate* pContext);
COOXMLSigner(unsigned char* data, unsigned long length, ICertificate* pContext);
~COOXMLSigner();
void SetGuid (const std::wstring& guid);
void SetImageValid (const std::wstring& file);
void SetImageInvalid(const std::wstring& file);
void SetImageValid (unsigned char* data, unsigned long length);
void SetImageInvalid(unsigned char* data, unsigned long length);
void SetGuid (const std::wstring& guid);
void SetImageValid (const std::wstring& file);
void SetImageInvalid(const std::wstring& file);
void SetImageValid (unsigned char* data, unsigned long length);
void SetImageInvalid(unsigned char* data, unsigned long length);
int Sign(unsigned char*& pFiletoWrite, unsigned long& dwLenFiletoWrite);
int Sign(unsigned char*& pFiletoWrite, unsigned long& dwLenFiletoWrite);
// Simle alias to Sign(data, len) for folder realization
int Sign();
// Simle alias to Sign(data, len) for folder realization
int Sign();
private:
COOXMLSigner_private* m_internal;
COOXMLSigner_private* m_internal;
};
#endif //_XML_OOXMLSIGNER_H_

View File

@ -7,48 +7,49 @@
#define OOXML_SIGNATURE_INVALID 1
#define OOXML_SIGNATURE_NOTSUPPORTED 2
#define OOXML_SIGNATURE_BAD 3
#define OOXML_SIGNATURE_PARTIALLY 4
class COOXMLSignature_private;
class OPENSSL_DECL COOXMLSignature
{
public:
COOXMLSignature();
~COOXMLSignature();
COOXMLSignature();
~COOXMLSignature();
public:
int GetValid();
std::string GetGuid();
std::string GetDate();
ICertificate* GetCertificate();
std::string GetImageValidBase64();
std::string GetImageInvalidBase64();
int GetValid();
std::string GetGuid();
std::string GetDate();
ICertificate* GetCertificate();
std::string GetImageValidBase64();
std::string GetImageInvalidBase64();
std::wstring GetFile();
std::wstring GetFile();
public:
void Check();
void Check();
friend class COOXMLVerifier_private;
friend class COOXMLVerifier;
friend class COOXMLVerifier_private;
friend class COOXMLVerifier;
private:
COOXMLSignature_private* m_internal;
COOXMLSignature_private* m_internal;
};
class COOXMLVerifier_private;
class Q_DECL_EXPORT COOXMLVerifier
{
public:
COOXMLVerifier(const std::wstring& sFolder);
COOXMLVerifier(unsigned char* data, unsigned long length);
~COOXMLVerifier();
COOXMLVerifier(const std::wstring& sFolder);
COOXMLVerifier(unsigned char* data, unsigned long length);
~COOXMLVerifier();
int GetSignatureCount();
COOXMLSignature* GetSignature(const int& index);
int GetSignatureCount();
COOXMLSignature* GetSignature(const int& index);
void RemoveSignature(const std::string& sGuid);
void RemoveSignature(const std::string& sGuid);
private:
COOXMLVerifier_private* m_internal;
COOXMLVerifier_private* m_internal;
};
#endif //_XML_OOXMLVERIFIER_H_

View File

@ -27,6 +27,7 @@ HEADERS += \
src/XmlTransform.h
SOURCES += \
src/common.h \
src/XmlTransform.cpp \
src/CertificateCommon.cpp \
src/OOXMLSigner.cpp \

View File

@ -0,0 +1,141 @@
#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
{
namespace Properties
{
static const wchar_t* Email = L"email";
static const wchar_t* Phone = L"phone";
static const wchar_t* Name = L"name";
static const wchar_t* Signature = L"signature";
static const wchar_t* DateFrom = L"date-from";
static const wchar_t* DateTo = L"date-to";
static const wchar_t* CommonName = L"common-name";
static const wchar_t* OrganizationName = L"organization";
static const wchar_t* Country = L"country";
}
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);
void AddSkip(const size_t& size);
// 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();
void Generate(const std::map<std::wstring, std::wstring>& props = std::map<std::wstring, std::wstring>());
public:
std::map<std::wstring, std::wstring> GetProperties();
bool Load(CStorageBuffer* buffer);
bool Save(CStorageBuffer* buffer);
bool LoadKey(CStorageBuffer* buffer);
bool SaveKey(CStorageBuffer* buffer);
bool LoadCert(CStorageBuffer* buffer);
bool SaveCert(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);
}
OSIGN_DECL std::string GetLastError();
OSIGN_DECL void LogLastError();
}
#endif // _XMLSIGNER_OFORM_H_

View File

@ -0,0 +1,63 @@
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_USE_DYNAMIC_LIBRARY_BUILDING
# 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
core_ios {
OBJECTIVE_SOURCES += $$CORE_ROOT_DIR/DesktopEditor/common/File_ios.mm
LIBS += -framework Foundation
}
# ----------
build_xp:DESTDIR=$$DESTDIR/xp

View File

@ -0,0 +1,334 @@
#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)
{
int nLenDst = NSBase64::Base64DecodeGetRequiredLength((int)base64.length());
m_internal->Destroy();
m_internal->AddSize((size_t)nLenDst);
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);
}
void CStorageBuffer::AddSkip(const size_t& size)
{
m_internal->m_data->m_size += 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,524 @@
#include "../include/osign.h"
#include "./utils.h"
#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/x509v3.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>
#include <iostream>
namespace OSign
{
const char* c_record_common_name = "OSign Certificate";
const char* c_record_organization_name = "Ascensio System SIA";
const char* c_record_country = "US";
// common
void string_replace(std::string& text, const std::string& replaceFrom, const std::string& replaceTo)
{
size_t posn = 0;
while (std::string::npos != (posn = text.find(replaceFrom, posn)))
{
text.replace(posn, replaceFrom.length(), replaceTo);
posn += replaceTo.length();
}
}
tm ASN1_GetTimeT(ASN1_TIME* time)
{
struct tm t;
const char* str = (const char*) time->data;
size_t i = 0;
memset(&t, 0, sizeof(t));
if (time->type == V_ASN1_UTCTIME)
{
/* two digit year */
t.tm_year = (str[i++] - '0') * 10;
t.tm_year += (str[i++] - '0');
if (t.tm_year < 70)
t.tm_year += 100;
}
else if (time->type == V_ASN1_GENERALIZEDTIME)
{
/* four digit year */
t.tm_year = (str[i++] - '0') * 1000;
t.tm_year+= (str[i++] - '0') * 100;
t.tm_year+= (str[i++] - '0') * 10;
t.tm_year+= (str[i++] - '0');
t.tm_year -= 1900;
}
t.tm_mon = (str[i++] - '0') * 10;
t.tm_mon += (str[i++] - '0') - 1; // -1 since January is 0 not 1.
t.tm_mday = (str[i++] - '0') * 10;
t.tm_mday+= (str[i++] - '0');
t.tm_hour = (str[i++] - '0') * 10;
t.tm_hour+= (str[i++] - '0');
t.tm_min = (str[i++] - '0') * 10;
t.tm_min += (str[i++] - '0');
t.tm_sec = (str[i++] - '0') * 10;
t.tm_sec += (str[i++] - '0');
/* Note: we did not adjust the time based on time zone information */
return t;
}
std::wstring GetPropertyByName(const std::wstring& sSubject, const std::wstring& sName)
{
std::wstring::size_type pos = sSubject.find(sName + L"=");
if (std::wstring::npos != pos)
{
std::wstring::size_type name_len = sName.length() + 1;
std::wstring::size_type posEnd = sSubject.find(L"/", pos);
if (std::wstring::npos != posEnd)
return sSubject.substr(pos + name_len, posEnd - pos - name_len);
return sSubject.substr(pos + name_len);
}
return L"";
}
class CCertificate_private
{
public:
X509* m_cert = nullptr;
EVP_PKEY* m_key = nullptr;
static bool g_is_initialize;
public:
CCertificate_private()
{
if (!g_is_initialize)
{
g_is_initialize = true;
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
}
}
~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(const std::map<std::wstring, std::wstring>& props)
{
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);
m_cert = X509_new();
X509_set_version(m_cert, 2);
ASN1_STRING* serialNumber = X509_get_serialNumber(m_cert);
if (serialNumber)
{
const int nBytesCount = 16;
unsigned char pSerialNumber[nBytesCount];
RAND_bytes(pSerialNumber, nBytesCount);
if (1 != ASN1_STRING_set(serialNumber, pSerialNumber, nBytesCount) == 1)
ASN1_INTEGER_set(serialNumber, 1);
}
X509_gmtime_adj(X509_get_notBefore(m_cert), 0);
X509_gmtime_adj(X509_get_notAfter(m_cert), 31536000L);
if (X509_set_pubkey(m_cert, m_key) == 0)
{
EVP_PKEY_CTX_free(pctx);
Destroy();
return false;
}
X509_NAME* name_record = X509_get_subject_name(m_cert);
X509_NAME_add_entry_by_txt(name_record, "C", MBSTRING_ASC, (unsigned char *)c_record_country, -1, -1, 0);
X509_NAME_add_entry_by_txt(name_record, "O", MBSTRING_ASC, (unsigned char *)c_record_organization_name, -1, -1, 0);
X509_NAME_add_entry_by_txt(name_record, "CN", MBSTRING_ASC, (unsigned char *)c_record_common_name, -1, -1, 0);
X509_set_issuer_name(m_cert, name_record);
if (!props.empty())
{
std::string sAdditions = "";
for (std::map<std::wstring, std::wstring>::const_iterator iter = props.begin(); iter != props.end(); iter++)
{
// delete record for read
if (iter->first == Properties::DateTo ||
iter->first == Properties::DateFrom)
{
continue;
}
std::string sKey = U_TO_UTF8(iter->first);
std::string sValue = U_TO_UTF8(iter->second);
string_replace(sKey, ";", "&#59;");
string_replace(sKey, "=", "&#61;");
string_replace(sValue, ";", "&#59;");
sAdditions += (sKey + "=" + sValue + ";");
}
if (!sAdditions.empty())
{
//const int nid_user = OBJ_create("1.2.3", "key", "value");
ASN1_OCTET_STRING* oDataAdditions = ASN1_OCTET_STRING_new();
int nError = ASN1_OCTET_STRING_set(oDataAdditions, (unsigned const char*)sAdditions.c_str(), (int)sAdditions.length());
OSIGN_UNUSED(nError);
X509_EXTENSION* ext = X509_EXTENSION_create_by_NID(nullptr, NID_subject_alt_name, false, oDataAdditions);
nError = X509_add_ext(m_cert, ext, -1);
OSIGN_UNUSED(nError);
X509_EXTENSION_free(ext);
}
}
if (X509_sign(m_cert, m_key, EVP_md_null()) == 0)
{
LogLastError();
EVP_PKEY_CTX_free(pctx);
Destroy();
return false;
}
EVP_PKEY_CTX_free(pctx);
return true;
}
};
bool CCertificate_private::g_is_initialize = false;
CCertificate::CCertificate()
{
m_internal = new CCertificate_private();
}
CCertificate::~CCertificate()
{
delete m_internal;
}
void CCertificate::Generate(const std::map<std::wstring, std::wstring>& props)
{
m_internal->Create(props);
}
std::map<std::wstring, std::wstring> CCertificate::GetProperties()
{
std::map<std::wstring, std::wstring> props;
// date
if (true)
{
ASN1_TIME* _time1 = X509_get_notBefore(m_internal->m_cert);
struct tm t1 = ASN1_GetTimeT(_time1);
std::string sTimeBefore = std::to_string(t1.tm_mday) + "/" + std::to_string(t1.tm_mon + 1) + "/" + std::to_string(t1.tm_year + 1900);
ASN1_TIME* _time2 = X509_get_notAfter(m_internal->m_cert);
struct tm t2 = ASN1_GetTimeT(_time2);
std::string sTimeAfter = std::to_string(t2.tm_mday) + "/" + std::to_string(t2.tm_mon + 1) + "/" + std::to_string(t2.tm_year + 1900);
props.insert(std::make_pair(Properties::DateFrom, UTF8_TO_U(sTimeBefore)));
props.insert(std::make_pair(Properties::DateTo, UTF8_TO_U(sTimeAfter)));
}
// names
if (true)
{
X509_NAME* pSubjectName = X509_get_subject_name(m_internal->m_cert);
char buffer[10000];
memset(buffer, 0, 10000);
X509_NAME_oneline(pSubjectName, buffer, 10000);
std::string sSubjectNameA(buffer);
std::wstring sSubject = UTF8_TO_U(sSubjectNameA);
std::wstring sCommonName = GetPropertyByName(sSubject, L"CN");
std::wstring sOrganizationName = GetPropertyByName(sSubject, L"O");
std::wstring sCountry = GetPropertyByName(sSubject, L"C");
if (!sCommonName.empty()) props.insert(std::make_pair(Properties::CommonName, sCommonName));
if (!sOrganizationName.empty()) props.insert(std::make_pair(Properties::OrganizationName, sOrganizationName));
if (!sCountry.empty()) props.insert(std::make_pair(Properties::Country, sCountry));
}
// additions
if (true)
{
int subjectAltNameLoc = X509_get_ext_by_NID(m_internal->m_cert, NID_subject_alt_name, -1);
if(subjectAltNameLoc != -1)
{
X509_EXTENSION* ext = X509_get_ext(m_internal->m_cert, subjectAltNameLoc);
ASN1_OCTET_STRING* oData = X509_EXTENSION_get_data(ext);
std::string sDataString = std::string((char*)oData->data, oData->length);
std::string::size_type posStart = 0;
std::string::size_type posEnd = sDataString.find(';');
while (posEnd != std::string::npos)
{
std::string::size_type posSplit = sDataString.find('=', posStart);
if (std::string::npos == posSplit)
break;
std::string sKeyA = sDataString.substr(posStart, posSplit - posStart);
std::string sValueA = sDataString.substr(posSplit + 1, posEnd - posSplit - 1);
string_replace(sKeyA, "&#59;", ";");
string_replace(sKeyA, "&#61;", "=");
string_replace(sValueA, "&#59;", ";");
std::wstring sKey = UTF8_TO_U(sKeyA);
std::wstring sValue = UTF8_TO_U(sValueA);
props.insert(std::make_pair(sKey, sValue));
posStart = posEnd + 1;
posEnd = sDataString.find(';', posStart);
}
}
}
return props;
}
bool CCertificate::Load(CStorageBuffer* buffer)
{
if (!LoadCert(buffer))
return false;
if (!LoadKey(buffer))
return false;
return true;
}
bool CCertificate::Save(CStorageBuffer* buffer)
{
if (!m_internal->m_cert || !m_internal->m_key)
return false;
SaveCert(buffer);
SaveKey(buffer);
return true;
}
bool CCertificate::LoadKey(CStorageBuffer* buffer)
{
int nLenKey = buffer->ReadInt();
unsigned char* pDataKey = buffer->ReadData((size_t)nLenKey);
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::SaveKey(CStorageBuffer* buffer)
{
if (!m_internal->m_key)
return false;
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;
}
bool CCertificate::LoadCert(CStorageBuffer* buffer)
{
int nLenCert = buffer->ReadInt();
unsigned char* pDataCert = buffer->ReadData((size_t)nLenCert);
BIO* bio = BIO_new_mem_buf((void*)pDataCert, (int)nLenCert);
if (!PEM_read_bio_X509(bio, &m_internal->m_cert, NULL, NULL))
{
LogLastError();
BIO_free(bio);
return false;
}
BIO_free(bio);
return true;
}
bool CCertificate::SaveCert(CStorageBuffer* buffer)
{
if (!m_internal->m_cert)
return false;
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);
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)
{
if (!m_internal->m_cert)
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;
}
}
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;
}
}
}
namespace OSign
{
std::string GetLastError()
{
BIO* bio = BIO_new(BIO_s_mem());
ERR_print_errors(bio);
char *buf = NULL;
size_t len = BIO_get_mem_data(bio, &buf);
std::string sRet((char*)buf, len);
BIO_free(bio);
return sRet;
}
void LogLastError()
{
std::cout << OSign::GetLastError() << std::endl;
}
}

View File

@ -0,0 +1,113 @@
#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->ReadData((size_t)nLen), nLen);
CCertificate* pCert = new CCertificate();
if (pCert->Load(&oCertBuffer))
m_internal->m_certs.push_back(pCert);
else
delete pCert;
}
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,167 @@
#include "gtest/gtest.h"
#include "../lib/include/osign.h"
#include "../../../../common/File.h"
class COSignTest : public testing::Test
{
public:
std::wstring WorkiDirectory;
public:
virtual void SetUp() override
{
WorkiDirectory = NSFile::GetProcessDirectory();
}
virtual void TearDown() override
{
}
};
// aes шифрование
TEST_F(COSignTest, crypt_storage_aes_gcm_random_password)
{
// создаем случайный пароль длиной 100 символов
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());
EXPECT_EQ(sDecryptData, sDataCrypt);
}
TEST_F(COSignTest, crypt_storage_aes_gcm_string_password)
{
// создаем случайный пароль из строки
std::string sPassword = "password";
OSign::CStorageBuffer oPassword;
oPassword.Add((unsigned char*)sPassword.c_str(), sPassword.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);
// сравниваем с исходником
std::string sDecryptData((char*)oDecryptBuffer.GetData(), oDecryptBuffer.GetLength());
EXPECT_EQ(sDecryptData, sDataCrypt);
}
// сериализация буфера
TEST_F(COSignTest, serialize_buffer_string)
{
std::string sBuffer = "Hello, world";
OSign::CStorageBuffer oBuffer;
oBuffer.Add((unsigned char*)sBuffer.c_str(), sBuffer.length());
std::string sBase64 = oBuffer.ToBase64();
OSign::CStorageBuffer oDecodeBuffer;
oDecodeBuffer.FromBase64(sBase64);
std::string sDecodeBuffer((char*)oDecodeBuffer.GetData(), oDecodeBuffer.GetLength());
EXPECT_EQ(sBuffer, sDecodeBuffer);
}
// подпись
TEST_F(COSignTest, sign_buffer_string)
{
// генерируем новый сертификат
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);
delete pCert;
EXPECT_EQ(bIsValid, true);
}
// тест сериализации стораджа через подпись/верификацию
TEST_F(COSignTest, serialize_storage_by_sign)
{
// генерируем новый сертификат
OSign::CCertificate* pCert = new OSign::CCertificate();
pCert->Generate();
// создаем сторадж и добавлем сертификат (сторадж сам следит за удалением сертификата)
OSign::CStorage oStorage;
oStorage.Add(pCert);
// сохраняем сторадж
OSign::CStorageBuffer oStorageBuffer;
oStorage.Save(&oStorageBuffer);
OSign::CStorage oStorageLoad;
oStorageLoad.Load(&oStorageBuffer);
// буфер для подписи
std::string sDataBuffer = "Hello, world!";
OSign::CStorageBuffer oBuffer;
oBuffer.Add((const unsigned char*)sDataBuffer.c_str(), sDataBuffer.length());
// подписываем
OSign::CStorageBuffer oBufferSign = pCert->Sign(oBuffer);
OSign::CCertificate* pCert2 = oStorage.Get(0);
bool bIsValid = pCert2->Verify(oBuffer, oBufferSign);
EXPECT_EQ(bIsValid, true);
}
// тест сериализации стораджа через подпись/верификацию
TEST_F(COSignTest, serialize_storage_by_property)
{
// генерируем новый сертификат с настройками
std::map<std::wstring, std::wstring> properties;
properties.insert(std::make_pair(OSign::Properties::Email, L"sign@onlyoffice.com"));
properties.insert(std::make_pair(OSign::Properties::Phone, L"+00000000000"));
std::wstring sNameTest = L"NameTest";
std::wstring sValueTest = L"ValueTest";
properties.insert(std::make_pair(sNameTest, sValueTest));
OSign::CCertificate* pCert = new OSign::CCertificate();
pCert->Generate(properties);
// создаем сторадж и добавлем сертификат (сторадж сам следит за удалением сертификата)
OSign::CStorage oStorage;
oStorage.Add(pCert);
// сохраняем сторадж
OSign::CStorageBuffer oStorageBuffer;
oStorage.Save(&oStorageBuffer);
OSign::CStorage oStorageLoad;
oStorageLoad.Load(&oStorageBuffer);
std::wstring sValue = L"";
OSign::CCertificate* pCert2 = oStorage.Get(0);
std::map<std::wstring, std::wstring> mapProps = pCert2->GetProperties();
std::map<std::wstring, std::wstring>::const_iterator iterFind = mapProps.find(sNameTest);
if (iterFind != mapProps.end())
sValue = iterFind->second;
EXPECT_EQ(sValueTest, sValue);
}

View File

@ -0,0 +1,17 @@
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)
include($$CORE_ROOT_DIR/Common/3dParty/googletest/googletest.pri)
ADD_DEPENDENCY(osign)
SOURCES += main.cpp
DESTDIR = $$PWD/build

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,213 +5,248 @@
#include "../../../common/File.h"
#include "../../../common/Directory.h"
#include "../../../../OfficeUtils/src/ZipFolder.h"
#include <set>
class CManifestFileInfo
{
public:
IFolder* m_pFolder;
protected:
std::wstring m_sFile;
std::wstring m_sAliasDirectory;
int m_nCountUnexistedFile;
public:
CManifestFileInfo()
{
m_pFolder = NULL;
m_sFile = L"";
m_nCountUnexistedFile = 0;
}
std::wstring& GetFilePath()
{
return m_sFile;
}
void SetFilePath(const std::wstring& sFilePath)
{
m_sFile = sFilePath;
m_sAliasDirectory = NSFile::GetDirectoryName(sFilePath);
m_sAliasDirectory = NSFile::GetDirectoryName(m_sAliasDirectory); // ../ from _rels/
}
std::wstring GetHeadPath(const std::wstring& sFile)
{
std::wstring sFullPath = m_sAliasDirectory + L"/" + sFile;
sFullPath = NSSystemPath::NormalizePath(sFullPath);
if (!sFullPath.empty() && '/' != sFullPath[0])
sFullPath = L"/" + sFullPath;
return sFullPath;
}
};
class COOXMLRelationship
{
public:
std::wstring rid;
std::wstring type;
std::wstring target;
std::wstring target_mode;
std::wstring rid;
std::wstring type;
std::wstring target;
std::wstring target_mode;
public:
COOXMLRelationship()
{
}
COOXMLRelationship()
{
}
COOXMLRelationship(XmlUtils::CXmlNode& node)
{
rid = node.GetAttribute("Id");
type = node.GetAttribute("Type");
target = node.GetAttribute("Target");
target_mode = node.GetAttribute("TargetMode");
COOXMLRelationship(XmlUtils::CXmlNode& node)
{
rid = node.GetAttribute("Id");
type = node.GetAttribute("Type");
target = node.GetAttribute("Target");
target_mode = node.GetAttribute("TargetMode");
CheckTargetMode();
}
CheckTargetMode();
}
std::wstring GetXml()
{
NSStringUtils::CStringBuilder builder;
builder.WriteString(L"<Relationship Id=\"");
builder.WriteEncodeXmlString(rid);
builder.WriteString(L"\" Type=\"");
builder.WriteEncodeXmlString(type);
builder.WriteString(L"\" Target=\"");
builder.WriteEncodeXmlString(target);
builder.WriteString(L"\" TargetMode=\"");
builder.WriteEncodeXmlString(target_mode);
builder.WriteString(L"\" />");
return builder.GetData();
}
std::wstring GetXml()
{
NSStringUtils::CStringBuilder builder;
builder.WriteString(L"<Relationship Id=\"");
builder.WriteEncodeXmlString(rid);
builder.WriteString(L"\" Type=\"");
builder.WriteEncodeXmlString(type);
builder.WriteString(L"\" Target=\"");
builder.WriteEncodeXmlString(target);
builder.WriteString(L"\" TargetMode=\"");
builder.WriteEncodeXmlString(target_mode);
builder.WriteString(L"\" />");
return builder.GetData();
}
static bool Compare(const COOXMLRelationship& i, const COOXMLRelationship& j)
{
return i.rid < j.rid;
}
static bool Compare(const COOXMLRelationship& i, const COOXMLRelationship& j)
{
return i.rid < j.rid;
}
protected:
void CheckTargetMode()
{
if (!target_mode.empty())
return;
void CheckTargetMode()
{
if (!target_mode.empty())
return;
if (0 == target.find(L"http") || 0 == target.find(L"www") || 0 == target.find(L"ftp"))
target_mode = L"External";
else
target_mode = L"Internal";
}
if (0 == target.find(L"http") || 0 == target.find(L"www") || 0 == target.find(L"ftp"))
target_mode = L"External";
else
target_mode = L"Internal";
}
};
class COOXMLRelationships
{
public:
std::vector<COOXMLRelationship> rels;
IFolder* m_pFolder;
std::vector<COOXMLRelationship> rels;
CManifestFileInfo* m_pFileInfo;
public:
COOXMLRelationships()
{
m_pFolder = NULL;
}
COOXMLRelationships()
{
}
COOXMLRelationships(const std::string& xml, std::map<std::wstring, bool>* check_need = NULL)
{
XmlUtils::CXmlNode oNode;
if (!oNode.FromXmlStringA(xml))
return;
COOXMLRelationships(const std::string& xml, CManifestFileInfo* pFileInfo, std::set<std::wstring>* check_need = NULL)
{
m_pFileInfo = pFileInfo;
XmlUtils::CXmlNode oNode;
if (!oNode.FromXmlStringA(xml))
return;
FromXmlNode(oNode, check_need);
}
FromXmlNode(oNode, check_need);
}
COOXMLRelationships(const std::wstring& xml, IFolder* pFolder, std::map<std::wstring, bool>* check_need = NULL)
{
XmlUtils::CXmlNode oNode;
COOXMLRelationships(CManifestFileInfo* pFileInfo, std::set<std::wstring>* check_need = NULL)
{
m_pFileInfo = pFileInfo;
if (NULL == pFolder)
{
if (!oNode.FromXmlString(xml))
return;
}
else
{
m_pFolder = pFolder;
oNode = pFolder->getNodeFromFile(xml);
if (!oNode.IsValid())
return;
}
if (!m_pFileInfo || NULL == m_pFileInfo->m_pFolder)
return;
FromXmlNode(oNode, check_need);
}
XmlUtils::CXmlNode oNode = m_pFileInfo->m_pFolder->getNodeFromFile(m_pFileInfo->GetFilePath());
if (!oNode.IsValid())
return;
void FromXmlNode(XmlUtils::CXmlNode& oNode, std::map<std::wstring, bool>* check_need = NULL)
{
std::vector<XmlUtils::CXmlNode> oNodes;
if (!oNode.GetNodes(L"Relationship", oNodes))
return;
FromXmlNode(oNode, check_need);
}
size_t nCount = oNodes.size();
for (size_t i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode &oRel = oNodes[i];
void FromXmlNode(XmlUtils::CXmlNode& oNode, std::set<std::wstring>* check_need = NULL)
{
std::vector<XmlUtils::CXmlNode> oNodes = oNode.GetNodes(L"Relationship");
size_t nCount = oNodes.size();
for (size_t i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode oRel = oNodes[i];
if (NULL == check_need)
{
rels.push_back(COOXMLRelationship(oRel));
}
else
{
std::wstring sRid = oRel.GetAttribute("Id");
if (check_need->find(sRid) != check_need->end())
rels.push_back(COOXMLRelationship(oRel));
}
}
}
COOXMLRelationship oCurrentRel(oRel);
if (NULL == check_need)
{
rels.push_back(oCurrentRel);
}
else
{
std::wstring sRid = oRel.GetAttribute("Id");
if (check_need->find(sRid) != check_need->end())
rels.push_back(oCurrentRel);
}
}
}
std::wstring GetXml()
{
NSStringUtils::CStringBuilder builder;
std::wstring GetXml()
{
NSStringUtils::CStringBuilder builder;
builder.WriteString(L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
builder.WriteString(L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
// sort by rId
std::sort(rels.begin(), rels.end(), COOXMLRelationship::Compare);
// sort by rId
std::sort(rels.begin(), rels.end(), COOXMLRelationship::Compare);
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
builder.WriteString(i->GetXml());
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
builder.WriteString(i->GetXml());
builder.WriteString(L"</Relationships>");
builder.WriteString(L"</Relationships>");
return builder.GetData();
}
return builder.GetData();
}
std::wstring GetTransforms()
{
NSStringUtils::CStringBuilder builder;
std::wstring GetTransforms()
{
NSStringUtils::CStringBuilder builder;
builder.WriteString(L"<Transforms><Transform Algorithm=\"http://schemas.openxmlformats.org/package/2006/RelationshipTransform\">");
builder.WriteString(L"<Transforms><Transform Algorithm=\"http://schemas.openxmlformats.org/package/2006/RelationshipTransform\">");
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
{
builder.WriteString(L"<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"");
builder.WriteEncodeXmlString(i->rid);
builder.WriteString(L"\" />");
}
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
{
builder.WriteString(L"<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"");
builder.WriteEncodeXmlString(i->rid);
builder.WriteString(L"\" />");
}
builder.WriteString(L"</Transform><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>");
builder.WriteString(L"</Transform><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>");
return builder.GetData();
}
return builder.GetData();
}
void CheckOriginSigs(const std::wstring& file)
{
int rId = 0;
std::string sReplace = "";
std::vector<COOXMLRelationship>::iterator i = rels.begin();
while (i != rels.end())
{
if (0 == i->target.find(L"_xmlsignatures/"))
{
sReplace = U_TO_UTF8(i->target);
break;
}
void CheckOriginSigs(const std::wstring& file)
{
int rId = 0;
std::string sReplace = "";
std::vector<COOXMLRelationship>::iterator i = rels.begin();
while (i != rels.end())
{
if (0 == i->target.find(L"_xmlsignatures/"))
{
sReplace = U_TO_UTF8(i->target);
break;
}
std::wstring rid = i->rid;
rid = rid.substr(3);
std::wstring rid = i->rid;
rid = rid.substr(3);
int nTemp = std::stoi(rid);
int nTemp = std::stoi(rid);
if (nTemp > rId)
rId = nTemp;
if (nTemp > rId)
rId = nTemp;
i++;
}
i++;
}
if (!sReplace.empty())
{
if (sReplace == "_xmlsignatures/origin.sigs")
return;
if (!sReplace.empty())
{
if (sReplace == "_xmlsignatures/origin.sigs")
return;
std::string sXmlA = m_pFolder->readXml(file);
NSStringUtils::string_replaceA(sXmlA, sReplace, "_xmlsignatures/origin.sigs");
m_pFolder->writeXmlA(file, sXmlA);
return;
}
std::string sXmlA = m_pFileInfo->m_pFolder->readXml(file);
NSStringUtils::string_replaceA(sXmlA, sReplace, "_xmlsignatures/origin.sigs");
m_pFileInfo->m_pFolder->writeXmlA(file, sXmlA);
return;
}
std::string sXmlA = m_pFolder->readXml(file);
std::string sXmlA = m_pFileInfo->m_pFolder->readXml(file);
std::string::size_type pos = sXmlA.rfind("</Relationships>");
if (pos == std::string::npos)
return;
std::string::size_type pos = sXmlA.rfind("</Relationships>");
if (pos == std::string::npos)
return;
rId++;
std::string sRet = sXmlA.substr(0, pos);
sRet += ("<Relationship Id=\"rId" + std::to_string(rId) + "\" \
rId++;
std::string sRet = sXmlA.substr(0, pos);
sRet += ("<Relationship Id=\"rId" + std::to_string(rId) + "\" \
Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin\" Target=\"_xmlsignatures/origin.sigs\"/>\
</Relationships>");
m_pFolder->writeXmlA(file, sRet);
}
m_pFileInfo->m_pFolder->writeXmlA(file, sRet);
}
};
#endif //_XML_RELS_H_

View File

@ -1,21 +1,21 @@
#include "./XmlTransform.h"
IXmlTransform* IXmlTransform::GetFromType(const std::string& alg)
IXmlTransform* IXmlTransform::GetFromType(const std::string& alg, CManifestFileInfo* pManifestFileInfo)
{
if (true)
{
CXmlTransformRelationship* transform = new CXmlTransformRelationship();
if (transform->m_algorithm == alg)
return transform;
RELEASEOBJECT(transform);
}
if (true)
{
CXmlTransformC14N* transform = new CXmlTransformC14N();
if (transform->CheckC14NTransform(alg))
return transform;
RELEASEOBJECT(transform);
}
if (true)
{
CXmlTransformRelationship* transform = new CXmlTransformRelationship(pManifestFileInfo);
if (transform->m_algorithm == alg)
return transform;
RELEASEOBJECT(transform);
}
if (true)
{
CXmlTransformC14N* transform = new CXmlTransformC14N();
if (transform->CheckC14NTransform(alg))
return transform;
RELEASEOBJECT(transform);
}
return NULL;
return NULL;
}

View File

@ -6,184 +6,185 @@
class IXmlTransform
{
protected:
std::string m_algorithm;
std::string m_algorithm;
public:
IXmlTransform()
{
m_algorithm = "";
}
virtual ~IXmlTransform()
{
}
IXmlTransform()
{
m_algorithm = "";
}
virtual ~IXmlTransform()
{
}
public:
virtual std::string Transform(const std::string& sXml) = 0;
virtual void LoadFromXml(XmlUtils::CXmlNode& node) = 0;
virtual std::string Transform(const std::string& sXml) = 0;
virtual void LoadFromXml(XmlUtils::CXmlNode& node) = 0;
static IXmlTransform* GetFromType(const std::string& alg);
static IXmlTransform* GetFromType(const std::string& alg, CManifestFileInfo* pManifestFileInfo);
};
class CXmlTransformRelationship : public IXmlTransform
{
protected:
std::map<std::wstring, bool> m_arIds;
CManifestFileInfo* m_pManifestFileInfo;
std::set<std::wstring> m_arIds;
public:
CXmlTransformRelationship() : IXmlTransform()
{
m_algorithm = "http://schemas.openxmlformats.org/package/2006/RelationshipTransform";
}
CXmlTransformRelationship(CManifestFileInfo* pManifestFileInfo) : IXmlTransform()
{
m_pManifestFileInfo = pManifestFileInfo;
m_algorithm = "http://schemas.openxmlformats.org/package/2006/RelationshipTransform";
}
virtual std::string Transform(const std::string& xml)
{
COOXMLRelationships _rels(xml, &m_arIds);
return U_TO_UTF8(_rels.GetXml());
}
virtual std::string Transform(const std::string& xml)
{
COOXMLRelationships _rels(xml, m_pManifestFileInfo, &m_arIds);
return U_TO_UTF8(_rels.GetXml());
}
virtual void LoadFromXml(XmlUtils::CXmlNode& node)
{
std::vector<XmlUtils::CXmlNode> oNodesIds;
node.GetChilds(oNodesIds);
virtual void LoadFromXml(XmlUtils::CXmlNode& node)
{
std::vector<XmlUtils::CXmlNode> oNodesIds;
node.GetChilds(oNodesIds);
size_t nCount = oNodesIds.size();
for (size_t i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode _node = oNodesIds[i];
size_t nCount = oNodesIds.size();
for (size_t i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode& _node = oNodesIds[i];
std::wstring sType = _node.GetAttribute("SourceId");
if (!sType.empty())
m_arIds.insert(std::pair<std::wstring, bool>(sType, true));
}
}
std::wstring sType = _node.GetAttribute("SourceId");
if (!sType.empty())
m_arIds.insert(sType);
}
}
};
class CXmlTransformC14N : public IXmlTransform
{
protected:
int m_mode;
bool m_comments;
int m_mode;
bool m_comments;
public:
CXmlTransformC14N() : IXmlTransform()
{
m_mode = -1;
m_comments = false;
}
CXmlTransformC14N() : IXmlTransform()
{
m_mode = -1;
m_comments = false;
}
bool CheckC14NTransform(const std::string& alg)
{
m_mode = -1;
if ("http://www.w3.org/TR/2001/REC-xml-c14n-20010315" == alg)
{
m_mode = XmlUtils::XML_C14N_1_0;
m_comments = false;
}
else if ("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" == alg)
{
m_mode = XmlUtils::XML_C14N_1_0;
m_comments = true;
}
else if ("http://www.w3.org/2006/12/xml-c14n11" == alg)
{
m_mode = XmlUtils::XML_C14N_1_1;
m_comments = false;
}
else if ("http://www.w3.org/2006/12/xml-c14n11#WithComments" == alg)
{
m_mode = XmlUtils::XML_C14N_1_1;
m_comments = true;
}
else if ("http://www.w3.org/2001/10/xml-exc-c14n#" == alg)
{
m_mode = XmlUtils::XML_C14N_EXCLUSIVE_1_0;
m_comments = false;
}
else if ("http://www.w3.org/2001/10/xml-exc-c14n#WithComments" == alg)
{
m_mode = XmlUtils::XML_C14N_EXCLUSIVE_1_0;
m_comments = true;
}
return (-1 != m_mode) ? true : false;
}
bool CheckC14NTransform(const std::string& alg)
{
m_mode = -1;
if ("http://www.w3.org/TR/2001/REC-xml-c14n-20010315" == alg)
{
m_mode = XmlUtils::XML_C14N_1_0;
m_comments = false;
}
else if ("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" == alg)
{
m_mode = XmlUtils::XML_C14N_1_0;
m_comments = true;
}
else if ("http://www.w3.org/2006/12/xml-c14n11" == alg)
{
m_mode = XmlUtils::XML_C14N_1_1;
m_comments = false;
}
else if ("http://www.w3.org/2006/12/xml-c14n11#WithComments" == alg)
{
m_mode = XmlUtils::XML_C14N_1_1;
m_comments = true;
}
else if ("http://www.w3.org/2001/10/xml-exc-c14n#" == alg)
{
m_mode = XmlUtils::XML_C14N_EXCLUSIVE_1_0;
m_comments = false;
}
else if ("http://www.w3.org/2001/10/xml-exc-c14n#WithComments" == alg)
{
m_mode = XmlUtils::XML_C14N_EXCLUSIVE_1_0;
m_comments = true;
}
return (-1 != m_mode) ? true : false;
}
virtual std::string Transform(const std::string& xml)
{
if (-1 == m_mode)
return xml;
return XmlUtils::NSXmlCanonicalizator::Execute(xml, m_mode, m_comments);
}
virtual std::string Transform(const std::string& xml)
{
if (-1 == m_mode)
return xml;
return XmlUtils::NSXmlCanonicalizator::Execute(xml, m_mode, m_comments);
}
virtual void LoadFromXml(XmlUtils::CXmlNode& node)
{
// none
XML_UNUSED(node);
}
virtual void LoadFromXml(XmlUtils::CXmlNode& node)
{
// none
XML_UNUSED(node);
}
};
class CXmlTransforms
{
protected:
std::vector<IXmlTransform*> m_transforms;
bool m_valid;
std::vector<IXmlTransform*> m_transforms;
bool m_valid;
public:
CXmlTransforms()
{
m_valid = true;
}
CXmlTransforms()
{
m_valid = true;
}
CXmlTransforms(XmlUtils::CXmlNode& node)
{
m_valid = true;
CXmlTransforms(XmlUtils::CXmlNode& node, CManifestFileInfo* pManifestInfo)
{
m_valid = true;
std::vector<XmlUtils::CXmlNode> oNodes = node.GetNodes(L"Transform");
size_t nCount = oNodes.size();
for (size_t i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode &nodeTransform = oNodes[i];
std::vector<XmlUtils::CXmlNode> oNodes = node.GetNodes(L"Transform");
size_t nCount = oNodes.size();
for (size_t i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode nodeTransform = oNodes[i];
IXmlTransform* pTransform = IXmlTransform::GetFromType(nodeTransform.GetAttributeA("Algorithm"));
if (NULL == pTransform)
{
m_valid = false;
return;
}
IXmlTransform* pTransform = IXmlTransform::GetFromType(nodeTransform.GetAttributeA("Algorithm"), pManifestInfo);
if (NULL == pTransform)
{
m_valid = false;
return;
}
pTransform->LoadFromXml(nodeTransform);
m_transforms.push_back(pTransform);
}
}
pTransform->LoadFromXml(nodeTransform);
m_transforms.push_back(pTransform);
}
}
~CXmlTransforms()
{
for (std::vector<IXmlTransform*>::iterator i = m_transforms.begin(); i != m_transforms.end(); i++)
{
IXmlTransform* t = *i;
RELEASEOBJECT(t);
}
m_transforms.clear();
}
~CXmlTransforms()
{
for (std::vector<IXmlTransform*>::iterator i = m_transforms.begin(); i != m_transforms.end(); i++)
{
IXmlTransform* t = *i;
RELEASEOBJECT(t);
}
m_transforms.clear();
}
bool GetValid()
{
return m_valid;
}
bool GetValid()
{
return m_valid;
}
std::string Transform(const std::string& xml)
{
std::string sResult = xml;
for (std::vector<IXmlTransform*>::iterator i = m_transforms.begin(); i != m_transforms.end(); i++)
{
sResult = (*i)->Transform(sResult);
}
return sResult;
}
std::string Transform(const std::string& xml)
{
std::string sResult = xml;
for (std::vector<IXmlTransform*>::iterator i = m_transforms.begin(); i != m_transforms.end(); i++)
{
sResult = (*i)->Transform(sResult);
}
return sResult;
}
void AddTransform(IXmlTransform* transform)
{
m_transforms.push_back(transform);
}
void AddTransform(IXmlTransform* transform)
{
m_transforms.push_back(transform);
}
};
#endif //_XML_TRANSFORM_H_

View File

@ -0,0 +1,92 @@
#pragma once
#include "./../include/CertificateCommon.h"
#include "../../../../OfficeUtils/src/ZipFolder.h"
#include "./XmlTransform.h"
#include <cstdio>
#include <ctime>
#include <time.h>
class CSignFolderFiles
{
public:
std::map<std::wstring, std::wstring> m_content_types;
std::vector<std::wstring> m_rels;
std::vector<std::wstring> m_files;
public:
CSignFolderFiles() {}
~CSignFolderFiles() {}
public:
static bool CheckNeedSign(const std::wstring& sCheckFile)
{
if (0 == sCheckFile.find(L"_xmlsignatures") ||
0 == sCheckFile.find(L"docProps") ||
0 == sCheckFile.find(L"[Content_Types].xml") ||
0 == sCheckFile.find(L"[trash]"))
return false;
return true;
}
void Folder_Parse(IFolder* pFolder, bool bIsAddSlash = false)
{
// 1) Parse files in directory
std::vector<std::wstring> files = pFolder->getFiles(L"", true);
// 2) Check each file
std::wstring sFolder = L"";
for (std::vector<std::wstring>::iterator i = files.begin(); i != files.end(); i++)
{
std::wstring sCheckFile = *i;
// make cool filename
sCheckFile = pFolder->getLocalFilePath(sCheckFile);
// check needed file
if (!CheckNeedSign(sCheckFile))
continue;
// check rels and add to needed array
std::wstring::size_type posExt = sCheckFile.rfind(L".");
if (std::wstring::npos == posExt)
continue;
std::wstring sExt = sCheckFile.substr(posExt + 1);
if (bIsAddSlash)
sCheckFile = L"/" + sCheckFile;
if (sExt == L"rels")
m_rels.push_back(sCheckFile);
else
m_files.push_back(sCheckFile);
}
std::sort(m_rels.begin(), m_rels.end());
std::sort(m_files.begin(), m_files.end());
}
void Folder_ParseContentTypes(IFolder* pFolder)
{
XmlUtils::CXmlNode oNode = pFolder->getNodeFromFile(L"/[Content_Types].xml");
std::vector<XmlUtils::CXmlNode> nodesDefaults = oNode.GetNodes(L"Default");
std::vector<XmlUtils::CXmlNode> nodesOverrides = oNode.GetNodes(L"Override");
size_t nCount = nodesDefaults.size();
for (size_t i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode node = nodesDefaults[i];
m_content_types.insert(std::pair<std::wstring, std::wstring>(node.GetAttribute("Extension"), node.GetAttribute("ContentType")));
}
nCount = nodesOverrides.size();
for (size_t i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode node = nodesOverrides[i];
m_content_types.insert(std::pair<std::wstring, std::wstring>(node.GetAttribute("PartName"), node.GetAttribute("ContentType")));
}
}
};