Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

975 lines
29 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: frmtutil.cpp
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include <dbgdef.h>
extern HINSTANCE HinstDll;
///////////////////////////////////////////////////////
const WCHAR RgwchHex[] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
const CHAR RgchHex[] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL FormatAlgorithmString(LPWSTR *ppString, CRYPT_ALGORITHM_IDENTIFIER const *pAlgorithm)
{
PCCRYPT_OID_INFO pOIDInfo;
pOIDInfo = CryptFindOIDInfo(
CRYPT_OID_INFO_OID_KEY,
pAlgorithm->pszObjId,
0);
if (pOIDInfo != NULL)
{
if (NULL == (*ppString = AllocAndCopyWStr((LPWSTR) pOIDInfo->pwszName)))
{
return FALSE;
}
}
else
{
if (NULL == (*ppString = CertUIMkWStr(pAlgorithm->pszObjId)))
{
return FALSE;
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL FormatDateString(LPWSTR *ppString, FILETIME ft, BOOL fIncludeTime, BOOL fLongFormat, HWND hwnd)
{
int cch;
int cch2;
LPWSTR psz;
SYSTEMTIME st;
FILETIME localTime;
DWORD locale;
BOOL bRTLLocale;
DWORD dwFlags = fLongFormat ? DATE_LONGDATE : 0;
// See if the user locale id is RTL (Arabic, Urdu, Farsi or Hebrew).
locale = GetUserDefaultLCID();
bRTLLocale = ( (PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_ARABIC) ||
(PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_URDU) ||
(PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_FARSI) ||
(PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_HEBREW)
);
locale = MAKELCID( MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT) ;
if (bRTLLocale && (hwnd != NULL))
{
//Get the date format that matches the edit control reading direction.
if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_RTLREADING) {
dwFlags |= DATE_RTLREADING;
} else {
dwFlags |= DATE_LTRREADING;
}
}
if (!FileTimeToLocalFileTime(&ft, &localTime))
{
return FALSE;
}
if (!FileTimeToSystemTime(&localTime, &st))
{
//
// if the conversion to local time failed, then just use the original time
//
if (!FileTimeToSystemTime(&ft, &st))
{
return FALSE;
}
}
cch = (GetTimeFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL, NULL, 0) +
GetDateFormatU(locale, dwFlags, &st, NULL, NULL, 0) + 5);
if (NULL == (psz = (LPWSTR) malloc((cch+5) * sizeof(WCHAR))))
{
return FALSE;
}
cch2 = GetDateFormatU(locale, dwFlags, &st, NULL, psz, cch);
if (fIncludeTime)
{
psz[cch2-1] = ' ';
GetTimeFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL,
&psz[cch2], cch-cch2);
}
*ppString = psz;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL FormatValidityString(LPWSTR *ppString, PCCERT_CONTEXT pCertContext, HWND hwnd)
{
WCHAR szText[256];
LPWSTR pwszReturnText;
LPWSTR pwszText;
void *pTemp;
*ppString = NULL;
LoadStringU(HinstDll, IDS_VALIDFROM, szText, ARRAYSIZE(szText));
if (NULL == (pwszReturnText = AllocAndCopyWStr(szText)))
{
return FALSE;
}
if (!FormatDateString(&pwszText, pCertContext->pCertInfo->NotBefore, FALSE, FALSE, hwnd))
{
free(pwszReturnText);
return FALSE;
}
if (NULL == (pTemp = realloc(pwszReturnText, (wcslen(pwszReturnText)+wcslen(pwszText)+3) * sizeof(WCHAR))))
{
free(pwszText);
free(pwszReturnText);
return FALSE;
}
pwszReturnText = (LPWSTR) pTemp;
wcscat(pwszReturnText, L" ");
wcscat(pwszReturnText, pwszText);
free(pwszText);
pwszText = NULL;
LoadStringU(HinstDll, IDS_VALIDTO, szText, ARRAYSIZE(szText));
if (NULL == (pTemp = realloc(pwszReturnText, (wcslen(pwszReturnText)+wcslen(szText)+3) * sizeof(WCHAR))))
{
free(pwszReturnText);
return FALSE;
}
pwszReturnText = (LPWSTR) pTemp;
wcscat(pwszReturnText, L" ");
wcscat(pwszReturnText, szText);
if (!FormatDateString(&pwszText, pCertContext->pCertInfo->NotAfter, FALSE, FALSE, hwnd))
{
free(pwszReturnText);
return FALSE;
}
if (NULL == (pTemp = realloc(pwszReturnText, (wcslen(pwszReturnText)+wcslen(pwszText)+3) * sizeof(WCHAR))))
{
free(pwszText);
free(pwszReturnText);
return FALSE;
}
pwszReturnText = (LPWSTR) pTemp;
wcscat(pwszReturnText, L" ");
wcscat(pwszReturnText, pwszText);
free(pwszText);
*ppString = pwszReturnText;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL FormatSerialNoString(LPWSTR *ppString, CRYPT_INTEGER_BLOB const *pblob)
{
DWORD i = 0;
LPBYTE pb;
//DSIE: Bug 54159.
// To solve the problem, we need to put the Left-To-Right marker (0x200e),
// if complex script is supported, at the beginning of the Unicode string,
// so that it will always be displayed as US string (left-to-right).
#if (0)
if (NULL == (*ppString = (LPWSTR) malloc((pblob->cbData * 3) * sizeof(WCHAR))))
{
return FALSE;
}
// fill the buffer
pb = &pblob->pbData[pblob->cbData-1];
while (pb >= &pblob->pbData[0])
{
(*ppString)[i++] = RgwchHex[(*pb & 0xf0) >> 4];
(*ppString)[i++] = RgwchHex[*pb & 0x0f];
(*ppString)[i++] = L' ';
pb--;
}
(*ppString)[--i] = 0;
#else
HMODULE hModule = NULL;
DWORD dwLength = pblob->cbData * 3;
// See if complex script is supported.
if (hModule = GetModuleHandle("LPK.DLL"))
{
dwLength++;
}
if (NULL == (*ppString = (LPWSTR) malloc(dwLength * sizeof(WCHAR))))
{
return FALSE;
}
// The marker will be changed back to NULL if no data to format.
if (hModule)
{
(*ppString)[i++] = (WCHAR) 0x200e;
}
// fill the buffer
pb = &pblob->pbData[pblob->cbData-1];
while (pb >= &pblob->pbData[0])
{
(*ppString)[i++] = RgwchHex[(*pb & 0xf0) >> 4];
(*ppString)[i++] = RgwchHex[*pb & 0x0f];
(*ppString)[i++] = L' ';
pb--;
}
(*ppString)[--i] = 0;
#endif
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
#define NUM_HEXBYTES_PERLINE 8
#define NUM_CHARS_PERLINE ((NUM_HEXBYTES_PERLINE*2) + (NUM_HEXBYTES_PERLINE-1) + 3 + NUM_HEXBYTES_PERLINE + 2)
// (two hex digits per byte) + (space between each byte)+ (3 spaces) + (an ascci char per byte) + \n
BOOL FormatMemBufToWindow(HWND hWnd, LPBYTE pbData, DWORD cbData)
{
DWORD i = 0;
LPBYTE pb;
LPSTR pszBuffer;
DWORD cbBuffer;
char szHexText[(NUM_HEXBYTES_PERLINE*2) + NUM_HEXBYTES_PERLINE];
DWORD dwHexTextIndex = 0;
char szASCIIText[NUM_HEXBYTES_PERLINE+1];
DWORD dwASCIITextIndex = 0;
BYTE *pbBuffer;
cbBuffer = ((cbData+NUM_HEXBYTES_PERLINE-1) / NUM_HEXBYTES_PERLINE) * NUM_CHARS_PERLINE + 1;
if (NULL == (pszBuffer = (LPSTR) malloc(cbBuffer)))
{
return FALSE;
}
pszBuffer[0] = 0;
pbBuffer = (BYTE *) &pszBuffer[0];
szHexText[(NUM_HEXBYTES_PERLINE*2) + NUM_HEXBYTES_PERLINE-1] = 0;
szASCIIText[NUM_HEXBYTES_PERLINE] = 0;
#if (1) //DSIE: bug 262252
if (cbData && pbData)
{
pb = pbData;
while (pb <= &(pbData[cbData-1]))
{
// if we have a full line, then add the ascii characters
if (((pb - pbData) % NUM_HEXBYTES_PERLINE == 0) && (pb != pbData))
{
szHexText[(NUM_HEXBYTES_PERLINE*2) + NUM_HEXBYTES_PERLINE-1] = 0;
//
// for some reason strcat is dying when the string gets REALLY long, so just do
// the string cat stuff manually with memcpy.
//
memcpy(pbBuffer, (BYTE *) szHexText, strlen(szHexText)); pbBuffer += strlen(szHexText);//strcat(pszBuffer, szHexText);
memcpy(pbBuffer, (BYTE *) " ", strlen(" ")); pbBuffer += strlen(" ");//strcat(pszBuffer, " ");
memcpy(pbBuffer, (BYTE *) szASCIIText, strlen(szASCIIText)); pbBuffer += strlen(szASCIIText);//strcat(pszBuffer, szASCIIText);
memcpy(pbBuffer, (BYTE *) "\n", strlen("\n")); pbBuffer += strlen("\n");//strcat(pszBuffer, "\n");
dwHexTextIndex = 0;
dwASCIITextIndex = 0;
}
szHexText[dwHexTextIndex++] = RgchHex[(*pb & 0xf0) >> 4];
szHexText[dwHexTextIndex++] = RgchHex[*pb & 0x0f];
// this will overwrite the null character when it is the last iteration,
// so just reset the null characert before doing the strcat
szHexText[dwHexTextIndex++] = ' ';
szASCIIText[dwASCIITextIndex++] = (*pb >= 0x20 && *pb <= 0x7f) ? (char)*pb : '.';
pb++;
}
//
// print out the last line
//
// fill in with spaces if needed
for (i=dwHexTextIndex; i<((NUM_HEXBYTES_PERLINE*2) + NUM_HEXBYTES_PERLINE-1); i++)
{
szHexText[i] = ' ';
}
szHexText[(NUM_HEXBYTES_PERLINE*2) + NUM_HEXBYTES_PERLINE-1] = 0;
// add the null character to the proper place in the ascii buffer
szASCIIText[dwASCIITextIndex] = 0;
//
// for some reason strcat is dying when the string gets REALLY long, so just do
// the string cat stuff manually with memcpy.
//
memcpy(pbBuffer, (BYTE *) szHexText, strlen(szHexText)); pbBuffer += strlen(szHexText);//strcat(pszBuffer, szHexText);
memcpy(pbBuffer, (BYTE *) " ", strlen(" ")); pbBuffer += strlen(" ");//strcat(pszBuffer, " ");
memcpy(pbBuffer, (BYTE *) szASCIIText, strlen(szASCIIText)); pbBuffer += strlen(szASCIIText);//strcat(pszBuffer, szASCIIText);
*pbBuffer = 0;
}
#endif
SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM) pszBuffer);
free(pszBuffer);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL FormatMemBufToString(LPWSTR *ppString, LPBYTE pbData, DWORD cbData)
{
DWORD i = 0;
LPBYTE pb;
if (NULL == (*ppString = (LPWSTR) malloc((cbData * 3) * sizeof(WCHAR))))
{
return FALSE;
}
//
// copy to the buffer
//
pb = pbData;
while (pb <= &(pbData[cbData-1]))
{
(*ppString)[i++] = RgwchHex[(*pb & 0xf0) >> 4];
(*ppString)[i++] = RgwchHex[*pb & 0x0f];
(*ppString)[i++] = L' ';
pb++;
}
(*ppString)[--i] = 0;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
#define STRING_ALLOCATION_SIZE 128
BOOL FormatDNNameString(LPWSTR *ppString, LPBYTE pbData, DWORD cbData, BOOL fMultiline)
{
CERT_NAME_INFO *pNameInfo;
DWORD cbNameInfo;
WCHAR szText[256];
LPWSTR pwszText;
int i,j;
DWORD numChars = 1; // 1 for the terminating 0
DWORD numAllocations = 1;
void *pTemp;
//
// decode the dnname into a CERT_NAME_INFO struct
//
if (!CryptDecodeObject(
X509_ASN_ENCODING,
X509_UNICODE_NAME,
pbData,
cbData,
0,
NULL,
&cbNameInfo))
{
return FALSE;
}
if (NULL == (pNameInfo = (CERT_NAME_INFO *) malloc(cbNameInfo)))
{
return FALSE;
}
if (!CryptDecodeObject(
X509_ASN_ENCODING,
X509_UNICODE_NAME,
pbData,
cbData,
0,
pNameInfo,
&cbNameInfo))
{
free (pNameInfo);
return FALSE;
}
//
// allocate an initial buffer for the DN name string, then if it grows larger
// than the initial amount just grow as needed
//
*ppString = (LPWSTR) malloc(STRING_ALLOCATION_SIZE * sizeof(WCHAR));
if (*ppString == NULL)
{
free (pNameInfo);
return FALSE;
}
(*ppString)[0] = 0;
//
// loop for each rdn and add it to the string
//
for (i=pNameInfo->cRDN-1; i>=0; i--)
{
// if this is not the first iteration, then add a eol or a ", "
if (i != (int)pNameInfo->cRDN-1)
{
if (numChars+2 >= (numAllocations * STRING_ALLOCATION_SIZE))
{
pTemp = realloc(*ppString, ++numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR));
if (pTemp == NULL)
{
free (pNameInfo);
free (*ppString);
return FALSE;
}
*ppString = (LPWSTR) pTemp;
}
if (fMultiline)
wcscat(*ppString, L"\n");
else
wcscat(*ppString, L", ");
numChars += 2;
}
for (j=pNameInfo->rgRDN[i].cRDNAttr-1; j>=0; j--)
{
// if this is not the first iteration, then add a eol or a ", "
if (j != (int)pNameInfo->rgRDN[i].cRDNAttr-1)
{
if (numChars+2 >= (numAllocations * STRING_ALLOCATION_SIZE))
{
pTemp = realloc(*ppString, ++numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR));
if (pTemp == NULL)
{
free (pNameInfo);
free (*ppString);
return FALSE;
}
*ppString = (LPWSTR) pTemp;
}
if (fMultiline)
wcscat(*ppString, L"\n");
else
wcscat(*ppString, L", ");
numChars += 2;
}
//
// add the field name to the string if it is Multiline display
//
if (fMultiline)
{
if (!MyGetOIDInfo(szText, ARRAYSIZE(szText), pNameInfo->rgRDN[i].rgRDNAttr[j].pszObjId))
{
free (pNameInfo);
return FALSE;
}
if ((numChars + wcslen(szText) + 3) >= (numAllocations * STRING_ALLOCATION_SIZE))
{
// increment the number of allocation blocks until it is large enough
while ((numChars + wcslen(szText) + 3) >= (++numAllocations * STRING_ALLOCATION_SIZE));
pTemp = realloc(*ppString, numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR));
if (pTemp == NULL)
{
free (pNameInfo);
free (*ppString);
return FALSE;
}
*ppString = (LPWSTR) pTemp;
}
numChars += wcslen(szText) + 3;
wcscat(*ppString, szText);
wcscat(*ppString, L" = "); // delimiter
}
//
// add the value to the string
//
if (CERT_RDN_ENCODED_BLOB == pNameInfo->rgRDN[i].rgRDNAttr[j].dwValueType ||
CERT_RDN_OCTET_STRING == pNameInfo->rgRDN[i].rgRDNAttr[j].dwValueType)
{
// translate the buffer to a text string and display it that way
if (FormatMemBufToString(
&pwszText,
pNameInfo->rgRDN[i].rgRDNAttr[j].Value.pbData,
pNameInfo->rgRDN[i].rgRDNAttr[j].Value.cbData))
{
if ((numChars + wcslen(pwszText)) >= (numAllocations * STRING_ALLOCATION_SIZE))
{
// increment the number of allocation blocks until it is large enough
while ((numChars + wcslen(pwszText)) >= (++numAllocations * STRING_ALLOCATION_SIZE));
pTemp = realloc(*ppString, numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR));
if (pTemp == NULL)
{
free (pwszText);
free (pNameInfo);
free (*ppString);
return FALSE;
}
*ppString = (LPWSTR) pTemp;
}
wcscat(*ppString, pwszText);
numChars += wcslen(pwszText);
free (pwszText);
}
}
else
{
// buffer is already a string so just copy it
if ((numChars + (pNameInfo->rgRDN[i].rgRDNAttr[j].Value.cbData/sizeof(WCHAR)))
>= (numAllocations * STRING_ALLOCATION_SIZE))
{
// increment the number of allocation blocks until it is large enough
while ((numChars + (pNameInfo->rgRDN[i].rgRDNAttr[j].Value.cbData/sizeof(WCHAR)))
>= (++numAllocations * STRING_ALLOCATION_SIZE));
pTemp = realloc(*ppString, numAllocations * STRING_ALLOCATION_SIZE * sizeof(WCHAR));
if (pTemp == NULL)
{
free (pNameInfo);
free (*ppString);
return FALSE;
}
*ppString = (LPWSTR) pTemp;
}
wcscat(*ppString, (LPWSTR) pNameInfo->rgRDN[i].rgRDNAttr[j].Value.pbData);
numChars += (pNameInfo->rgRDN[i].rgRDNAttr[j].Value.cbData/sizeof(WCHAR));
}
}
}
free (pNameInfo);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL FormatEnhancedKeyUsageString(LPWSTR *ppString, PCCERT_CONTEXT pCertContext, BOOL fPropertiesOnly, BOOL fMultiline)
{
CERT_ENHKEY_USAGE *pKeyUsage = NULL;
DWORD cbKeyUsage = 0;
DWORD numChars = 1;
WCHAR szText[CRYPTUI_MAX_STRING_SIZE];
DWORD i;
//
// Try to get the enhanced key usage property
//
if (!CertGetEnhancedKeyUsage ( pCertContext,
fPropertiesOnly ? CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG : 0,
NULL,
&cbKeyUsage))
{
return FALSE;
}
if (NULL == (pKeyUsage = (CERT_ENHKEY_USAGE *) malloc(cbKeyUsage)))
{
return FALSE;
}
if (!CertGetEnhancedKeyUsage ( pCertContext,
fPropertiesOnly ? CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG : 0,
pKeyUsage,
&cbKeyUsage))
{
free(pKeyUsage);
return FALSE;
}
if (pKeyUsage->cUsageIdentifier == 0)
{
free (pKeyUsage);
if (GetLastError() == CRYPT_E_NOT_FOUND)
{
LoadStringU(HinstDll, IDS_ALL_FIELDS, szText, ARRAYSIZE(szText));
if (NULL == (*ppString = AllocAndCopyWStr(szText)))
{
return FALSE;
}
else
{
return TRUE;
}
}
else
{
LoadStringU(HinstDll, IDS_NO_USAGES, szText, ARRAYSIZE(szText));
if (NULL == (*ppString = AllocAndCopyWStr(szText)))
{
return FALSE;
}
else
{
return TRUE;
}
}
}
//
// calculate size
//
// loop for each usage and add it to the display string
for (i=0; i<pKeyUsage->cUsageIdentifier; i++)
{
if (MyGetOIDInfo(szText, ARRAYSIZE(szText), pKeyUsage->rgpszUsageIdentifier[i]))
{
// add delimeter if not first iteration
if (i != 0)
{
numChars += 2;
}
numChars += wcslen(szText);
}
else
{
free (pKeyUsage);
return FALSE;
}
}
if (NULL == (*ppString = (LPWSTR) malloc((numChars+1) * sizeof(WCHAR))))
{
free (pKeyUsage);
return FALSE;
}
//
// copy to buffer
//
(*ppString)[0] = 0;
// loop for each usage and add it to the display string
for (i=0; i<pKeyUsage->cUsageIdentifier; i++)
{
if (MyGetOIDInfo(szText, ARRAYSIZE(szText), pKeyUsage->rgpszUsageIdentifier[i]))
{
// add delimeter if not first iteration
if (i != 0)
{
if (fMultiline)
wcscat(*ppString, L"\n");
else
wcscat(*ppString, L", ");
numChars += 2;
}
// add the enhanced key usage string
wcscat(*ppString, szText);
numChars += wcslen(szText);
}
else
{
free (pKeyUsage);
return FALSE;
}
}
free (pKeyUsage);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
LPWSTR AllocAndReturnSignTime(CMSG_SIGNER_INFO const *pSignerInfo, FILETIME **ppSignTime, HWND hwnd)
{
DWORD i;
BOOL fFound = FALSE;
FILETIME *pFileTime = NULL;
DWORD cbFileTime = 0;
LPWSTR pszReturn = NULL;
if (ppSignTime != NULL)
{
*ppSignTime = NULL;
}
//
// loop for each authenticated attribute
//
i=0;
while ((!fFound) && (i<pSignerInfo->AuthAttrs.cAttr))
{
if (!(strcmp(pSignerInfo->AuthAttrs.rgAttr[i].pszObjId, szOID_RSA_signingTime) == 0))
{
i++;
continue;
}
assert(pSignerInfo->AuthAttrs.rgAttr[i].cValue == 1);
fFound = TRUE;
//decode the EncodedSigner info
if(!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
PKCS_UTC_TIME,
pSignerInfo->AuthAttrs.rgAttr[i].rgValue[0].pbData,
pSignerInfo->AuthAttrs.rgAttr[i].rgValue[0].cbData,
0,
NULL,
&cbFileTime))
{
return NULL;
}
if (NULL == (pFileTime = (FILETIME *) malloc(cbFileTime)))
{
return NULL;
}
if(!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
PKCS_UTC_TIME,
pSignerInfo->AuthAttrs.rgAttr[i].rgValue[0].pbData,
pSignerInfo->AuthAttrs.rgAttr[i].rgValue[0].cbData,
0,
pFileTime,
&cbFileTime))
{
return NULL;
}
//
// return the sign time if the caller wants it, otherwise format the string and return it
//
if (ppSignTime)
{
if (NULL != (*ppSignTime = (FILETIME *) malloc(sizeof(FILETIME))))
{
memcpy(*ppSignTime, pFileTime, sizeof(FILETIME));
}
}
else if (!FormatDateString(&pszReturn, *pFileTime, TRUE, TRUE, hwnd))
{
free(pFileTime);
return NULL;
}
}
if (pFileTime != NULL)
{
free(pFileTime);
}
return(pszReturn);
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
LPWSTR AllocAndReturnTimeStampersTimes(CMSG_SIGNER_INFO const *pSignerInfo, FILETIME **ppSignTime, HWND hwnd)
{
PCMSG_SIGNER_INFO pCounterSignerInfo;
DWORD cbCounterSignerInfo;
DWORD i;
LPWSTR pszReturnText = NULL;
LPWSTR pszTimeText = NULL;
void *pTemp;
if (ppSignTime != NULL)
{
*ppSignTime = NULL;
}
for (i=0; i<pSignerInfo->UnauthAttrs.cAttr; i++)
{
if (!(strcmp(pSignerInfo->UnauthAttrs.rgAttr[i].pszObjId, szOID_RSA_counterSign) == 0))
{
continue;
}
assert(pSignerInfo->UnauthAttrs.rgAttr[i].cValue == 1);
//decode the EncodedSigner info
if(!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
PKCS7_SIGNER_INFO,
pSignerInfo->UnauthAttrs.rgAttr[i].rgValue[0].pbData,
pSignerInfo->UnauthAttrs.rgAttr[i].rgValue[0].cbData,
0,
NULL,
&cbCounterSignerInfo))
{
return NULL;
}
if (NULL == (pCounterSignerInfo = (PCMSG_SIGNER_INFO)malloc(cbCounterSignerInfo)))
{
return NULL;
}
if(!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
PKCS7_SIGNER_INFO,
pSignerInfo->UnauthAttrs.rgAttr[i].rgValue[0].pbData,
pSignerInfo->UnauthAttrs.rgAttr[i].rgValue[0].cbData,
0,
pCounterSignerInfo,
&cbCounterSignerInfo))
{
free(pCounterSignerInfo);
return NULL;
}
if (ppSignTime != NULL)
{
//
// break after this which means we just get the first time stamp time,
// but reallistically there should only be one anyway.
//
AllocAndReturnSignTime(pCounterSignerInfo, ppSignTime, hwnd);
free(pCounterSignerInfo);
break;
}
else
{
pszTimeText = AllocAndReturnSignTime(pCounterSignerInfo, NULL, hwnd);
if (pszReturnText == NULL)
{
pszReturnText = pszTimeText;
}
else if (pszTimeText != NULL)
{
pTemp = realloc(pszReturnText,
(wcslen(pszReturnText) + wcslen(pszTimeText) + wcslen(L", ") + 1) * sizeof(WCHAR));
if (pTemp == NULL)
{
free(pszTimeText);
free(pszReturnText);
return NULL;
}
pszReturnText = (LPWSTR) pTemp;
wcscat(pszReturnText, L", ");
wcscat(pszReturnText, pszTimeText);
free(pszTimeText);
}
}
free(pCounterSignerInfo);
}
//
// if there were no counter signers, then use the time in the original signer info
//
if ((pszReturnText == NULL) && (ppSignTime == NULL))
{
pszReturnText = AllocAndReturnSignTime(pSignerInfo, NULL, hwnd);
}
return(pszReturnText);
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
LPWSTR FormatCTLSubjectUsage(CTL_USAGE *pSubjectUsage, BOOL fMultiline)
{
DWORD i;
WCHAR szText[CRYPTUI_MAX_STRING_SIZE];
LPWSTR pwszText = NULL;
void *pTemp;
for (i=0; i<pSubjectUsage->cUsageIdentifier; i++)
{
if (!MyGetOIDInfo(szText, ARRAYSIZE(szText), pSubjectUsage->rgpszUsageIdentifier[i]))
{
continue;
}
if (pwszText == NULL)
{
pwszText = AllocAndCopyWStr(szText);
}
else
{
pTemp = realloc(pwszText, (wcslen(szText) + wcslen(pwszText) + 3) * sizeof(WCHAR));
if (pTemp != NULL)
{
pwszText = (LPWSTR) pTemp;
if (fMultiline)
{
wcscat(pwszText, L"\n");
}
else
{
wcscat(pwszText, L", ");
}
wcscat(pwszText, szText);
}
else
{
free(pwszText);
return NULL;
}
}
}
return pwszText;
}