//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: frmtutil.cpp // //-------------------------------------------------------------------------- #include "global.hxx" #include 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; icUsageIdentifier; 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; icUsageIdentifier; 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) && (iAuthAttrs.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; iUnauthAttrs.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; icUsageIdentifier; 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; }