windows-nt/Source/XPSP1/NT/inetsrv/iis/setup/util/certlook/utils.cpp
2020-09-26 16:20:57 +08:00

239 lines
5.6 KiB
C++

#include "utils.h"
#include <wincrypt.h>
//***************************************************************************
//*
//* purpose:
//*
//***************************************************************************
LPSTR StripWhitespace( LPSTR pszString )
{
LPSTR pszTemp = NULL;
if ( pszString == NULL )
{
return NULL;
}
while ( *pszString == ' ' || *pszString == '\t' )
{
pszString += 1;
}
// Catch case where string consists entirely of whitespace or empty string.
if ( *pszString == '\0' )
{
return pszString;
}
pszTemp = pszString;
pszString += lstrlenA(pszString) - 1;
while ( *pszString == ' ' || *pszString == '\t' )
{
*pszString = '\0';
pszString -= 1;
}
return pszTemp;
}
//***************************************************************************
//*
//* purpose: return back a Alocated wide string from a ansi string
//* caller must free the returned back pointer with GlobalFree()
//*
//***************************************************************************
LPWSTR MakeWideStrFromAnsi(UINT uiCodePage, LPSTR psz)
{
LPWSTR pwsz;
int i;
// make sure they gave us something
if (!psz)
{
return NULL;
}
// compute the length
i = MultiByteToWideChar(uiCodePage, 0, psz, -1, NULL, 0);
if (i <= 0) return NULL;
// allocate memory in that length
pwsz = (LPWSTR) GlobalAlloc(GPTR,i * sizeof(WCHAR));
if (!pwsz) return NULL;
// clear out memory
memset(pwsz, 0, wcslen(pwsz) * sizeof(WCHAR));
// convert the ansi string into unicode
i = MultiByteToWideChar(uiCodePage, 0, (LPSTR) psz, -1, pwsz, i);
if (i <= 0)
{
GlobalFree(pwsz);
pwsz = NULL;
return NULL;
}
// make sure ends with null
pwsz[i - 1] = 0;
// return the pointer
return pwsz;
}
BOOL IsFileExist(LPCTSTR szFile)
{
// Check if the file has expandable Environment strings
LPTSTR pch = NULL;
pch = _tcschr( (LPTSTR) szFile, _T('%'));
if (pch)
{
TCHAR szValue[_MAX_PATH];
_tcscpy(szValue,szFile);
if (!ExpandEnvironmentStrings( (LPCTSTR)szFile, szValue, sizeof(szValue)/sizeof(TCHAR)))
{_tcscpy(szValue,szFile);}
return (GetFileAttributes(szValue) != 0xFFFFFFFF);
}
else
{
return (GetFileAttributes(szFile) != 0xFFFFFFFF);
}
}
void AddPath(LPTSTR szPath, LPCTSTR szName )
{
LPTSTR p = szPath;
// Find end of the string
while (*p){p = _tcsinc(p);}
// If no trailing backslash then add one
if (*(_tcsdec(szPath, p)) != _T('\\'))
{_tcscat(szPath, _T("\\"));}
// if there are spaces precluding szName, then skip
while ( *szName == ' ' ) szName = _tcsinc(szName);;
// Add new name to existing path string
_tcscat(szPath, szName);
}
void DoExpandEnvironmentStrings(LPTSTR szFile)
{
TCHAR szValue[_MAX_PATH];
_tcscpy(szValue,szFile);
// Check if the file has expandable Environment strings
LPTSTR pch = NULL;
pch = _tcschr( (LPTSTR) szFile, _T('%'));
if (pch)
{
if (!ExpandEnvironmentStrings( (LPCTSTR)szFile, szValue, sizeof(szValue)/sizeof(TCHAR)))
{
_tcscpy(szValue,szFile);
}
}
_tcscpy(szFile,szValue);
return;
}
// return -1 for error
// return 0 for not exportable
// reutrn 1 for exportable
#define PRIVATE_KEY_ERROR -1
#define PRIVATE_KEY_NOT_EXPORTABLE 0
#define PRIVATE_KEY_EXPORTABLE 1
DWORD CheckPrivateKeyStatus(PCCERT_CONTEXT pCertContextRequest)
{
HCRYPTPROV hCryptProv = NULL;
DWORD dwKeySpec = 0;
BOOL fCallerFreeProv = FALSE;
BOOL dwRet = PRIVATE_KEY_ERROR;
HCRYPTKEY hKey = NULL;
DWORD dwPermissions = 0;
DWORD dwSize = 0;
//
// first get the private key context
//
if (!CryptAcquireCertificatePrivateKey(
pCertContextRequest,
CRYPT_ACQUIRE_USE_PROV_INFO_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
NULL,
&hCryptProv,
&dwKeySpec,
&fCallerFreeProv))
{
DWORD dw = GetLastError();
dwRet = PRIVATE_KEY_ERROR;
goto ErrorReturn;
}
//
// get the handle to the key
//
if (!CryptGetUserKey(hCryptProv, dwKeySpec, &hKey))
{
dwRet = PRIVATE_KEY_ERROR;
goto ErrorReturn;
}
//
// finally, get the permissions on the key and check if it is exportable
//
dwSize = sizeof(dwPermissions);
if (!CryptGetKeyParam(hKey, KP_PERMISSIONS, (PBYTE)&dwPermissions, &dwSize, 0))
{
goto ErrorReturn;
}
dwRet = (dwPermissions & CRYPT_EXPORT) ? PRIVATE_KEY_EXPORTABLE : PRIVATE_KEY_NOT_EXPORTABLE;
CleanUp:
if (hKey != NULL)
{
CryptDestroyKey(hKey);
}
if (fCallerFreeProv)
{
CryptReleaseContext(hCryptProv, 0);
}
return dwRet;
ErrorReturn:
goto CleanUp;
}
HRESULT AttachFriendlyName(PCCERT_CONTEXT pContext)
{
CRYPT_DATA_BLOB blob_name;
WCHAR szName[200];
wcscpy(szName,L"TestingName\0\0");
blob_name.pbData = (LPBYTE)(LPCWSTR) szName;
blob_name.cbData = (wcslen(szName)+1) * sizeof(WCHAR);
if (!CertSetCertificateContextProperty(pContext,CERT_FRIENDLY_NAME_PROP_ID, 0, &blob_name))
{
_tprintf(_T("AttachFriendlyName: FAILED\n"));
return HRESULT_FROM_WIN32(GetLastError());
}
else
{
_tprintf(_T("AttachFriendlyName: SUCCEEDED!!!\n"));
}
return ERROR_SUCCESS;
}