Compare commits

...

7 Commits

Author SHA1 Message Date
c2c6430495 . 2017-04-17 18:55:02 +03:00
9ecf5b7834 Merge pull request #23 from ONLYOFFICE/hotfix/v4.3.2
Hotfix/v4.3.2
2017-04-17 17:12:30 +03:00
1d003863dd . 2017-04-17 17:10:12 +03:00
774561bd00 Merge branch 'develop' into hotfix/v4.3.2 2017-04-17 16:56:05 +03:00
d356a305b9 tests (mscrypto) 2017-04-17 16:45:35 +03:00
51c77c3a85 Fixed downloading icu binaries from sourceforge 2017-04-05 19:59:56 +03:00
4326a7d258 fix bug 34695 2017-04-05 19:48:02 +03:00
12 changed files with 793 additions and 39 deletions

View File

@ -45,13 +45,13 @@ namespace Writers
int index;
};
std::vector<_chartElem> m_aCharts;
int nChartCount;
public:
std::wstring m_sDir;
int nEmbeddedCount;
ChartWriter(std::wstring sDir) : m_sDir(sDir)
{
nChartCount = 0;
nEmbeddedCount = 1000;
}
~ChartWriter()
{
@ -80,30 +80,20 @@ namespace Writers
}
return true;
}
void AddChart(std::wstring& content, std::wstring& sRelsName, std::wstring& sFileName, int& index)
void AddChart(std::wstring& content, std::wstring& sRelsName, std::wstring& sFileName, int index)
{
_chartElem oChartElem;
oChartElem.content = content;
oChartElem.index = nChartCount + 1;
nChartCount++;
oChartElem.index = index;
oChartElem.filename = L"chart" + std::to_wstring(oChartElem.index) + L".xml";
sRelsName = L"charts/" + oChartElem.filename;
sFileName = oChartElem.filename;
index = oChartElem.index;
m_aCharts.push_back(oChartElem);
}
int getChartCount()
{
return nChartCount;
}
void setChartCount(int val)
{
nChartCount = val;
}
};
}
#endif // #ifndef CHART_WRITER

View File

@ -6292,15 +6292,11 @@ public:
std::wstring sDrawingProperty = oCDrawingProperty.Write();
if(false == sDrawingProperty.empty())
{
m_oFileWriter.m_pDrawingConverter->SetDocumentChartsCount(m_oFileWriter.m_oChartWriter.getChartCount());
long nCurPos = m_oBufferedStream.GetPos();
std::wstring sDrawingXml;
m_oFileWriter.m_pDrawingConverter->SaveObjectEx(oCDrawingProperty.DataPos, oCDrawingProperty.DataLength, sDrawingProperty, XMLWRITER_DOC_TYPE_DOCX, sDrawingXml);
m_oBufferedStream.Seek(nCurPos);
m_oFileWriter.m_oChartWriter.setChartCount(m_oFileWriter.m_pDrawingConverter->GetDocumentChartsCount());
if( false == sDrawingXml.empty())
{
GetRunStringWriter().WriteString(sDrawingXml);
@ -6606,8 +6602,11 @@ public:
OOX::Spreadsheet::CChartSpace* pChartSpace = new OOX::Spreadsheet::CChartSpace();
oBinaryChartReader.ReadCT_ChartSpace(length, &pChartSpace->m_oChartSpace);
//save xlsx
std::wstring sXlsxFilename = L"Microsoft_Excel_Worksheet" + std::to_wstring(m_oFileWriter.m_oChartWriter.getChartCount() + 1) + L".xlsx";
//save xlsx
_INT32 nChartCount = m_oFileWriter.m_pDrawingConverter->GetDocumentChartsCount();
_INT32 nChartIndex = nChartCount + 1;
m_oFileWriter.m_pDrawingConverter->SetDocumentChartsCount(nChartCount + 1);
std::wstring sXlsxFilename = L"Microsoft_Excel_Worksheet" + std::to_wstring(nChartIndex) + L".xlsx";
std::wstring sXlsxPath = pathChartsWorksheetDir.GetPath() + FILE_SEPARATOR_STR + sXlsxFilename;
BinXlsxRW::CXlsxSerializer oXlsxSerializer;
oXlsxSerializer.writeChartXlsx(sXlsxPath, *pChartSpace);
@ -6632,7 +6631,6 @@ public:
std::wstring sFilename;
std::wstring sRelsName;
int nChartIndex;
std::wstring sContent = sw.GetData();
m_oFileWriter.m_oChartWriter.AddChart(sContent, sRelsName, sFilename, nChartIndex);
@ -6826,8 +6824,7 @@ public:
std::wstring strDstEmbeddedTemp = strDstEmbedded + FILE_SEPARATOR_STR + L"Temp";
NSDirectory::CreateDirectory(strDstEmbeddedTemp);
int id = m_oFileWriter.m_oChartWriter.getChartCount();
m_oFileWriter.m_oChartWriter.setChartCount(id + 1);
int id = m_oFileWriter.m_oChartWriter.nEmbeddedCount++;
std::wstring sXlsxFilename = L"Microsoft_Excel_Worksheet" + std::to_wstring( id + 1) + L".xlsx";
BinXlsxRW::SaveParams oSaveParams(m_oFileWriter.m_sThemePath, m_oFileWriter.m_pDrawingConverter->GetContentTypes());//???

View File

@ -371,16 +371,21 @@ void PptxConverter::convert_slides()
//nullable_bool showMasterSp;
convert_slide (slide->cSld.GetPointer(), true);
convert (slide->transition.GetPointer());
convert (slide->comments.operator->());
convert (slide->Note.operator->());
convert (slide->transition.GetPointer());
convert (slide->timing.GetPointer());
//nullable<Logic::Timing> timing;
//smart_ptr<NotesSlide> Note;
odp_context->end_slide();
}
}
void PptxConverter::convert(PPTX::NotesSlide *oox_note)
{
if (!oox_note) return;
}
void PptxConverter::convert(OOX::WritingElement *oox_unknown)
{
if (oox_unknown == NULL)return;
@ -433,6 +438,16 @@ void PptxConverter::convert(PPTX::Logic::Transition *oox_transition)
if (!oox_transition) return;
}
void PptxConverter::convert(PPTX::Logic::Timing *oox_timing)
{
if (!oox_timing) return;
if (!oox_timing->tnLst.IsInit()) return;
for (size_t i = 0; i < oox_timing->tnLst->list.size(); i++)
{
//oox_timing->tnLst[0]
}
}
void PptxConverter::convert(PPTX::Logic::TableProperties *oox_table_pr)
{

View File

@ -47,6 +47,7 @@ namespace OOX
namespace PPTX
{
class TableStyles;
class NotesSlide;
class Presentation;
class Comments;
class Folder;
@ -104,12 +105,14 @@ namespace Oox2Odf
void convert(OOX::WritingElement *oox_unknown);
void convert_slide (PPTX::Logic::CSld *oox_slide, bool bPlaceholders = true);
void convert_layout (PPTX::Logic::CSld *oox_slide);
void convert (PPTX::Comments *oox_comments);
void convert_slide (PPTX::Logic::CSld *oox_slide, bool bPlaceholders = true);
void convert_layout (PPTX::Logic::CSld *oox_slide);
void convert (PPTX::Comments *oox_comments);
void convert (PPTX::NotesSlide *oox_note);
void convert(PPTX::Logic::Bg *oox_background);
void convert(PPTX::Logic::Transition *oox_transition);
void convert(PPTX::Logic::Timing *oox_timing);
void convert(PPTX::Logic::Table *oox_table);
void convert(PPTX::Logic::TableRow *oox_table_row);

View File

@ -47,7 +47,6 @@ namespace PPTX
explicit TimeNodeBase(XmlUtils::CXmlNode& node);
const TimeNodeBase& operator =(XmlUtils::CXmlNode& node);
public:
virtual void fromXML(XmlUtils::CXmlNode& node);
virtual void GetTimeNodeFrom(XmlUtils::CXmlNode& element);
virtual bool is_init()const{return (m_node.IsInit());};
@ -61,7 +60,6 @@ namespace PPTX
template<class T> AVSINLINE const T& as() const { return m_node.as<T>(); }
virtual std::wstring toXML() const;
//public:
private:
smart_ptr<WrapperWritingElement> m_node;
protected:

View File

@ -46,7 +46,6 @@ namespace PPTX
public:
PPTX_LOGIC_BASE(Timing)
public:
virtual void fromXML(XmlUtils::CXmlNode& node)
{
tnLst = node.ReadNode(_T("p:tnLst"));
@ -76,7 +75,6 @@ namespace PPTX
pWriter->EndNode(_T("p:timing"));
}
public:
nullable<TnLst> tnLst;
nullable<BldLst> bldLst;
protected:

View File

@ -55,8 +55,6 @@ namespace PPTX
return *this;
}
public:
virtual void fromXML(XmlUtils::CXmlNode& node)
{
name = XmlUtils::GetNameNoNS(node.GetName());
@ -72,9 +70,8 @@ namespace PPTX
return XmlUtils::CreateNode(_T("p:") + name, oValue);
}
public:
std::vector<TimeNodeBase> list;
std::wstring name;
std::wstring name;
protected:
virtual void FillParentPointersForChilds()
{

View File

@ -23,7 +23,7 @@ if "%platform%" == "win_64" (
if exist "%SCRIPTPATH%%platform%\icu.zip" (
echo "icu already downloaded"
) else (
Powershell.exe Invoke-WebRequest -OutFile %platform%\icu.zip "%URL%"
Powershell.exe Invoke-WebRequest -OutFile %platform%\icu.zip -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::FireFox "%URL%"
)
SET UNSIP_PROGRAMM="C:\Program Files\7-Zip\7z.exe"

View File

@ -0,0 +1,274 @@
/**
* XML Security Library example: Signing a file with a dynamicaly created template and an X509 certificate.
*
* Signs a file using a dynamicaly created template, key from PEM file and
* an X509 certificate. The signature has one reference with one enveloped
* transform to sign the whole document except the <dsig:Signature/> node
* itself. The key certificate is written in the <dsig:X509Data/> node.
*
* This example was developed and tested with OpenSSL crypto library. The
* certificates management policies for another crypto library may break it.
*
* Usage:
* sign3 <xml-doc> <pem-key>
*
* Example:
* ./sign3 sign3-doc.xml rsakey.pem rsacert.pem > sign3-res.xml
*
* The result signature could be validated using verify3 example:
* ./verify3 sign3-res.xml ca2cert.pem cacert.pem
*
* This is free software; see Copyright file in the source
* distribution for preciese wording.
*
* Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <libxml/tree.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#ifndef XMLSEC_NO_XSLT
#include <libxslt/xslt.h>
#include <libxslt/security.h>
#endif /* XMLSEC_NO_XSLT */
#include <xmlsec/xmlsec.h>
#include <xmlsec/xmltree.h>
#include <xmlsec/xmldsig.h>
#include <xmlsec/templates.h>
#include <xmlsec/crypto.h>
int sign_file(const char* xml_file, const char* key_file, const char* cert_file);
int
main(int argc, char **argv) {
#ifndef XMLSEC_NO_XSLT
xsltSecurityPrefsPtr xsltSecPrefs = NULL;
#endif /* XMLSEC_NO_XSLT */
assert(argv);
if(argc != 4) {
fprintf(stderr, "Error: wrong number of arguments.\n");
fprintf(stderr, "Usage: %s <xml-file> <key-file> <cert-file>\n", argv[0]);
return(1);
}
/* Init libxml and libxslt libraries */
xmlInitParser();
//LIBXML_TEST_VERSION
//xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
xmlSubstituteEntitiesDefault(1);
#ifndef XMLSEC_NO_XSLT
xmlIndentTreeOutput = 1;
#endif /* XMLSEC_NO_XSLT */
/* Init libxslt */
#ifndef XMLSEC_NO_XSLT
/* disable everything */
xsltSecPrefs = xsltNewSecurityPrefs();
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid);
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid);
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid);
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid);
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid);
xsltSetDefaultSecurityPrefs(xsltSecPrefs);
#endif /* XMLSEC_NO_XSLT */
/* Init xmlsec library */
if(xmlSecInit() < 0) {
fprintf(stderr, "Error: xmlsec initialization failed.\n");
return(-1);
}
/* Check loaded library version */
if(xmlSecCheckVersion() != 1) {
fprintf(stderr, "Error: loaded xmlsec library version is not compatible.\n");
return(-1);
}
/* Load default crypto engine if we are supporting dynamic
* loading for xmlsec-crypto libraries. Use the crypto library
* name ("openssl", "nss", etc.) to load corresponding
* xmlsec-crypto library.
*/
#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
if(xmlSecCryptoDLLoadLibrary(NULL) < 0) {
fprintf(stderr, "Error: unable to load default xmlsec-crypto library. Make sure\n"
"that you have it installed and check shared libraries path\n"
"(LD_LIBRARY_PATH) envornment variable.\n");
return(-1);
}
#endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
/* Init crypto library */
if(xmlSecCryptoAppInit(NULL) < 0) {
fprintf(stderr, "Error: crypto initialization failed.\n");
return(-1);
}
/* Init xmlsec-crypto library */
if(xmlSecCryptoInit() < 0) {
fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n");
return(-1);
}
if(sign_file(argv[1], argv[2], argv[3]) < 0) {
return(-1);
}
/* Shutdown xmlsec-crypto library */
xmlSecCryptoShutdown();
/* Shutdown crypto library */
xmlSecCryptoAppShutdown();
/* Shutdown xmlsec library */
xmlSecShutdown();
/* Shutdown libxslt/libxml */
#ifndef XMLSEC_NO_XSLT
xsltFreeSecurityPrefs(xsltSecPrefs);
xsltCleanupGlobals();
#endif /* XMLSEC_NO_XSLT */
xmlCleanupParser();
return(0);
}
/**
* sign_file:
* @xml_file: the XML file name.
* @key_file: the PEM private key file name.
* @cert_file: the x509 certificate PEM file.
*
* Signs the @xml_file using private key from @key_file and dynamicaly
* created enveloped signature template. The certificate from @cert_file
* is placed in the <dsig:X509Data/> node.
*
* Returns 0 on success or a negative value if an error occurs.
*/
int
sign_file(const char* xml_file, const char* key_file, const char* cert_file) {
xmlDocPtr doc = NULL;
xmlNodePtr signNode = NULL;
xmlNodePtr refNode = NULL;
xmlNodePtr keyInfoNode = NULL;
xmlNodePtr x509DataNode = NULL;
xmlSecDSigCtxPtr dsigCtx = NULL;
int res = -1;
assert(xml_file);
assert(key_file);
assert(cert_file);
/* load doc file */
doc = xmlParseFile(xml_file);
if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file);
goto done;
}
/* create signature template for RSA-SHA1 enveloped signature */
signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
xmlSecTransformRsaSha1Id, NULL);
if(signNode == NULL) {
fprintf(stderr, "Error: failed to create signature template\n");
goto done;
}
/* add <dsig:Signature/> node to the doc */
xmlAddChild(xmlDocGetRootElement(doc), signNode);
/* add reference */
refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id,
NULL, NULL, NULL);
if(refNode == NULL) {
fprintf(stderr, "Error: failed to add reference to signature template\n");
goto done;
}
/* add enveloped transform */
if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) {
fprintf(stderr, "Error: failed to add enveloped transform to reference\n");
goto done;
}
/* add <dsig:KeyInfo/> and <dsig:X509Data/> */
keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL);
if(keyInfoNode == NULL) {
fprintf(stderr, "Error: failed to add key info\n");
goto done;
}
x509DataNode = xmlSecTmplKeyInfoAddX509Data(keyInfoNode);
if(x509DataNode == NULL) {
fprintf(stderr, "Error: failed to add X509Data node\n");
goto done;
}
if(xmlSecTmplX509DataAddSubjectName(x509DataNode) == NULL) {
fprintf(stderr, "Error: failed to add X509SubjectName node\n");
goto done;
}
if(xmlSecTmplX509DataAddCertificate(x509DataNode) == NULL) {
fprintf(stderr, "Error: failed to add X509Certificate node\n");
goto done;
}
/* create signature context, we don't need keys manager in this example */
dsigCtx = xmlSecDSigCtxCreate(NULL);
if(dsigCtx == NULL) {
fprintf(stderr,"Error: failed to create signature context\n");
goto done;
}
/* load private key, assuming that there is not password */
dsigCtx->signKey = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatPem, NULL, NULL, NULL);
if(dsigCtx->signKey == NULL) {
fprintf(stderr,"Error: failed to load private pem key from \"%s\"\n", key_file);
goto done;
}
/* load certificate and add to the key */
if(xmlSecCryptoAppKeyCertLoad(dsigCtx->signKey, cert_file, xmlSecKeyDataFormatPem) < 0) {
fprintf(stderr,"Error: failed to load pem certificate \"%s\"\n", cert_file);
goto done;
}
/* set key name to the file name, this is just an example! */
if(xmlSecKeySetName(dsigCtx->signKey, (const xmlChar*)key_file) < 0) {
fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file);
goto done;
}
/* sign the template */
if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) {
fprintf(stderr,"Error: signature failed\n");
goto done;
}
/* print signed document to stdout */
xmlDocDump(stdout, doc);
/* success */
res = 0;
done:
/* cleanup */
if(dsigCtx != NULL) {
xmlSecDSigCtxDestroy(dsigCtx);
}
if(doc != NULL) {
xmlFreeDoc(doc);
}
return(res);
}

View File

@ -0,0 +1,45 @@
QT -= core gui
TARGET = test
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
DEFINES += UNICODE
CORE_ROOT_DIR = $$PWD/../../../..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
#DEFINES += XMLSEC_CRYPTO_DYNAMIC_LOADING
DEFINES += XMLSEC_CRYPTO_MSCRYPTO
INCLUDEPATH += \
$$CORE_ROOT_DIR/DesktopEditor/xml/libxml2/include \
$$CORE_ROOT_DIR/DesktopEditor/xml/libxml2/include/libxml \
\
$$CORE_ROOT_DIR/DesktopEditor/xmlsec/xmlsec/include
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
DEFINES += XMLSEC_NO_XSLT
DEFINES += XMLSEC_STATIC
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -llibxmlsec
LIBS += -lcrypt32
LIBS += -lcryptui
LIBS += -lAdvapi32
SOURCES += main.cpp

View File

@ -0,0 +1,426 @@
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <cryptuiapi.h>
#include <tchar.h>
#include <string>
#include "../../../common/File.h"
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "cryptui.lib")
#pragma comment (lib, "Advapi32.lib")
//#define ENUMS_CERTS
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);
bool Sign(HCERTSTORE hStoreHandle, PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile);
bool Verify(HCERTSTORE hStoreHandle, PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile);
void main(void)
{
//-------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// This program lists all of the certificates in a system certificate
// store and all of the property identifier numbers of those
// certificates. It also demonstrates the use of two
// UI functions. One, CryptUIDlgSelectCertificateFromStore,
// displays the certificates in a store
// and allows the user to select one of them,
// The other, CryptUIDlgViewContext,
// displays the contents of a single certificate.
//-------------------------------------------------------------------
// Declare and initialize variables.
HCERTSTORE hCertStore;
PCCERT_CONTEXT pCertContext=NULL;
char pszNameString[256];
char pszStoreName[256];
void* pvData;
DWORD cbData;
DWORD dwPropId = 0;
// Zero must be used on the first
// call to the function. After that,
// the last returned property identifier is passed.
//-------------------------------------------------------------------
// Begin processing and Get the name of the system certificate store
// to be enumerated. Output here is to stderr so that the program
// can be run from the command line and stdout can be redirected
// to a file.
/*
fprintf(stderr,"Please enter the store name:");
gets_s(pszStoreName, sizeof(pszStoreName));
fprintf(stderr,"The store name is %s.\n",pszStoreName);
*/
pszStoreName[0] = 'M';
pszStoreName[1] = 'Y';
pszStoreName[2] = '\0';
//-------------------------------------------------------------------
// Open a system certificate store.
if ( hCertStore = CertOpenSystemStore(NULL, pszStoreName))
{
fprintf(stderr,"The %s store has been opened. \n", pszStoreName);
}
else
{
// If the store was not opened, exit to an error routine.
MyHandleError("The store was not opened.");
}
//-------------------------------------------------------------------
// Use CertEnumCertificatesInStore to get the certificates
// from the open store. pCertContext must be reset to
// NULL to retrieve the first certificate in the store.
// pCertContext = NULL;
#ifdef ENUMS_CERTS
while(pCertContext= CertEnumCertificatesInStore(
hCertStore,
pCertContext))
{
//-------------------------------------------------------------------
// A certificate was retrieved. Continue.
//-------------------------------------------------------------------
// Display the certificate.
if ( CryptUIDlgViewContext(
CERT_STORE_CERTIFICATE_CONTEXT,
pCertContext,
NULL,
NULL,
0,
NULL))
{
// printf("OK\n");
}
else
{
MyHandleError("UI failed.");
}
if(CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
pszNameString,
128))
{
printf("\nCertificate for %s \n",pszNameString);
}
else
fprintf(stderr,"CertGetName failed. \n");
//-------------------------------------------------------------------
// Loop to find all of the property identifiers for the specified
// certificate. The loop continues until
// CertEnumCertificateContextProperties returns zero.
while(dwPropId = CertEnumCertificateContextProperties(
pCertContext, // The context whose properties are to be listed.
dwPropId)) // Number of the last property found.
// This must be zero to find the first
// property identifier.
{
//-------------------------------------------------------------------
// When the loop is executed, a property identifier has been found.
// Print the property number.
printf("Property # %d found->", dwPropId);
//-------------------------------------------------------------------
// Indicate the kind of property found.
switch(dwPropId)
{
case CERT_FRIENDLY_NAME_PROP_ID:
{
printf("Display name: ");
break;
}
case CERT_SIGNATURE_HASH_PROP_ID:
{
printf("Signature hash identifier ");
break;
}
case CERT_KEY_PROV_HANDLE_PROP_ID:
{
printf("KEY PROVE HANDLE");
break;
}
case CERT_KEY_PROV_INFO_PROP_ID:
{
printf("KEY PROV INFO PROP ID ");
break;
}
case CERT_SHA1_HASH_PROP_ID:
{
printf("SHA1 HASH identifier");
break;
}
case CERT_MD5_HASH_PROP_ID:
{
printf("md5 hash identifier ");
break;
}
case CERT_KEY_CONTEXT_PROP_ID:
{
printf("KEY CONTEXT PROP identifier");
break;
}
case CERT_KEY_SPEC_PROP_ID:
{
printf("KEY SPEC PROP identifier");
break;
}
case CERT_ENHKEY_USAGE_PROP_ID:
{
printf("ENHKEY USAGE PROP identifier");
break;
}
case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
{
printf("NEXT UPDATE LOCATION PROP identifier");
break;
}
case CERT_PVK_FILE_PROP_ID:
{
printf("PVK FILE PROP identifier ");
break;
}
case CERT_DESCRIPTION_PROP_ID:
{
printf("DESCRIPTION PROP identifier ");
break;
}
case CERT_ACCESS_STATE_PROP_ID:
{
printf("ACCESS STATE PROP identifier ");
break;
}
case CERT_SMART_CARD_DATA_PROP_ID:
{
printf("SMART_CARD DATA PROP identifier ");
break;
}
case CERT_EFS_PROP_ID:
{
printf("EFS PROP identifier ");
break;
}
case CERT_FORTEZZA_DATA_PROP_ID:
{
printf("FORTEZZA DATA PROP identifier ");
break;
}
case CERT_ARCHIVED_PROP_ID:
{
printf("ARCHIVED PROP identifier ");
break;
}
case CERT_KEY_IDENTIFIER_PROP_ID:
{
printf("KEY IDENTIFIER PROP identifier ");
break;
}
case CERT_AUTO_ENROLL_PROP_ID:
{
printf("AUTO ENROLL identifier. ");
break;
}
} // End switch.
//-------------------------------------------------------------------
// Retrieve information on the property by first getting the
// property size.
// For more information, see CertGetCertificateContextProperty.
if(CertGetCertificateContextProperty(
pCertContext,
dwPropId ,
NULL,
&cbData))
{
// Continue.
}
else
{
// If the first call to the function failed,
// exit to an error routine.
MyHandleError("Call #1 to GetCertContextProperty failed.");
}
//-------------------------------------------------------------------
// The call succeeded. Use the size to allocate memory
// for the property.
if(pvData = (void*)malloc(cbData))
{
// Memory is allocated. Continue.
}
else
{
// If memory allocation failed, exit to an error routine.
MyHandleError("Memory allocation failed.");
}
//----------------------------------------------------------------
// Allocation succeeded. Retrieve the property data.
if(CertGetCertificateContextProperty(
pCertContext,
dwPropId,
pvData,
&cbData))
{
// The data has been retrieved. Continue.
}
else
{
// If an error occurred in the second call,
// exit to an error routine.
MyHandleError("Call #2 failed.");
}
//---------------------------------------------------------------
// Show the results.
printf("The Property Content is %d \n", pvData);
//----------------------------------------------------------------
// Free the certificate context property memory.
free(pvData);
} // End inner while.
} // End outer while.
#endif
//-------------------------------------------------------------------
// Select a new certificate by using the user interface.
if(!(pCertContext = CryptUIDlgSelectCertificateFromStore(hCertStore, NULL, NULL, NULL, CRYPTUI_SELECT_LOCATION_COLUMN, 0, NULL)))
{
MyHandleError("Select UI failed." );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool bRes = true;
bRes = Sign(hCertStore, pCertContext, NSFile::GetProcessDirectory() + L"/document.xml", NSFile::GetProcessDirectory() + L"/result.txt");
bRes = Verify(hCertStore, pCertContext, NSFile::GetProcessDirectory() + L"/document.xml", NSFile::GetProcessDirectory() + L"/result.txt");
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CertFreeCertificateContext(pCertContext);
CertCloseStore(hCertStore,0);
printf("The function completed successfully. \n");
}
void MyHandleError(LPTSTR psz)
{
_ftprintf(stderr, TEXT("An error occurred in the program. \n"));
_ftprintf(stderr, TEXT("%s\n"), psz);
_ftprintf(stderr, TEXT("Error number %x.\n"), GetLastError());
_ftprintf(stderr, TEXT("Program terminating. \n"));
exit(1);
} // End of MyHandleError.
bool Sign(HCERTSTORE hStoreHandle, PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile)
{
// Variables
HCRYPTPROV hCryptProv = NULL;
DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL;
BOOL bResult = FALSE;
DWORD dwSigLen = 0;
BYTE* pbSignature = NULL;
// Open the certificate store.
bResult = CryptAcquireCertificatePrivateKey(pCertContext, 0, NULL, &hCryptProv, &dwKeySpec, NULL);
bool bIsResult = ((dwKeySpec & AT_SIGNATURE) == AT_SIGNATURE);
// Create the hash object.
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
BYTE* pDataSrc = NULL;
DWORD dwFileSrcLen = 0;
NSFile::CFileBinary::ReadAllBytes(sFileXml, &pDataSrc, dwFileSrcLen);
bResult = CryptHashData(hHash, pDataSrc, dwFileSrcLen, 0);
// Sign the hash object
dwSigLen = 0;
bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &dwSigLen);
pbSignature = new BYTE[dwSigLen];
bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, pbSignature, &dwSigLen);
NSFile::CFileBinary oFile;
oFile.CreateFileW(sSignatureFile);
//oFile.WriteFile(pbSignature, dwSigLen);
char* pBase64 = NULL;
int nBase64Len = 0;
NSFile::CBase64Converter::Encode(pbSignature, (int)dwSigLen, pBase64, nBase64Len, NSBase64::B64_BASE64_FLAG_NONE);
oFile.WriteFile((BYTE*)pBase64, (DWORD)nBase64Len);
oFile.CloseFile();
delete[] pbSignature;
delete[] pDataSrc;
bResult = CryptDestroyHash(hHash);
return (bResult == TRUE);
}
bool Verify(HCERTSTORE hStoreHandle, PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile)
{
DWORD dwKeySpec = 0;
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hPubKey = NULL;
BOOL bResult = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
// Create the hash object.
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
BYTE* pDataSrc = NULL;
DWORD dwFileSrcLen = 0;
NSFile::CFileBinary::ReadAllBytes(sFileXml, &pDataSrc, dwFileSrcLen);
BYTE* pDataHashBase64 = NULL;
DWORD dwFileHashSrcLenBase64 = 0;
NSFile::CFileBinary::ReadAllBytes(sSignatureFile, &pDataHashBase64, dwFileHashSrcLenBase64);
BYTE* pDataHash = NULL;
DWORD dwHashLen = 0;
int nTmp = 0;
NSFile::CBase64Converter::Decode((char*)pDataHashBase64, (int)dwFileHashSrcLenBase64, pDataHash, nTmp);
dwHashLen = (DWORD)nTmp;
bResult = CryptHashData(hHash, pDataSrc, dwFileSrcLen, 0);
// Get the public key from the certificate
CryptImportPublicKeyInfo(hCryptProv, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey);
bResult = CryptVerifySignature(hHash, pDataHash, dwHashLen, hPubKey, NULL, 0);
delete[] pDataSrc;
delete[] pDataHash;
delete[] pDataHashBase64;
bResult = CryptDestroyHash(hHash);
return bResult;
}

View File

@ -0,0 +1,11 @@
QT -= core gui
TARGET = test
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
DEFINES -= UNICODE
SOURCES += main.cpp