Initial support for MS CryptoAPI added
XML hashing implemented with wxExtend's cryptographic classes now
This commit is contained in:
parent
40ffe7d7f8
commit
a2c8cfd710
@ -21,6 +21,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\src\appbar.cpp" />
|
<ClCompile Include="..\src\appbar.cpp" />
|
||||||
<ClCompile Include="..\src\comutils.cpp" />
|
<ClCompile Include="..\src\comutils.cpp" />
|
||||||
|
<ClCompile Include="..\src\crypto.cpp" />
|
||||||
<ClCompile Include="..\src\stdafx.cpp">
|
<ClCompile Include="..\src\stdafx.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
@ -33,6 +34,7 @@
|
|||||||
<ClInclude Include="..\include\wxex\appbar.h" />
|
<ClInclude Include="..\include\wxex\appbar.h" />
|
||||||
<ClInclude Include="..\include\wxex\common.h" />
|
<ClInclude Include="..\include\wxex\common.h" />
|
||||||
<ClInclude Include="..\include\wxex\comutils.h" />
|
<ClInclude Include="..\include\wxex\comutils.h" />
|
||||||
|
<ClInclude Include="..\include\wxex\crypto.h" />
|
||||||
<ClInclude Include="..\include\wxex\xml.h" />
|
<ClInclude Include="..\include\wxex\xml.h" />
|
||||||
<ClInclude Include="..\src\stdafx.h" />
|
<ClInclude Include="..\src\stdafx.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
<ClCompile Include="..\src\xml.cpp">
|
<ClCompile Include="..\src\xml.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\crypto.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\src\stdafx.h">
|
<ClInclude Include="..\src\stdafx.h">
|
||||||
@ -48,6 +51,9 @@
|
|||||||
<ClInclude Include="..\include\wxex\xml.h">
|
<ClInclude Include="..\include\wxex\xml.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\wxex\crypto.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\locale\wxExtend.pot">
|
<None Include="..\locale\wxExtend.pot">
|
||||||
|
260
include/wxex/crypto.h
Normal file
260
include/wxex/crypto.h
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 Amebis
|
||||||
|
|
||||||
|
This file is part of wxExtend.
|
||||||
|
|
||||||
|
wxExtend is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
wxExtend is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with wxExtend. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <wx/buffer.h>
|
||||||
|
#include <wx/string.h>
|
||||||
|
|
||||||
|
#include <Wincrypt.h>
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Cryptographics Session Base Class
|
||||||
|
///
|
||||||
|
class WXEXTEND_API wxCryptoSession
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
HCRYPTPROV m_h; ///< Session Handle
|
||||||
|
|
||||||
|
public:
|
||||||
|
wxCryptoSession();
|
||||||
|
virtual ~wxCryptoSession();
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Has the session creation been successful?
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true if creation succeeded
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
inline bool IsOk() const
|
||||||
|
{
|
||||||
|
return m_h != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns Session handle to be used in native API calls.
|
||||||
|
///
|
||||||
|
inline operator HCRYPTPROV() const
|
||||||
|
{
|
||||||
|
return m_h;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// RSA AES Cryptographics Session
|
||||||
|
///
|
||||||
|
class WXEXTEND_API wxCryptoSessionRSAAES : public wxCryptoSession
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxCryptoSessionRSAAES();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Cryptographics Hash Base
|
||||||
|
///
|
||||||
|
class WXEXTEND_API wxCryptoHash
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
HCRYPTHASH m_h; ///< Hash Handle
|
||||||
|
|
||||||
|
public:
|
||||||
|
wxCryptoHash();
|
||||||
|
virtual ~wxCryptoHash();
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Has the hash creation been successful?
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true if creation succeeded
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
inline bool IsOk() const
|
||||||
|
{
|
||||||
|
return m_h != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns Hash handle to be used in native API calls.
|
||||||
|
///
|
||||||
|
inline operator HCRYPTHASH() const
|
||||||
|
{
|
||||||
|
return m_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Hashes given block of data
|
||||||
|
///
|
||||||
|
/// \param[in] data Pointer to memory block
|
||||||
|
/// \param[in] size Size of memory block in bytes
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true if hashing succeeded
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool Hash(const void *data, size_t size);
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Hashes given block of data
|
||||||
|
///
|
||||||
|
/// \param[in] data Memory block
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true if hashing succeeded
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
inline bool Hash(const wxMemoryBuffer &data)
|
||||||
|
{
|
||||||
|
return Hash(data.GetData(), data.GetDataLen());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Converts string to UTF-8 and hashes it.
|
||||||
|
///
|
||||||
|
/// \param[in] str String to hash
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true if hashing succeeded
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
inline bool HashAsUTF8(const wxString &str)
|
||||||
|
{
|
||||||
|
const wxScopedCharBuffer buf(str.ToUTF8());
|
||||||
|
return Hash((const char*)buf.data(), buf.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Signs the hash using session key
|
||||||
|
///
|
||||||
|
/// \param[out] signature Digital signature
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true if signing succeeded
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool Sign(wxMemoryBuffer &signature);
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Signs the hash using session key
|
||||||
|
///
|
||||||
|
/// \returns Digital Signature
|
||||||
|
///
|
||||||
|
inline wxMemoryBuffer Sign()
|
||||||
|
{
|
||||||
|
wxMemoryBuffer signature;
|
||||||
|
wxVERIFY(Sign(signature));
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// SHA-1 Cryptographics Hash
|
||||||
|
///
|
||||||
|
class WXEXTEND_API wxCryptoHashSHA1 : public wxCryptoHash
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxCryptoHashSHA1(wxCryptoSession &session);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Cryptographics Key Base
|
||||||
|
///
|
||||||
|
class WXEXTEND_API wxCryptoKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxCryptoKey();
|
||||||
|
virtual ~wxCryptoKey();
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Has the key creation been successful?
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true if creation succeeded
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
inline bool IsOk() const
|
||||||
|
{
|
||||||
|
return m_h != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \returns Key handle to be used in native API calls.
|
||||||
|
///
|
||||||
|
inline operator HCRYPTKEY() const
|
||||||
|
{
|
||||||
|
return m_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ImportPrivate(wxCryptoSession &session, const void *data, size_t size);
|
||||||
|
bool ImportPublic(wxCryptoSession &session, const void *data, size_t size);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HCRYPTKEY m_h;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Verifies if the hash matches signature and the public key
|
||||||
|
///
|
||||||
|
/// \param[in] hash Hash
|
||||||
|
/// \param[in] signature_data Pointer to signature data
|
||||||
|
/// \param[in] signature_size Signature data size in bytes
|
||||||
|
/// \param[in] key Public key
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true if verification succeeded and the hash matches
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool WXEXTEND_API wxCryptoVerifySignature(const wxCryptoHash &hash, const void *signature_data, size_t signature_size, const wxCryptoKey &key);
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Verifies if the hash matches signature and the public key
|
||||||
|
///
|
||||||
|
/// \param[in] hash Hash
|
||||||
|
/// \param[in] signature Signature data
|
||||||
|
/// \param[in] key Public key
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true if verification succeeded and the hash matches
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
inline bool wxCryptoVerifySignature(const wxCryptoHash &hash, const wxMemoryBuffer &signature, const wxCryptoKey &key)
|
||||||
|
{
|
||||||
|
return ::wxCryptoVerifySignature(hash, signature.GetData(), signature.GetDataLen(), key);
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "crypto.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
@ -113,4 +114,4 @@ inline wxString wxXmlEscapeAttr(_In_ const wxString& str)
|
|||||||
/// \param[in] node Root node
|
/// \param[in] node Root node
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
void WXEXTEND_API wxXmlHashNode(_In_ HCRYPTHASH hash, const wxXmlNode *node);
|
bool WXEXTEND_API wxXmlHashNode(_In_ wxCryptoHash &hash, const wxXmlNode *node);
|
||||||
|
188
src/crypto.cpp
Normal file
188
src/crypto.cpp
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015-2016 Amebis
|
||||||
|
|
||||||
|
This file is part of wxExtend.
|
||||||
|
|
||||||
|
wxExtend is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
wxExtend is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with wxExtend. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#pragma comment(lib, "Crypt32.lib")
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// wxCryptoSession
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
wxCryptoSession::wxCryptoSession() : m_h(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxCryptoSession::~wxCryptoSession()
|
||||||
|
{
|
||||||
|
if (m_h)
|
||||||
|
::CryptReleaseContext(m_h, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// wxCryptoSessionRSAAES
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
wxCryptoSessionRSAAES::wxCryptoSessionRSAAES()
|
||||||
|
{
|
||||||
|
::CryptAcquireContext(&m_h, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// wxCryptoHash
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
wxCryptoHash::wxCryptoHash() : m_h(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxCryptoHash::~wxCryptoHash()
|
||||||
|
{
|
||||||
|
if (m_h)
|
||||||
|
::CryptDestroyHash(m_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool wxCryptoHash::Hash(const void *data, size_t size)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(m_h, wxT("object uninitialized"));
|
||||||
|
wxASSERT_MSG(data || !size, wxT("invalid parameter"));
|
||||||
|
|
||||||
|
return ::CryptHashData(m_h, (const BYTE*)data, size, 0) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool wxCryptoHash::Sign(wxMemoryBuffer &signature)
|
||||||
|
{
|
||||||
|
// Try with the current buffer size first.
|
||||||
|
DWORD size = (DWORD)signature.GetBufSize();
|
||||||
|
BYTE *data = (BYTE*)signature.GetWriteBuf(size);
|
||||||
|
if (::CryptSignHash(m_h, AT_SIGNATURE, NULL, 0, data, &size)) {
|
||||||
|
// The buffer was large enough. Set the actual size.
|
||||||
|
signature.SetDataLen(size);
|
||||||
|
} else if (::GetLastError() == ERROR_MORE_DATA) {
|
||||||
|
// The buffer was not big enough. Variable size contains the actual required size. Realloc and retry one more time.
|
||||||
|
wxCHECK(::CryptSignHash(m_h, AT_SIGNATURE, NULL, 0, data = (BYTE*)signature.GetWriteBuf(size), &size), false);
|
||||||
|
signature.SetDataLen(size);
|
||||||
|
} else {
|
||||||
|
signature.Clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse byte order, for consistent OpenSSL experience.
|
||||||
|
for (DWORD i = 0, j = size - 1; i < j; i++, j--)
|
||||||
|
wxSwap(data[i], data[j]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// wxCryptoHashSHA1
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
wxCryptoHashSHA1::wxCryptoHashSHA1(wxCryptoSession &session)
|
||||||
|
{
|
||||||
|
::CryptCreateHash(session, CALG_SHA1, 0, 0, &m_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// wxCryptoKey
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
wxCryptoKey::wxCryptoKey() : m_h(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxCryptoKey::~wxCryptoKey()
|
||||||
|
{
|
||||||
|
if (m_h)
|
||||||
|
::CryptDestroyKey(m_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool wxCryptoKey::ImportPrivate(wxCryptoSession &session, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(!m_h, wxT("object initialized"));
|
||||||
|
wxASSERT_MSG(session.IsOk(), wxT("invalid session"));
|
||||||
|
wxASSERT_MSG(data || !size, wxT("invalid parameter"));
|
||||||
|
|
||||||
|
PUBLICKEYSTRUC *key_data = NULL;
|
||||||
|
DWORD key_size = 0;
|
||||||
|
if (!::CryptDecodeObjectEx(X509_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, (const BYTE*)data, size, CRYPT_DECODE_ALLOC_FLAG, NULL, &key_data, &key_size))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// See: http://pumka.net/2009/12/16/rsa-encryption-cplusplus-delphi-cryptoapi-php-openssl-2/comment-page-1/#comment-429
|
||||||
|
key_data->aiKeyAlg = CALG_RSA_SIGN;
|
||||||
|
|
||||||
|
if (!::CryptImportKey(session, (const BYTE*)key_data, key_size, NULL, 0, &m_h)) {
|
||||||
|
::LocalFree(key_data);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
::LocalFree(key_data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool wxCryptoKey::ImportPublic(wxCryptoSession &session, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(!m_h, wxT("object initialized"));
|
||||||
|
wxASSERT_MSG(session.IsOk(), wxT("invalid session"));
|
||||||
|
wxASSERT_MSG(data || !size, wxT("invalid parameter"));
|
||||||
|
|
||||||
|
CERT_PUBLIC_KEY_INFO *keyinfo_data = NULL;
|
||||||
|
DWORD keyinfo_size = 0;
|
||||||
|
if (!::CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, (const BYTE*)data, size, CRYPT_DECODE_ALLOC_FLAG, NULL, &keyinfo_data, &keyinfo_size))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!::CryptImportPublicKeyInfo(session, X509_ASN_ENCODING, keyinfo_data, &m_h)) {
|
||||||
|
::LocalFree(keyinfo_data);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
::LocalFree(keyinfo_data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// wxCryptoVerifySignature
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool WXEXTEND_API wxCryptoVerifySignature(const wxCryptoHash &hash, const void *signature_data, size_t signature_size, const wxCryptoKey &key)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(hash.IsOk() , wxT("invalid hash"));
|
||||||
|
wxASSERT_MSG(signature_data || !signature_size, wxT("invalid parameter"));
|
||||||
|
wxASSERT_MSG(key.IsOk() , wxT("invalid key"));
|
||||||
|
|
||||||
|
// Reverse byte order, for consistent OpenSSL experience.
|
||||||
|
wxMemoryBuffer signature(signature_size);
|
||||||
|
BYTE *data = (BYTE*)signature.GetData();
|
||||||
|
for (size_t i = 0, j = signature_size - 1; i < signature_size; i++, j--)
|
||||||
|
data[i] = ((const BYTE*)signature_data)[j];
|
||||||
|
|
||||||
|
return ::CryptVerifySignature(hash, data, signature_size, key, NULL, 0) ? true : false;
|
||||||
|
}
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "../include/wxex/appbar.h"
|
#include "../include/wxex/appbar.h"
|
||||||
#include "../include/wxex/comutils.h"
|
#include "../include/wxex/comutils.h"
|
||||||
|
#include "../include/wxex/crypto.h"
|
||||||
#include "../include/wxex/xml.h"
|
#include "../include/wxex/xml.h"
|
||||||
|
|
||||||
#include "../include/wxex/common.h"
|
#include "../include/wxex/common.h"
|
||||||
|
50
src/xml.cpp
50
src/xml.cpp
@ -20,14 +20,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
|
||||||
static inline BOOL CryptHashData(__in HCRYPTHASH hHash, __in const wxString &str, __in DWORD dwFlags)
|
bool WXEXTEND_API wxXmlHashNode(_In_ wxCryptoHash &hash, const wxXmlNode *node)
|
||||||
{
|
|
||||||
const wxScopedCharBuffer buf(str.ToUTF8());
|
|
||||||
return ::CryptHashData(hHash, (const BYTE*)buf.data(), buf.length(), dwFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WXEXTEND_API wxXmlHashNode(_In_ HCRYPTHASH hash, const wxXmlNode *node)
|
|
||||||
{
|
{
|
||||||
wxASSERT_MSG(node, wxT("invalid parameter"));
|
wxASSERT_MSG(node, wxT("invalid parameter"));
|
||||||
|
|
||||||
@ -38,22 +31,22 @@ void WXEXTEND_API wxXmlHashNode(_In_ HCRYPTHASH hash, const wxXmlNode *node)
|
|||||||
static const BYTE element_in[] = "<";
|
static const BYTE element_in[] = "<";
|
||||||
|
|
||||||
// Hash the open tag.
|
// Hash the open tag.
|
||||||
wxVERIFY(::CryptHashData(hash, element_in, _countof(element_in) - 1, 0));
|
wxCHECK(hash.Hash(element_in, _countof(element_in) - 1), false);
|
||||||
wxVERIFY(::CryptHashData(hash, node->GetName(), 0));
|
wxCHECK(hash.HashAsUTF8(node->GetName()), false);
|
||||||
for (wxXmlAttribute *attr = node->GetAttributes(); attr; attr = attr->GetNext()) {
|
for (wxXmlAttribute *attr = node->GetAttributes(); attr; attr = attr->GetNext()) {
|
||||||
static const BYTE attrib_sep[] = " ";
|
static const BYTE attrib_sep[] = " ";
|
||||||
|
|
||||||
wxVERIFY(::CryptHashData(hash, attrib_sep, _countof(attrib_sep) - 1, 0));
|
wxCHECK(hash.Hash(attrib_sep, _countof(attrib_sep) - 1), false);
|
||||||
wxVERIFY(::CryptHashData(hash, attr->GetName(), 0));
|
wxCHECK(hash.HashAsUTF8(attr->GetName()), false);
|
||||||
wxString value = attr->GetValue();
|
wxString value = attr->GetValue();
|
||||||
if (!value.IsEmpty()) {
|
if (!value.IsEmpty()) {
|
||||||
static const BYTE
|
static const BYTE
|
||||||
attrval_in [] = "=\"",
|
attrval_in [] = "=\"",
|
||||||
attrval_out[] = "\"";
|
attrval_out[] = "\"";
|
||||||
|
|
||||||
wxVERIFY(::CryptHashData(hash, attrval_in, _countof(attrval_in) - 1, 0));
|
wxCHECK(hash.Hash(attrval_in, _countof(attrval_in) - 1), false);
|
||||||
wxVERIFY(::CryptHashData(hash, wxXmlEscapeAttr(value), 0));
|
wxCHECK(hash.HashAsUTF8(wxXmlEscapeAttr(value)), false);
|
||||||
wxVERIFY(::CryptHashData(hash, attrval_out, _countof(attrval_out) - 1, 0));
|
wxCHECK(hash.Hash(attrval_out, _countof(attrval_out) - 1), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,21 +58,21 @@ void WXEXTEND_API wxXmlHashNode(_In_ HCRYPTHASH hash, const wxXmlNode *node)
|
|||||||
elemclose_in[] = "</";
|
elemclose_in[] = "</";
|
||||||
|
|
||||||
// Hash the open tag closing.
|
// Hash the open tag closing.
|
||||||
wxVERIFY(::CryptHashData(hash, element_out, _countof(element_out) - 1, 0));
|
wxCHECK(hash.Hash(element_out, _countof(element_out) - 1), false);
|
||||||
|
|
||||||
// Hash the children.
|
// Hash the children.
|
||||||
for (; child; child = child->GetNext())
|
for (; child; child = child->GetNext())
|
||||||
wxXmlHashNode(hash, child);
|
wxCHECK(wxXmlHashNode(hash, child), false);
|
||||||
|
|
||||||
// Hash the closing tag.
|
// Hash the closing tag.
|
||||||
wxVERIFY(::CryptHashData(hash, elemclose_in, _countof(elemclose_in) - 1, 0));
|
wxCHECK(hash.Hash(elemclose_in, _countof(elemclose_in) - 1), false);
|
||||||
wxVERIFY(::CryptHashData(hash, node->GetName(), 0));
|
wxCHECK(hash.HashAsUTF8(node->GetName()), false);
|
||||||
wxVERIFY(::CryptHashData(hash, element_out, _countof(element_out) - 1, 0));
|
wxCHECK(hash.Hash(element_out, _countof(element_out) - 1), false);
|
||||||
} else {
|
} else {
|
||||||
static const BYTE element_out [] = "/>";
|
static const BYTE element_out [] = "/>";
|
||||||
|
|
||||||
// Hash the childless element tag closing.
|
// Hash the childless element tag closing.
|
||||||
wxVERIFY(::CryptHashData(hash, element_out, _countof(element_out) - 1, 0));
|
wxCHECK(hash.Hash(element_out, _countof(element_out) - 1), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -87,7 +80,7 @@ void WXEXTEND_API wxXmlHashNode(_In_ HCRYPTHASH hash, const wxXmlNode *node)
|
|||||||
|
|
||||||
case wxXML_TEXT_NODE:
|
case wxXML_TEXT_NODE:
|
||||||
{
|
{
|
||||||
wxVERIFY(::CryptHashData(hash, wxXmlEscapeText(node->GetContent()), 0));
|
wxCHECK(hash.HashAsUTF8(wxXmlEscapeText(node->GetContent())), false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,16 +90,16 @@ void WXEXTEND_API wxXmlHashNode(_In_ HCRYPTHASH hash, const wxXmlNode *node)
|
|||||||
cdata_in [] = "<![CDATA[",
|
cdata_in [] = "<![CDATA[",
|
||||||
cdata_out[] = "]]>";
|
cdata_out[] = "]]>";
|
||||||
|
|
||||||
wxVERIFY(::CryptHashData(hash, cdata_in, _countof(cdata_in) - 1, 0));
|
wxCHECK(hash.Hash(cdata_in, _countof(cdata_in) - 1), false);
|
||||||
wxVERIFY(::CryptHashData(hash, node->GetContent(), 0));
|
wxCHECK(hash.HashAsUTF8(node->GetContent()), false);
|
||||||
wxVERIFY(::CryptHashData(hash, cdata_out, _countof(cdata_out) - 1, 0));
|
wxCHECK(hash.Hash(cdata_out, _countof(cdata_out) - 1), false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case wxXML_COMMENT_NODE:
|
case wxXML_COMMENT_NODE:
|
||||||
{
|
{
|
||||||
wxVERIFY(::CryptHashData(hash, node->GetContent(), 0));
|
wxCHECK(hash.HashAsUTF8(node->GetContent()), false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,12 +107,15 @@ void WXEXTEND_API wxXmlHashNode(_In_ HCRYPTHASH hash, const wxXmlNode *node)
|
|||||||
{
|
{
|
||||||
// Hash the children.
|
// Hash the children.
|
||||||
for (wxXmlNode *child = node->GetChildren(); child; child = child->GetNext())
|
for (wxXmlNode *child = node->GetChildren(); child; child = child->GetNext())
|
||||||
wxXmlHashNode(hash, child);
|
wxCHECK(wxXmlHashNode(hash, child), false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG(wxT("unsupported XML node type"));
|
wxFAIL_MSG(wxT("unsupported XML node type"));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user