Skip to content

Commit

Permalink
Merge pull request #83 from david-maw/development
Browse files Browse the repository at this point in the history
Implement a multibyte (ANSI) Build
  • Loading branch information
david-maw authored Feb 5, 2020
2 parents d938022 + 34553ba commit 17abfa0
Show file tree
Hide file tree
Showing 22 changed files with 333 additions and 80 deletions.
2 changes: 1 addition & 1 deletion Common/BaseSock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ bool CBaseSock::Connect(LPCWSTR HostName, USHORT PortNumber)

Timeout.tv_sec = GetSendTimeoutSeconds();

_itot_s(PortNumber, PortName, _countof(PortName), 10);
_itow_s(PortNumber, PortName, _countof(PortName), 10);

ActualSocket = socket(AF_INET, SOCK_STREAM, 0);
if (ActualSocket == INVALID_SOCKET) {
Expand Down
13 changes: 7 additions & 6 deletions Common/CertHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <vector>
#include <cryptuiapi.h>
#include <string>
#include <WinDNS.h>

#pragma comment(lib, "Cryptui.lib")
#pragma comment(lib, "Dnsapi.lib")
Expand Down Expand Up @@ -104,13 +105,13 @@ bool MatchCertificateName(PCCERT_CONTEXT pCertContext, LPCWSTR pszRequiredName)

// Select, and return a handle to a server certificate located by name
// Usually used for a best guess at a certificate to be used as the SSL certificate for a server
SECURITY_STATUS CertFindServerCertificateByName(PCCERT_CONTEXT & pCertContext, LPCTSTR pszSubjectName, bool fUserStore)
SECURITY_STATUS CertFindServerCertificateByName(PCCERT_CONTEXT & pCertContext, LPCWSTR pszSubjectName, bool fUserStore)
{
HCERTSTORE hCertStore{};
WCHAR pszFriendlyNameString[128];
WCHAR pszNameString[128];

if (pszSubjectName == nullptr || _tcslen(pszSubjectName) == 0)
if (pszSubjectName == nullptr || wcsnlen(pszSubjectName, 1) == 0)
{
DebugMsg("**** No subject name specified!");
return E_POINTER;
Expand Down Expand Up @@ -208,7 +209,7 @@ SECURITY_STATUS CertFindServerCertificateByName(PCCERT_CONTEXT & pCertContext, L

// Select, and return a handle to a client certificate
// We take a best guess at a certificate to be used as the SSL certificate for this client
SECURITY_STATUS CertFindClientCertificate(PCCERT_CONTEXT & pCertContext, const LPCTSTR pszSubjectName, bool fUserStore)
SECURITY_STATUS CertFindClientCertificate(PCCERT_CONTEXT & pCertContext, const LPCWSTR pszSubjectName, bool fUserStore)
{
HCERTSTORE hCertStore;
WCHAR pszFriendlyNameString[128];
Expand Down Expand Up @@ -271,7 +272,7 @@ SECURITY_STATUS CertFindClientCertificate(PCCERT_CONTEXT & pCertContext, const L
if (pCertContext) // We have a saved certificate context we no longer need, so free it
CertFreeCertificateContext(pCertContext);
pCertContext = CertDuplicateCertificateContext(pCertContextCurrent);
if (pszSubjectName && _tcscmp(pszNameString, pszSubjectName))
if (pszSubjectName && wcsncmp(pszNameString, pszSubjectName, _countof(pszNameString)))
DebugMsg(" Subject name does not match.");
else
{
Expand Down Expand Up @@ -519,7 +520,7 @@ BOOL WINAPI ValidServerCert(

CryptUIDlgSelectCertificate SelectCertificate = nullptr;

SECURITY_STATUS CertFindServerCertificateUI(PCCERT_CONTEXT & pCertContext, LPCTSTR pszSubjectName, bool fUserStore)
SECURITY_STATUS CertFindServerCertificateUI(PCCERT_CONTEXT & pCertContext, LPCWSTR pszSubjectName, bool fUserStore)
{
// Open a certificate store.
HCERTSTORE hCertStore;
Expand Down Expand Up @@ -610,7 +611,7 @@ SECURITY_STATUS CertFindCertificateBySignature(PCCERT_CONTEXT & pCertContext, ch
DebugMsg("CertGetNameString failed getting friendly name.");
return HRESULT_FROM_WIN32(GetLastError());
}
DebugMsg("CertFindCertificateBySignature found certificate '%S' is allowed to be used for server authentication.", (LPWSTR)ATL::CT2W(pszFriendlyNameString));
DebugMsg("CertFindCertificateBySignature found certificate '%S' is allowed to be used for server authentication.", (LPWSTR)pszFriendlyNameString);
if (CertCompareCertificateName(X509_ASN_ENCODING, &pCertContext->pCertInfo->Subject, &pCertContext->pCertInfo->Issuer))
DebugMsg("A self-signed certificate was found.");
}
Expand Down
8 changes: 4 additions & 4 deletions Common/Include/CertHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ bool MatchCertificateName(PCCERT_CONTEXT pCertContext, LPCWSTR pszRequiredName);
HRESULT ShowCertInfo(PCCERT_CONTEXT pCertContext, std::wstring Title);
HRESULT CertTrusted(PCCERT_CONTEXT pCertContext, const bool isClientCert);
std::wstring GetCertName(PCCERT_CONTEXT pCertContext);
SECURITY_STATUS CertFindClientCertificate(PCCERT_CONTEXT & pCertContext, const LPCTSTR pszSubjectName = nullptr, bool fUserStore = true);
SECURITY_STATUS CertFindClientCertificate(PCCERT_CONTEXT & pCertContext, const LPCWSTR pszSubjectName = nullptr, bool fUserStore = true);
SECURITY_STATUS CertFindFromIssuerList(PCCERT_CONTEXT & pCertContext, SecPkgContext_IssuerListInfoEx & IssuerListInfo, bool fUserStore = false);
SECURITY_STATUS CertFindServerCertificateUI(PCCERT_CONTEXT & pCertContext, LPCTSTR pszSubjectName, bool fUserStore = false);
SECURITY_STATUS CertFindServerCertificateByName(PCCERT_CONTEXT & pCertContext, LPCTSTR pszSubjectName, bool fUserStore = false);
SECURITY_STATUS CertFindServerCertificateUI(PCCERT_CONTEXT & pCertContext, LPCWSTR pszSubjectName, bool fUserStore = false);
SECURITY_STATUS CertFindServerCertificateByName(PCCERT_CONTEXT & pCertContext, LPCWSTR pszSubjectName, bool fUserStore = false);
SECURITY_STATUS CertFindCertificateBySignature(PCCERT_CONTEXT & pCertContext, char const * const signature, bool fUserStore = false);

HRESULT CertFindByName(PCCERT_CONTEXT & pCertContext, const LPCTSTR pszSubjectName, bool fUserStore = false);
HRESULT CertFindByName(PCCERT_CONTEXT & pCertContext, const LPCWSTR pszSubjectName, bool fUserStore = false);

// defined in source file CreateCertificate.cpp
PCCERT_CONTEXT CreateCertificate(bool MachineCert = false, LPCWSTR Subject = nullptr, LPCWSTR FriendlyName = nullptr, LPCWSTR Description = nullptr, bool forClient = false);
2 changes: 1 addition & 1 deletion Common/Include/Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ void DebugMsg(const WCHAR* pszFormat, ...);
void DebugMsg(const CHAR* pszFormat, ...);
bool IsUserAdmin();
std::wstring GetHostName(COMPUTER_NAME_FORMAT WhichName = ComputerNameDnsHostname);
std::wstring GetUserName();
std::wstring GetCurrentUserName();
const char* const GetVersionText();
4 changes: 2 additions & 2 deletions Common/Utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ std::wstring GetHostName(COMPUTER_NAME_FORMAT WhichName)
return std::wstring();
}

// Utility function to return the user name I'm runing under
std::wstring GetUserName()
// Utility function to return the user name I'm running under
std::wstring GetCurrentUserName()
{
DWORD NameLength = 0;
if (ERROR_SUCCESS == ::GetUserName(nullptr, &NameLength))
Expand Down
6 changes: 3 additions & 3 deletions SSLClient/Include/SSLClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CSSLClient
void StartRecvTimer();
void StartSendTimer();
// Regular class interface
static PSecurityFunctionTable SSPI();
static PSecurityFunctionTableW SSPI();
// Set up state for this connection
HRESULT Initialize(LPCWSTR ServerName, const void * const lpBuf = nullptr, const int Len = 0);
// Attributes
Expand All @@ -32,13 +32,13 @@ class CSSLClient
bool getServerCertTrusted() const;

private:
static PSecurityFunctionTable g_pSSPI;
static PSecurityFunctionTableW g_pSSPI;
CredentialHandle m_ClientCreds;
CActiveSock * m_SocketStream;
int m_LastError{ 0 };
bool m_encrypting = false;
static HRESULT InitializeClass();
SECURITY_STATUS SSPINegotiateLoop(WCHAR* ServerName);
SECURITY_STATUS SSPINegotiateLoop(LPCWCHAR ServerName);
static const int MaxMsgSize = 16000; // Arbitrary but less than 16384 limit, including MaxExtraSize
static const int MaxExtraSize = 50; // Also arbitrary, current header is 5 bytes, trailer 36
CHAR writeBuffer[MaxMsgSize + MaxExtraSize]{}; // Enough for a whole encrypted message
Expand Down
19 changes: 11 additions & 8 deletions SSLClient/SSLClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ CSSLClient::CSSLClient(CActiveSock * SocketStream)

// Avoid using (or exporting) g_pSSPI directly to give us some flexibility in case we want
// to change implementation later
PSecurityFunctionTable CSSLClient::SSPI() { return g_pSSPI; }
PSecurityFunctionTableW CSSLClient::SSPI() { return g_pSSPI; }

// Set up the connection, including SSL handshake, certificate selection/validation
// lpBuf and Len let you provide any data that's already been read
Expand Down Expand Up @@ -69,7 +69,7 @@ HRESULT CSSLClient::Initialize(LPCWSTR ServerName, const void * const lpBuf, con
else
readBufferBytes = 0;
// Perform SSL handshake
hr = SSPINegotiateLoop(ATL::CW2T(ServerName));
hr = SSPINegotiateLoop(ServerName);
if (FAILED(hr))
{
DebugMsg("Couldn't connect");
Expand Down Expand Up @@ -418,7 +418,7 @@ int CSSLClient::Send(LPCVOID lpBuf, const size_t Len)

// Negotiate a connection with the server, sending and receiving messages until the
// negotiation succeeds or fails
SECURITY_STATUS CSSLClient::SSPINegotiateLoop(WCHAR* ServerName)
SECURITY_STATUS CSSLClient::SSPINegotiateLoop(LPCWCHAR ServerName)
{
int cbData;
TimeStamp tsExpiry;
Expand Down Expand Up @@ -453,7 +453,7 @@ SECURITY_STATUS CSSLClient::SSPINegotiateLoop(WCHAR* ServerName)
#pragma warning (suppress: 4238)
&m_ClientCreds.get(),
nullptr,
ServerName,
const_cast<SEC_WCHAR *>(ServerName),
dwSSPIFlags,
0,
SECURITY_NATIVE_DREP,
Expand Down Expand Up @@ -632,7 +632,7 @@ SECURITY_STATUS CSSLClient::SSPINegotiateLoop(WCHAR* ServerName)
else
{
DebugMsg("Server Certificate returned");
ServerCertNameMatches = MatchCertificateName(hServerCertContext.get(), ATL::CW2T(ServerName));
ServerCertNameMatches = MatchCertificateName(hServerCertContext.get(), ServerName);
hr = CertTrusted(hServerCertContext.get(), false);
ServerCertTrusted = hr == S_OK;
bool IsServerCertAcceptable = ServerCertAcceptable == nullptr;
Expand Down Expand Up @@ -808,9 +808,12 @@ SECURITY_STATUS CSSLClient::SSPINegotiateLoop(WCHAR* ServerName)

HRESULT CSSLClient::Disconnect(bool closeUnderlyingSocket)
{
HRESULT hr = DisconnectSSL();
if FAILED(hr)
return hr;
if (m_hContext)
{
HRESULT hr = DisconnectSSL();
if FAILED(hr)
return hr;
}
return closeUnderlyingSocket ? m_SocketStream->Disconnect() : S_OK;
}

Expand Down
8 changes: 4 additions & 4 deletions SSLClient/SSLClient.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,30 @@
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>Dynamic</UseOfMfc>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>Dynamic</UseOfMfc>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
Expand Down
8 changes: 5 additions & 3 deletions SSLClient/framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@ const bool debug = false;
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#endif

#include <afx.h>
#include <afxwin.h> // MFC core and standard components
#include <afxmt.h>
#include <atltime.h>
#include <Windows.h>

#include <WS2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")

#define SECURITY_WIN32
#include <security.h>
#include <strsafe.h>

// Standard C++
#include <iostream>
typedef unsigned char byte;
12 changes: 6 additions & 6 deletions SSLServer/Include/Listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class ISocketStream;
class CListener
{
public:
enum ErrorType {
enum class ErrorType {
NoError,
UnknownError,
SocketInuse,
Expand All @@ -20,19 +20,19 @@ class CListener
HANDLE m_hSocketEvents[FD_SETSIZE]{};
int m_iNumListenSockets{ 0 };
CCriticalSection m_WorkerCountLock;
CWinThread * m_ListenerThread{ nullptr };
static UINT __cdecl Worker(LPVOID);
static UINT __cdecl ListenerWorker(LPVOID);
uintptr_t m_ListenerThread { 0 };
static void __cdecl Worker(LPVOID);
static void __cdecl ListenerWorker(LPVOID);
void Listen();
std::function<void(ISocketStream * StreamSock)> m_actualwork;
public:
static void LogWarning(const WCHAR* const);
static void LogWarning(const CHAR* const);
int m_WorkerCount{ 0 };
CEvent m_StopEvent{ FALSE, TRUE };
CEvent m_StopEvent{ TRUE, FALSE };
// Initialize the listener
ErrorType Initialize(int TCPSocket);
std::function<SECURITY_STATUS(PCCERT_CONTEXT & pCertContext, LPCTSTR pszSubjectName)> SelectServerCert;
std::function<SECURITY_STATUS(PCCERT_CONTEXT & pCertContext, LPCWSTR pszSubjectName)> SelectServerCert;
std::function<bool(PCCERT_CONTEXT pCertContext, const bool trusted)> ClientCertAcceptable;
void EndListening();
void BeginListening(std::function<void(ISocketStream * StreamSock)> actualwork);
Expand Down
Loading

0 comments on commit 17abfa0

Please sign in to comment.