📄 decryptverify.c
字号:
/*____________________________________________________________________________
Copyright (C) 1997 Network Associates Inc. and affiliated companies.
All rights reserved.
$Id: DecryptVerify.c,v 1.20.4.3 1999/06/07 20:05:06 dgal Exp $
____________________________________________________________________________*/
// System Headers
#include <windows.h>
#include <windowsx.h>
#include <assert.h>
// PGPsdk Headers
#include "pgpConfig.h"
#include "pgpKeys.h"
#include "pgpErrors.h"
#include "pgpWerr.h"
#include "pgpUtilities.h"
#include "pgpMem.h"
#include "pgpSDKPrefs.h"
#include "pgpSC.h"
// Shared Headers
#include "PGPcl.h"
#include "SigEvent.h"
#include "Working.h"
#include "Prefs.h"
#include "DecryptVerify.h"
#include "ParseMime.h"
#include "VerificationBlock.h"
#include "WorkingResource.h"
#include "SharedStrings.h"
typedef struct _VerificationBlock VerificationBlock;
struct _VerificationBlock
{
VerificationBlock * next;
VerificationBlock * previous;
char * szBlockBegin;
char * szBlockEnd;
void * pOutput;
PGPSize outSize;
PGPBoolean bEncrypted;
PGPBoolean FYEO;
};
typedef struct _DecodeEventData
{
HINSTANCE hInst;
HWND hwnd;
HWND hwndWorking;
PGPtlsContextRef tlsContext;
char * szName;
PGPKeySetRef pubKeySet;
PGPKeySetRef recipients;
PGPUInt32 keyCount;
PGPKeyID *keyIDArray;
VerificationBlock * pVerBlock;
} DecodeEventData;
static PGPError DecryptVerify(HINSTANCE hInst, HWND hwnd,
PGPContextRef context,
PGPtlsContextRef tlsContext,
char *szName, char *szModule,
PGPOptionListRef options, BOOL bMIME,
VerificationBlock *pVerBlock);
PGPError DecodeEventHandler(PGPContextRef context,
PGPEvent *event,
PGPUserValue userValue);
static void DisplayErrorCode(char *szFile,
int nLine,
char *szModule,
int nCode);
PGPError DecryptVerifyBuffer(HINSTANCE hInst, HWND hwnd,
PGPContextRef context,
PGPtlsContextRef tlsContext,
char *szName, char *szModule,
void *pInput, DWORD dwInSize,
BOOL bMIME, void **ppOutput, PGPSize *pOutSize,
BOOL *FYEO)
{
PGPError err = kPGPError_NoErr;
PGPOptionListRef options = NULL;
VerificationBlock * pVerBlock = NULL;
VerificationBlock * pTempBlock = NULL;
PGPMemoryMgrRef memoryMgr = NULL;
VerificationBlock * pVerIndex = NULL;
OUTBUFFLIST * obl = NULL;
OUTBUFFLIST * nobl = NULL;
BOOL bFYEO = FALSE;
pgpAssert(pInput != NULL);
pgpAssert(ppOutput != NULL);
pgpAssert(pOutSize != NULL);
pgpAssert(szName != NULL);
pgpAssert(szModule != NULL);
pgpAssert(PGPRefIsValid(context));
pgpAssert(PGPRefIsValid(tlsContext));
memoryMgr = PGPGetContextMemoryMgr(context);
err = PGPBuildOptionList(context, &options,
PGPOInputBuffer(context, pInput, dwInSize),
PGPOLastOption(context));
if (IsPGPError(err))
{
DisplayErrorCode(__FILE__, __LINE__, szModule, err);
goto DecryptVerifyBufferError;
}
pVerBlock =
(VerificationBlock *) PGPNewData(memoryMgr,
sizeof(VerificationBlock),
kPGPMemoryMgrFlags_Clear);
pVerBlock->next = NULL;
pVerBlock->szBlockBegin = NULL;
pVerBlock->szBlockEnd = NULL;
pVerBlock->pOutput = NULL;
pVerBlock->outSize = 0;
pVerBlock->bEncrypted = FALSE;
pVerBlock->FYEO = FALSE;
err = DecryptVerify(hInst, hwnd, context, tlsContext, szName, szModule,
options, bMIME, pVerBlock);
*ppOutput = NULL;
*pOutSize = 0;
pVerIndex=pVerBlock;
// Convert pVerBlock to OUTBUFFLIST
do
{
if (pVerIndex->szBlockBegin != NULL)
{
nobl=MakeOutBuffItem(&obl);
nobl->pBuff=pVerIndex->szBlockBegin;
nobl->dwBuffSize=strlen(pVerIndex->szBlockBegin);
}
if (pVerIndex->pOutput != NULL)
{
nobl=MakeOutBuffItem(&obl);
nobl->pBuff=pVerIndex->pOutput;
nobl->dwBuffSize=strlen(pVerIndex->pOutput);
if (GetSecureViewerPref((void *)context))
nobl->FYEO = TRUE;
else
{
nobl->FYEO=pVerIndex->FYEO;
if (nobl->FYEO)
bFYEO = TRUE;
}
}
if (pVerIndex->szBlockEnd != NULL)
{
nobl=MakeOutBuffItem(&obl);
nobl->pBuff=pVerIndex->szBlockEnd;
nobl->dwBuffSize=strlen(pVerIndex->szBlockEnd);
}
pTempBlock = pVerIndex;
pVerIndex=pVerIndex->next;
PGPFreeData(pTempBlock);
}
while (pVerIndex != NULL);
// Concatinate them to ppOutput
ConcatOutBuffList((void *)context,
obl,
(char **)ppOutput,
pOutSize,
FYEO);
/* We don't want to show the FYEO warning if the user has
"Always use Secure Viewer" on */
*FYEO = bFYEO;
DecryptVerifyBufferError:
if (options != NULL)
PGPFreeOptionList(options);
return err;
}
PGPError DecryptVerifyFile(HINSTANCE hInst, HWND hwnd, PGPContextRef context,
PGPtlsContextRef tlsContext,
char *szName, char *szModule,
char *szInFile, BOOL bMIME, BOOL bBinary,
char **pszOutFile, void **ppOutput,
PGPSize *pOutSize, BOOL *FYEO)
{
PGPError err = kPGPError_NoErr;
PGPOptionListRef options = NULL;
PGPFileSpecRef inputFile = NULL;
PGPFileSpecRef outputFile = NULL;
PGPFileSpecRef finalFile = NULL;
PGPFileSpecRef dataFile = NULL;
PGPUInt32 macCreator = 0;
PGPUInt32 macType = 0;
VerificationBlock * pVerBlock = NULL;
VerificationBlock * pTempBlock = NULL;
char * szExtension = NULL;
char * szOutFile = NULL;
OUTBUFFLIST * obl = NULL;
OUTBUFFLIST * nobl = NULL;
BOOL bFYEO = FALSE;
pgpAssert(szInFile != NULL);
pgpAssert(pszOutFile != NULL);
pgpAssert(szName != NULL);
pgpAssert(szModule != NULL);
pgpAssert(PGPRefIsValid(context));
pgpAssert(PGPRefIsValid(tlsContext));
if (ppOutput != NULL)
*ppOutput = NULL;
if (pOutSize != NULL)
*pOutSize = 0;
err = PGPNewFileSpecFromFullPath(context, szInFile, &inputFile);
if (IsPGPError(err))
{
DisplayErrorCode(__FILE__, __LINE__, szModule, err);
goto DecryptVerifyFileError;
}
szOutFile = (char *) calloc(sizeof(char), strlen(szInFile)+5);
if (szOutFile == NULL)
{
err = kPGPError_OutOfMemory;
DisplayErrorCode(__FILE__, __LINE__, szModule, err);
goto DecryptVerifyFileError;
}
strcpy(szOutFile, szInFile);
szExtension = strrchr(szOutFile, '.');
if (szExtension != NULL)
{
if (!strcmp(szExtension, ".asc") || !strcmp(szExtension, ".pgp"))
*szExtension = '\0';
else
strcat(szOutFile, ".tmp");
}
else
strcat(szOutFile, ".tmp");
SetFileAttributes(szOutFile, FILE_ATTRIBUTE_NORMAL);
if (bBinary)
{
err = PGPNewFileSpecFromFullPath(context, szOutFile, &outputFile);
if (IsPGPError(err))
{
DisplayErrorCode(__FILE__, __LINE__, szModule, err);
goto DecryptVerifyFileError;
}
err = PGPBuildOptionList(context, &options,
PGPOInputFile(context, inputFile),
PGPOOutputFile(context, outputFile),
PGPOLastOption(context));
}
else
{
pVerBlock =
(VerificationBlock *) PGPNewData(PGPGetContextMemoryMgr(context),
sizeof(VerificationBlock),
kPGPMemoryMgrFlags_Clear);
pVerBlock->next = NULL;
pVerBlock->szBlockBegin = NULL;
pVerBlock->szBlockEnd = NULL;
pVerBlock->pOutput = NULL;
pVerBlock->outSize = 0;
pVerBlock->bEncrypted = FALSE;
pVerBlock->FYEO = FALSE;
err = PGPBuildOptionList(context, &options,
PGPOInputFile(context, inputFile),
PGPOLastOption(context));
}
if (IsPGPError(err))
{
DisplayErrorCode(__FILE__, __LINE__, szModule, err);
goto DecryptVerifyFileError;
}
err = DecryptVerify(hInst, hwnd, context, tlsContext, szName, szModule,
options, bMIME, pVerBlock);
if (!bBinary)
{
HANDLE hFile;
DWORD dwWritten;
BOOL bFixed = FALSE;
hFile = CreateFile(szOutFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if ((pVerBlock->FYEO) || (GetSecureViewerPref((void *)context)))
{
// Convert pVerBlock to OUTBUFFLIST
do
{
if (pVerBlock->szBlockBegin != NULL)
{
nobl=MakeOutBuffItem(&obl);
nobl->pBuff=pVerBlock->szBlockBegin;
nobl->dwBuffSize=strlen(pVerBlock->szBlockBegin);
}
if (pVerBlock->pOutput != NULL)
{
nobl=MakeOutBuffItem(&obl);
nobl->pBuff=pVerBlock->pOutput;
nobl->dwBuffSize=strlen(pVerBlock->pOutput);
if (GetSecureViewerPref((void *)context))
nobl->FYEO = TRUE;
else
{
nobl->FYEO=pVerBlock->FYEO;
if (nobl->FYEO)
bFYEO = TRUE;
}
}
if (pVerBlock->szBlockEnd != NULL)
{
nobl=MakeOutBuffItem(&obl);
nobl->pBuff=pVerBlock->szBlockEnd;
nobl->dwBuffSize=strlen(pVerBlock->szBlockEnd);
}
pTempBlock = pVerBlock;
pVerBlock=pVerBlock->next;
PGPFreeData(pTempBlock);
}
while (pVerBlock != NULL);
// Concatinate them to ppOutput
ConcatOutBuffList((void *)context,
obl,
(char **)ppOutput,
pOutSize,
FYEO);
/* We don't want to show the FYEO warning if the user has
"Always use Secure Viewer" on */
*FYEO = bFYEO;
}
else do
{
// Fix for Eudora 4.0.1 bug where "boundary=..." is on
// a separate line
if (pVerBlock->szBlockBegin != NULL)
{
if (!bMIME)
{
WriteFile(hFile, pVerBlock->szBlockBegin,
strlen(pVerBlock->szBlockBegin), &dwWritten,
NULL);
WriteFile(hFile, pVerBlock->pOutput,
strlen((char *) pVerBlock->pOutput), &dwWritten,
NULL);
WriteFile(hFile, pVerBlock->szBlockEnd,
strlen(pVerBlock->szBlockEnd), &dwWritten, NULL);
PGPFreeData(pVerBlock->szBlockBegin);
PGPFreeData(pVerBlock->pOutput);
PGPFreeData(pVerBlock->szBlockEnd);
}
else
{
BOOL bMultiMixed = FALSE;
BOOL bMultiAlt = FALSE;
BOOL bFirstMimePart = FALSE;
MimePart *pMimeList = NULL;
ParseMime((char *) pVerBlock->pOutput, &pMimeList);
if (pMimeList != NULL)
{
bMultiMixed = (pMimeList->nContentType ==
ContentType_MultipartMixed);
bMultiAlt = (pMimeList->nContentType ==
ContentType_MultipartAlternative);
if (bMultiMixed || bMultiAlt)
{
WriteFile(hFile, pMimeList->szHeader,
pMimeList->nHeaderLength, &dwWritten, NULL);
WriteFile(hFile, pMimeList->szBody,
pMimeList->nBodyLength, &dwWritten, NULL);
WriteFile(hFile, pMimeList->szFooter,
pMimeList->nFooterLength, &dwWritten, NULL);
if (pMimeList->nextPart != NULL)
{
pMimeList = pMimeList->nextPart;
free(pMimeList->previousPart);
}
else
{
free(pMimeList);
pMimeList = NULL;
}
}
}
bFirstMimePart = TRUE;
while (pMimeList != NULL)
{
WriteFile(hFile, pMimeList->szHeader,
pMimeList->nHeaderLength, &dwWritten, NULL);
if (bFirstMimePart || bMultiAlt)
{
bFirstMimePart = FALSE;
if (pMimeList->nContentType ==
ContentType_TextHTML)
{
char szTemp[] = "<html><pre>\r\n";
WriteFile(hFile, szTemp, strlen(szTemp),
&dwWritten, NULL);
}
if ((pMimeList->nContentType ==
ContentType_TextPlain) ||
(pMimeList->nContentType ==
ContentType_TextHTML))
{
WriteFile(hFile, pVerBlock->szBlockBegin,
strlen(pVerBlock->szBlockBegin),
&dwWritten, NULL);
}
if (pMimeList->nContentType ==
ContentType_TextHTML)
{
char szTemp[] = "</html>\r\n";
WriteFile(hFile, szTemp, strlen(szTemp),
&dwWritten, NULL);
}
}
WriteFile(hFile, pMimeList->szBody,
pMimeList->nBodyLength, &dwWritten, NULL);
if (bMultiAlt || (pMimeList->nextPart == NULL))
{
if (pMimeList->nContentType ==
ContentType_TextHTML)
{
char szTemp[] = "<html><pre>\r\n";
WriteFile(hFile, szTemp, strlen(szTemp),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -