|
|
//
// Utils.c
//
// 7/6/00 dangriff created
//
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include "utils.h"
#include "cspstruc.h"
#include "csptestsuite.h"
#include "logging.h"
//
// Function: BuildAlgList
//
BOOL BuildAlgList(HCRYPTPROV hProv, PCSPINFO pCSPInfo) { DWORD cb = 0; DWORD dwFlags = 0; PALGNODE pAlgNode = NULL; PTESTCASE ptc = &(pCSPInfo->TestCase); PROV_ENUMALGS_EX ProvEnumalgsEx; // Enumerate all supported algs
dwFlags = CRYPT_FIRST; cb = sizeof(ProvEnumalgsEx); memset(&ProvEnumalgsEx, 0, cb);
LogTestCaseSeparator(FALSE); // Log a blank line first
LogInfo(L"CryptGetProvParam PP_ENUMALGS_EX: enumerating supported algorithms");
while (CryptGetProvParam( hProv, PP_ENUMALGS_EX, (PBYTE) &ProvEnumalgsEx, &cb, dwFlags)) { // Increment the test case counter for every enumerated alg
++ptc->dwTestCaseID;
if (NULL == pCSPInfo->pAlgList) { //
// Allocate first node at user's pointer
//
LOG_TRY(TestAlloc( &((PBYTE) pCSPInfo->pAlgList), sizeof(ALGNODE), ptc));
pAlgNode = pCSPInfo->pAlgList; } else { //
// Add another node to the list
//
LOG_TRY(TestAlloc( &((PBYTE) pAlgNode->pAlgNodeNext), sizeof(ALGNODE), ptc));
pAlgNode = pAlgNode->pAlgNodeNext; }
// Zero out the ALGNODE struct
memset(pAlgNode, 0, sizeof(ALGNODE));
// Copy the ProvEnumalgsEx data into the ALGNODE struct
memcpy(&(pAlgNode->ProvEnumalgsEx), &ProvEnumalgsEx, cb);
//
// We just need to know if the current algorithm is considered "known"
// by the Test Suite. First, search through the list of REQUIRED algs,
// and assume that all REQUIRED algs are also KNOWN.
//
if (TRUE == (pAlgNode->fIsRequiredAlg = IsRequiredAlg( ProvEnumalgsEx.aiAlgid, pCSPInfo->dwExternalProvType))) { pAlgNode->fIsKnownAlg = TRUE; } else { //
// Now search through the remaining KNOWN, non-required, algorithms
//
pAlgNode->fIsKnownAlg = IsKnownAlg( ProvEnumalgsEx.aiAlgid, pCSPInfo->dwExternalProvType); } if (CRYPT_FIRST == dwFlags) { dwFlags = 0; }
LogProvEnumalgsEx(&ProvEnumalgsEx); }
if (ERROR_NO_MORE_ITEMS != GetLastError()) { ptc->dwErrorCode = ERROR_NO_MORE_ITEMS; ptc->fExpectSuccess = FALSE; ptc->pwszErrorHelp = L"CryptGetProvParam PP_ENUMALGS_EX: Wrong error code returned at end of enumeration"; //
// Log a FAIL
//
return CheckAndLogStatus( API_CRYPTGETPROVPARAM, FALSE, ptc, NULL, 0); } //
// Log a PASS
//
/*
return CheckAndLogStatus( API_CRYPTGETPROVPARAM, TRUE, ptc, NULL, 0); */ return TRUE; Cleanup: return FALSE; }
//
// Function: CreateNewInteropContext
//
BOOL CreateNewInteropContext( OUT HCRYPTPROV *phProv, IN LPWSTR pwszContainer, IN DWORD dwFlags, IN PTESTCASE ptc) { BOOL fSuccess = FALSE; //DWORD dwError = 0;
DWORD dwProvType = LogGetInteropProvType(); LPWSTR pwszProvName = LogGetInteropProvName(); BOOL fSavedExpectSuccess = ptc->fExpectSuccess; DWORD dwSavedErrorLevel = ptc->dwErrorLevel;
//
// All calls to CreateNewInteropContext are considered critical, since
// they are typically followed by additional dependent test code. Set a high
// failure rate for this reason.
//
ptc->dwErrorLevel = CSP_ERROR_API; ptc->fExpectSuccess = TRUE;
if (CRYPT_VERIFYCONTEXT != (dwFlags & CRYPT_VERIFYCONTEXT)) { TAcquire( phProv, pwszContainer, pwszProvName, dwProvType, CRYPT_DELETEKEYSET, ptc);
dwFlags &= CRYPT_NEWKEYSET; }
fSuccess = TAcquire( phProv, pwszContainer, pwszProvName, dwProvType, dwFlags, ptc);
ptc->dwErrorLevel = dwSavedErrorLevel; ptc->fExpectSuccess = fSavedExpectSuccess;
return fSuccess; }
//
// Function: CreateNewContext
//
BOOL CreateNewContext( OUT HCRYPTPROV *phProv, IN LPWSTR pwszContainer, IN DWORD dwFlags, IN PTESTCASE ptc) { BOOL fSuccess = FALSE; //DWORD dwError = 0;
DWORD dwProvType = LogGetProvType(); LPWSTR pwszProvName = LogGetProvName(); BOOL fSavedExpectSuccess = ptc->fExpectSuccess; DWORD dwSavedErrorLevel = ptc->dwErrorLevel;
//
// All calls to CreateNewContext are considered critical, since
// they are typically followed by additional dependent test code. Set a high
// failure rate for this reason.
//
ptc->dwErrorLevel = CSP_ERROR_API; ptc->fExpectSuccess = TRUE; if ( ! (dwFlags & CRYPT_VERIFYCONTEXT)) { //
// Call the CryptAcquireContext API directly (instead of
// TAcquire) since this key container may not already exist.
//
if (dwFlags & CRYPT_MACHINE_KEYSET) { CryptAcquireContext( phProv, pwszContainer, pwszProvName, dwProvType, CRYPT_DELETEKEYSET | CRYPT_MACHINE_KEYSET); } else { CryptAcquireContext( phProv, pwszContainer, pwszProvName, dwProvType, CRYPT_DELETEKEYSET); } if (FALSE == ptc->fTestingUserProtected && FALSE == ptc->fSmartCardCSP) { //
// Unless the above flag is set, all non-VERIFYCONTEXT context handles
// will be created with with the CRYPT_SILENT flag in order to
// maximize the test exposure to this flag.
//
dwFlags |= CRYPT_SILENT; } }
fSuccess = TAcquire( phProv, pwszContainer, pwszProvName, dwProvType, dwFlags, ptc);
ptc->dwErrorLevel = dwSavedErrorLevel; ptc->fExpectSuccess = fSavedExpectSuccess;
return fSuccess; }
//
// Function: CreateNewKey
//
BOOL CreateNewKey( IN HCRYPTPROV hProv, IN ALG_ID Algid, IN DWORD dwFlags, OUT HCRYPTKEY *phKey, IN PTESTCASE ptc) { BOOL fSuccess = FALSE; //DWORD dwError = 0;
BOOL fSavedExpectSuccess = ptc->fExpectSuccess; DWORD dwSavedErrorLevel = ptc->dwErrorLevel;
//
// All calls to CreateNewKey are considered critical, since
// they are typically followed by additional dependent test code. Set a high
// failure rate for the next CSP call for this reason.
//
ptc->dwErrorLevel = CSP_ERROR_API; ptc->fExpectSuccess = TRUE;
fSuccess = TGenKey( hProv, Algid, dwFlags, phKey, ptc);
ptc->dwErrorLevel = dwSavedErrorLevel; ptc->fExpectSuccess = fSavedExpectSuccess;
return fSuccess; }
//
// Function: CreateNewHash
//
BOOL CreateNewHash( IN HCRYPTPROV hProv, IN ALG_ID Algid, OUT HCRYPTHASH *phHash, IN PTESTCASE ptc) { BOOL fSuccess = FALSE; //DWORD dwError = 0;
BOOL fSavedExpectSuccess = ptc->fExpectSuccess; DWORD dwSavedErrorLevel = ptc->dwErrorLevel;
//
// All calls to CreateNewHash are considered critical, since
// they are typically followed by additional dependent test code. Set a high
// failure rate for the next CSP call for this reason.
//
ptc->dwErrorLevel = CSP_ERROR_API; ptc->fExpectSuccess = TRUE;
fSuccess = TCreateHash( hProv, Algid, 0, // hKey
0, // dwFlags
phHash, ptc);
ptc->dwErrorLevel = dwSavedErrorLevel; ptc->fExpectSuccess = fSavedExpectSuccess;
return fSuccess; }
//
// Function: TestAlloc
//
BOOL TestAlloc(OUT PBYTE *ppb, IN DWORD cb, PTESTCASE ptc) { if (NULL == (*ppb = (PBYTE) malloc(cb))) { LogApiFailure( API_MEMORY, ERROR_API_FAILED, ptc); return FALSE; }
memset(*ppb, 0, cb);
return TRUE; }
//
// Function: AlgListIterate
//
BOOL AlgListIterate( IN PALGNODE pAlgList, IN PFN_ALGNODE_FILTER pfnFilter, IN PFN_ALGNODE_PROC pfnProc, IN PVOID pvProcData, IN PTESTCASE ptc) { BOOL fErrorOccurred = FALSE; PALGNODE pAlgNode = NULL;
for (pAlgNode = pAlgList; pAlgNode != NULL; pAlgNode = pAlgNode->pAlgNodeNext) { if ( ((*pfnFilter)(pAlgNode)) ) { if (! ((*pfnProc)(pAlgNode, ptc, pvProcData)) ) { fErrorOccurred = TRUE; } } }
if (fErrorOccurred) { return FALSE; } else { return TRUE; } }
//
// Function: HashAlgFilter
//
BOOL HashAlgFilter(PALGNODE pAlgNode) { if ( (ALG_CLASS_HASH == GET_ALG_CLASS(pAlgNode->ProvEnumalgsEx.aiAlgid)) && pAlgNode->fIsKnownAlg) { return ! MacAlgFilter(pAlgNode); }
return FALSE; }
//
// Function: MacAlgFilter
//
BOOL MacAlgFilter(PALGNODE pAlgNode) { if ( ((CALG_MAC == pAlgNode->ProvEnumalgsEx.aiAlgid) || (CALG_HMAC == pAlgNode->ProvEnumalgsEx.aiAlgid)) && pAlgNode->fIsKnownAlg) { return TRUE; } else { return FALSE; } }
//
// Function: BlockCipherFilter
//
BOOL BlockCipherFilter(PALGNODE pAlgNode) { if ( (ALG_TYPE_BLOCK == GET_ALG_TYPE(pAlgNode->ProvEnumalgsEx.aiAlgid)) && pAlgNode->fIsKnownAlg) { return TRUE; } else { return FALSE; } }
//
// Function: DataEncryptFilter
//
BOOL DataEncryptFilter(PALGNODE pAlgNode) { if ( (ALG_CLASS_DATA_ENCRYPT == GET_ALG_CLASS(pAlgNode->ProvEnumalgsEx.aiAlgid)) && pAlgNode->fIsKnownAlg) { return TRUE; } else { return FALSE; } }
//
// Function: AllEncryptionAlgsFilter
// Purpose: Same algorithm set as DataEncryptFilter above,
// with the addition of the RSA key-exchange alg.
//
BOOL AllEncryptionAlgsFilter(PALGNODE pAlgNode) { return (CALG_RSA_KEYX == pAlgNode->ProvEnumalgsEx.aiAlgid) || DataEncryptFilter(pAlgNode); }
//
// Function: RSAAlgFilter
//
BOOL RSAAlgFilter(PALGNODE pAlgNode) { return (CALG_RSA_KEYX == pAlgNode->ProvEnumalgsEx.aiAlgid) || (CALG_RSA_SIGN == pAlgNode->ProvEnumalgsEx.aiAlgid); }
//
// Function: PrintBytes
//
#define CROW 8
void PrintBytes(LPWSTR pwszHdr, BYTE *pb, DWORD cbSize) { ULONG cb, i; WCHAR rgwsz[1024];
wsprintf(rgwsz, L" %s, %d bytes ::", pwszHdr, cbSize); LogInfo(rgwsz);
while (cbSize > 0) { // Start every row with an extra space
wsprintf(rgwsz, L" ");
cb = min(CROW, cbSize); cbSize -= cb; for (i = 0; i < cb; i++) wsprintf(rgwsz + wcslen(rgwsz), L" %02x", pb[i]); for (i = cb; i < CROW; i++) wsprintf(rgwsz + wcslen(rgwsz), L" "); wsprintf(rgwsz + wcslen(rgwsz), L" '"); for (i = 0; i < cb; i++) { if (pb[i] >= 0x20 && pb[i] <= 0x7f) wsprintf(rgwsz + wcslen(rgwsz), L"%c", pb[i]); else wsprintf(rgwsz + wcslen(rgwsz), L"."); } LogInfo(rgwsz);
pb += cb; } }
//
// Function: MkWStr
//
LPWSTR MkWStr(LPSTR psz) { int cWChars = 0; LPWSTR pwsz = NULL; if (psz == NULL) { return NULL; } cWChars = MultiByteToWideChar( 0, 0, psz, -1, NULL, 0); if (NULL == (pwsz = (LPWSTR) malloc(cWChars * sizeof(WCHAR)))) { return NULL; } MultiByteToWideChar( 0, 0, psz, -1, pwsz, cWChars); return(pwsz); }
|