/*++ Copyright (C) Microsoft Corporation, 1998 - 1999 Module Name: tclTrace Abstract: This module implements the CSP Tracing interpretation Author: Doug Barlow (dbarlow) 5/27/1998 Notes: ?Notes? --*/ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #endif #include #include #include #include #include #include #include #include "cspTrace.h" static void ShowBuf( LogBuffer &lb, ostream &outStr); static LPCTSTR ShowString( LogBuffer &lb); static void dump( const BYTE *pbData, DWORD cbLen, ostream &outStr); LPCTSTR MapValue( DWORD dwValue, const ValueMap *rgMap); LPCTSTR MaskValue( DWORD dwValue, const ValueMap *rgMap); static LPBYTE l_pbLogData = NULL; static DWORD l_cbLogData = 0; /*++ DoTclTrace: This routine interprets the given binary file, writing the output to stdout. Arguments: szInFile supplies the file name to be parsed. Return Value: None Remarks: ?Remarks? Author: Doug Barlow (dbarlow) 5/16/1998 --*/ void DoTclTrace( IN LPCTSTR szInFile) { HANDLE hLogFile = NULL; DWORD cbStructLen = 0; LPBYTE pbStruct = NULL; LogHeader *pLogObj; DWORD dwLen, dwRead; BOOL fSts; // // Open the log file. // hLogFile = CreateFile( szInFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hLogFile) { cerr << TEXT("Can't open file ") << szInFile << ": " << CErrorString(GetLastError()) << endl; goto ErrorExit; } // // Parse the file contents. // for (;;) { fSts = ReadFile( hLogFile, &dwLen, sizeof(DWORD), &dwRead, NULL); if ((!fSts) || (0 == dwRead)) goto ErrorExit; if (cbStructLen < dwLen) { if (NULL != pbStruct) LocalFree(pbStruct); pbStruct = (LPBYTE)LocalAlloc(LPTR, dwLen); cbStructLen = dwLen; } fSts = ReadFile( hLogFile, &pbStruct[sizeof(DWORD)], dwLen - sizeof(DWORD), &dwRead, NULL); if (!fSts) { cerr << "File read error: " << CErrorString(GetLastError()) << endl; goto ErrorExit; } // // Parse the structure into bytesize chunks. // pLogObj = (LogHeader *)pbStruct; pLogObj->cbLength = dwLen; l_pbLogData = pbStruct + pLogObj->cbDataOffset; l_cbLogData = pLogObj->cbLength - pLogObj->cbDataOffset; // // We've got the structure, now display the contents. // switch (pLogObj->id) { case AcquireContext: { struct TmpLog { LogHeader lh; LogBuffer bfContainer; DWORD dwFlags; LogBuffer bfVTable; HCRYPTPROV hProv; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set hProv ^\n") << TEXT(" [crypt acquire ^\n") << TEXT(" provider $prov ^\n"); if ((DWORD)(-1) != pld->bfContainer.cbOffset) cout << TEXT(" container {") << ShowString(pld->bfContainer) << TEXT("} ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {" << MaskValue(pld->dwFlags, rgMapAcquireFlags)) << TEXT("} ^\n"); cout << TEXT(" ]\n") << endl; break; } case GetProvParam: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; DWORD dwParam; DWORD dwDataLen; DWORD dwFlags; LogBuffer bfData; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set param ^\n") << TEXT(" [crypt $hProv parameter ") << MapValue(pld->dwParam, rgMapGetProvParam) << TEXT(" ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, rgMapGetProvFlags) << TEXT("} ^\n"); cout << TEXT(" ]\n") << endl; break; } case ReleaseContext: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; DWORD dwFlags; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("crypt $hProv release ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("}]\n"); cout << TEXT(" \n") << endl; break; } case SetProvParam: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; DWORD dwParam; LogBuffer bfData; DWORD dwFlags; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("crypt $hProv parameter ") << MapValue(pld->dwParam, rgMapSetProvParam) << TEXT(" ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); ShowBuf(pld->bfData, cout); cout << TEXT(" \n") << endl; break; } case DeriveKey: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; ALG_ID Algid; HCRYPTHASH hHash; DWORD dwFlags; HCRYPTKEY hKey; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set hKey ^\n") << TEXT(" [crypt $hProv create key ^\n") << TEXT(" algorithm ") << MapValue(pld->Algid, rgMapAlgId) << TEXT(" ^\n") << TEXT(" hash $hHash ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, rgMapDeriveKeyFlags) << TEXT("} ^\n"); cout << TEXT(" ]\n") << endl; break; } case DestroyKey: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTKEY hKey; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("crypt $hKey release\n") << endl; break; } case ExportKey: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTKEY hKey; HCRYPTKEY hPubKey; DWORD dwBlobType; DWORD dwFlags; DWORD dwDataLen; LogBuffer bfData; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set expKey ^\n") << TEXT(" [crypt $hKey export ^\n") << TEXT(" key $hPubKey ^\n") << TEXT(" type ") << MapValue(pld->dwBlobType, rgMapBlobType) << TEXT(" ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, rgMapExportKeyFlags) << TEXT("} ^\n"); cout << TEXT(" ]\n") << endl; break; } case GenKey: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; ALG_ID Algid; DWORD dwFlags; HCRYPTKEY hKey; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set hKey ^\n") << TEXT(" [crypt $hProv create key ^\n") << TEXT(" algorithm ") << MapValue(pld->Algid, rgMapAlgId) << TEXT(" ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, rgMapGenKeyFlags) << TEXT("} ^\n"); cout << TEXT(" ]\n") << endl; break; } case GetKeyParam: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTKEY hKey; DWORD dwParam; DWORD dwDataLen; DWORD dwFlags; LogBuffer bfData; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set param ^\n") << TEXT(" [crypt $hKey parameter ") << MapValue(pld->dwParam, rgMapKeyParam) << TEXT(" ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); cout << TEXT(" ]\n") << endl; break; } case GenRandom: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; DWORD dwLen; LogBuffer bfBuffer; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set rnd ^\n") << TEXT(" [crypt $hProv get random ") << pld->dwLen << TEXT("]\n") << endl; break; } case GetUserKey: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; DWORD dwKeySpec; HCRYPTKEY hUserKey; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set hKey ^\n") << TEXT(" [crypt $hProv get key ") << MapValue(pld->dwKeySpec, rgMapKeyId) << TEXT("]\n") << endl; break; } case ImportKey: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; LogBuffer bfData; HCRYPTKEY hPubKey; DWORD dwFlags; HCRYPTKEY hKey; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set hKey ^\n") << TEXT(" [crypt $hProv import ^\n"); if (0 != pld->hPubKey) cout << TEXT(" key $hPubKey ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); ShowBuf(pld->bfData, cout); cout << TEXT(" ]\n") << endl; break; } case SetKeyParam: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTKEY hKey; DWORD dwParam; LogBuffer bfData; DWORD dwFlags; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("crypt $hKey parameter ") << MapValue(pld->dwParam, rgMapKeyParam) << TEXT(" ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); ShowBuf(pld->bfData, cout); cout << TEXT(" ]\n") << endl; break; } case Encrypt: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTKEY hKey; HCRYPTHASH hHash; BOOL Final; DWORD dwFlags; LogBuffer bfInData; DWORD dwBufLen; LogBuffer bfOutData; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set ciphertext ^\n") << TEXT(" [crypt $hKey encrypt ^\n"); if (NULL != pld->hHash) cout << TEXT(" hash $hHash ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); if (pld->Final) cout << TEXT(" final ^\n"); else cout << TEXT(" more ^\n"); ShowBuf(pld->bfInData, cout); cout << TEXT(" ]\n") << endl; break; } case Decrypt: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTKEY hKey; HCRYPTHASH hHash; BOOL Final; DWORD dwFlags; LogBuffer bfInData; LogBuffer bfOutData; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set cleartext ^\n") << TEXT(" [crypt $hKey decrypt ^\n"); if (NULL != pld->hHash) cout << TEXT(" hash $hHash ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); if (pld->Final) cout << TEXT(" final ^\n"); else cout << TEXT(" more ^\n"); ShowBuf(pld->bfInData, cout); cout << TEXT(" ]\n") << endl; break; } case CreateHash: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; ALG_ID Algid; HCRYPTKEY hKey; DWORD dwFlags; HCRYPTHASH hHash; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set hHash ^\n") << TEXT(" [crypt $hProv create hash ^\n") << TEXT(" algorithm ") << MapValue(pld->Algid, rgMapAlgId) << TEXT(" ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); cout << TEXT(" ]\n") << endl; break; } case DestroyHash: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTHASH hHash; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("crypt $hHash release\n") << endl; break; } case GetHashParam: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTHASH hHash; DWORD dwParam; DWORD dwDataLen; DWORD dwFlags; LogBuffer bfData; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set param ^\n") << TEXT(" [crypt $hKey parameter ") << MapValue(pld->dwParam, rgMapHashParam) << TEXT(" ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); cout << TEXT(" ]\n") << endl; break; } case HashData: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTHASH hHash; LogBuffer bfData; DWORD dwFlags; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("crypt $hHash hash ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); ShowBuf(pld->bfData, cout); cout << endl; break; } case HashSessionKey: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTHASH hHash; HCRYPTKEY hKey; DWORD dwFlags; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("crypt $hHash hash ^\n") << TEXT(" key $hKey ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); cout << TEXT(" ]\n") << endl; break; } case SetHashParam: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTHASH hHash; DWORD dwParam; LogBuffer bfData; DWORD dwFlags; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("crypt $hHash parameter ") << MapValue(pld->dwParam, rgMapHashParam) << TEXT(" ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n"); ShowBuf(pld->bfData, cout); cout << TEXT(" ]\n") << endl; break; } case SignHash: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTHASH hHash; DWORD dwKeySpec; LogBuffer bfDescription; DWORD dwFlags; DWORD dwSigLen; LogBuffer bfSignature; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("set sig ^\n") << TEXT(" [crypt $hHash sign ^\n") << TEXT(" key ") << MapValue(pld->dwKeySpec, rgMapKeyId) << TEXT(" ^\n"); if ((DWORD)(-1) != pld->bfDescription.cbOffset) cout << TEXT(" description {") << ShowString(pld->bfDescription) << TEXT("} ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("}]\n"); cout << TEXT(" ]\n") << endl; break; } case VerifySignature: { struct TmpLog { LogHeader lh; HCRYPTPROV hProv; HCRYPTHASH hHash; LogBuffer bfSignature; DWORD dwSigLen; HCRYPTKEY hPubKey; LogBuffer bfDescription; DWORD dwFlags; } *pld = (struct TmpLog *)pLogObj; cout << TEXT("crypt $hHash verify ^\n") << TEXT(" key $hKey ^\n"); if ((DWORD)(-1) != pld->bfDescription.cbOffset) cout << TEXT(" description {") << ShowString(pld->bfDescription) << TEXT("} ^\n"); if (0 != pld->dwFlags) cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("}\n"); ShowBuf(pld->bfSignature, cout); cout << TEXT(" ]\n") << endl; break; } default: cerr << TEXT("Internal error") << endl; goto ErrorExit; break; } } ErrorExit: if (NULL == hLogFile) CloseHandle(hLogFile); } // /////////////////////////////////////////////////////////////////////////////// // // Suport routines // static void dump( const BYTE *pbData, DWORD cbLen, ostream &outStr) { unsigned long int b, i, lc; char buffer[32]; lc = 0; while (0 < cbLen) { b = min(sizeof(buffer), cbLen); memcpy(buffer, pbData, b); pbData += b; cbLen -= b; if (0 < b) { outStr << TEXT(" "); for (i = 0; i < b; i += 1) outStr << setw(2) << setfill('0') << hex << ((unsigned int)buffer[i] & 0xff); outStr << endl; lc += b; } } } static LPCTSTR MapValue( DWORD dwValue, const ValueMap *rgMap) { static TCHAR szReturn[128]; DWORD dwIndex; if (NULL != rgMap) { for (dwIndex = 0; NULL != rgMap[dwIndex].szValue; dwIndex += 1) if (rgMap[dwIndex].dwValue == dwValue) break; if (NULL != rgMap[dwIndex].szValue) lstrcpy(szReturn, rgMap[dwIndex].szValue); else _stprintf(szReturn, TEXT("0x%08x"), dwValue); } else _stprintf(szReturn, TEXT("0x%08x"), dwValue); return szReturn; } static LPCTSTR MaskValue( DWORD dwValue, const ValueMap *rgMap) { static TCHAR szReturn[1024]; TCHAR szNumeric[16]; DWORD dwIndex; BOOL fSpace = FALSE; szReturn[0] = 0; if (NULL != rgMap) { for (dwIndex = 0; NULL != rgMap[dwIndex].szValue; dwIndex += 1) { if (rgMap[dwIndex].dwValue == (rgMap[dwIndex].dwValue & dwValue)) { if (fSpace) lstrcat(szReturn, TEXT(" ")); else fSpace = TRUE; lstrcat(szReturn, rgMap[dwIndex].szValue); dwValue &= ~rgMap[dwIndex].dwValue; } } if (0 != dwValue) { if (fSpace) { lstrcat(szReturn, TEXT(" ")); fSpace = TRUE; } _stprintf(szNumeric, TEXT("0x%08x"), dwValue); lstrcat(szReturn, szNumeric); } else if (!fSpace) _stprintf(szReturn, TEXT("0x%08x"), dwValue); } else _stprintf(szReturn, TEXT("0x%08x"), dwValue); return szReturn; } static void ShowBuf( LogBuffer &lb, ostream &outStr) { if ((DWORD)(-1) == lb.cbOffset) outStr << TEXT(" ") << TEXT("") << endl; else if (0 == lb.cbLength) outStr << TEXT(" {}") << endl; else if (l_cbLogData < lb.cbOffset + lb.cbLength) outStr << TEXT(" ") << TEXT("") << endl; else dump(&l_pbLogData[lb.cbOffset], lb.cbLength, outStr); } static LPCTSTR ShowString( LogBuffer &lb) { LPCTSTR szReturn; if ((DWORD)(-1) == lb.cbOffset) szReturn = TEXT(""); else if (0 == lb.cbLength) szReturn = TEXT("{}"); else if (l_cbLogData < lb.cbOffset + lb.cbLength) szReturn = TEXT(""); else if (TEXT('\000') != (LPCTSTR)(l_pbLogData[lb.cbOffset + lb.cbLength - sizeof(TCHAR)])) szReturn = TEXT(""); else szReturn = (LPCTSTR)&l_pbLogData[lb.cbOffset]; return szReturn; }