📄 scencrypt.c
字号:
/*__________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: SCencrypt.c,v 1.30 2002/11/15 22:11:09 wjb Exp $
__________________________________________________________________________*/
#include "precomp.h"
BOOL GetCommentLine(PGPContextRef context,
char *comment,PGPSize size,PGPUInt32 *PrefAlg,
PGPCipherAlgorithm *pAllowedAlgs, int *pNumAlgs)
{
PGPPrefRef prefRef=NULL;
PGPError err;
BOOL RetVal;
RetVal=TRUE;
*comment=0;
*PrefAlg=kPGPCipherAlgorithm_CAST5;
err=PGPclPeekClientLibPrefRefs(&prefRef,NULL);
if(IsntPGPError(err))
{
PGPPrefArray *prefArray = NULL;
int i;
PGPGetPrefNumber(prefRef,
kPGPPrefPreferredAlgorithm,
PrefAlg);
err = PGPGetPrefArray(prefRef,
kPGPPrefAllowedAlgorithmsList,
&prefArray);
if (IsntPGPError(err))
{
PGPBoolean aes256=FALSE;
PGPInt32 num = prefArray->numElements;
// if we would have length passed, then
//if( num > *pNumAlgs )
// num = *pNumAlgs;
for (i=0; i<num; i++)
{
pAllowedAlgs[i] = (PGPCipherAlgorithm)
prefArray->elements[i].data;
if( pAllowedAlgs[i]==kPGPCipherAlgorithm_AES256 )
aes256=TRUE;
}
// Also add other AES algorithms for smaller keys; we assume that
// preference for the AES algorithm is stored as kPGPCipherAlgorithm_AES256.
// Better solution is to introduce client-defined kPGPCipherAlgorithm_AES
// with invalid algorithm value (more the 0xff) and check for
// kPGPCipherAlgorithm_AES instead of valid id kPGPCipherAlgorithm_AES256
if( aes256 )
{
// if( i<*pNumAlgs ) if we would have length passed
pAllowedAlgs[i++] = kPGPCipherAlgorithm_AES128;
// if( i<*pNumAlgs ) if we would have length passed
pAllowedAlgs[i++] = kPGPCipherAlgorithm_AES192;
#if PGP_DEBUG
{
char s[80];
sprintf(s, "Cloning AES alg pref, total size=%d\n", i);
OutputDebugString(s);
}
#endif
}
*pNumAlgs = i;
PGPFreePrefArray(prefArray);
}
else
*pNumAlgs = 0;
if(*comment==0)
{
PGPGetPrefStringBuffer(prefRef,
kPGPPrefComment,
size,
comment);
}
}
return RetVal;
}
PGPError GenericEncSign(MYSTATE *ms,
PGPOptionListRef opts,
char *OperationTarget)
{
PGPError err;
int UserCancel;
PGPBoolean DataIsASCII;
PPGPclRecipientDialogStruct prds;
PGPContextRef context;
char StrRes[500],szRDprompt[100],szPassTitle[100];
PGPBoolean FYEO;
PGPKeySetRef recipientSet;
PGPUInt32 iMinPhraseLength;
PGPUInt32 iMinPhraseQuality;
DataIsASCII=FALSE;
iMinPhraseLength=iMinPhraseQuality=0;
err=kPGPError_NoErr;
recipientSet=NULL;
context=ms->context;
prds=ms->prds;
// If this is first operation, put up recipient/sign dialog
if(ms->numDone==0)
{
FreePhrases(ms);
if(ms->Encrypt)
{
int RecipientReturn;
LoadString (g_hinst, IDS_PGPKEYSELDLG, StrRes, sizeof(StrRes));
strcpy(szRDprompt,ms->szAppName);
strcat(szRDprompt,StrRes);
prds->Version=kPGPCurrentRecipVersion;
prds->hwndParent=ms->hwndWorking;
prds->szTitle=szRDprompt;
prds->context=ms->context;
prds->tlsContext=ms->tlsContext;
prds->keydbOriginal=ms->KeyDB;
prds->dwDisableFlags|=kPGPclDisableSecureViewer;
// FYEO only for clipboard or text files
if((ms->Operation==MS_ENCRYPTCLIPBOARD) ||
(FileHasThisExtension(OperationTarget,"txt")))
{
prds->dwDisableFlags&=(~kPGPclDisableSecureViewer);
}
if(!((ms->Operation==MS_ENCRYPTFILELIST)&&
(ms->Encrypt)&&(!ms->Sign)))
prds->dwDisableFlags|=kPGPclDisableSelfDecryptingArchive;
RecipientReturn = PGPclRecipientDialog(prds);
if(!RecipientReturn)
return kPGPError_UserAbort;
// minimum passphrase length
if(PGPlnEnterprise())
{
PGPError prefErr;
PGPBoolean b;
PGPPrefRef prefs;
prefErr = PGPclPeekClientLibPrefRefs (&prefs, NULL);
if(IsntPGPError(prefErr))
{
prefErr = PGPGetPrefBoolean (prefs, kPGPPrefEnforceMinChars, &b);
if (IsntPGPError(prefErr)&&(b))
{
PGPGetPrefNumber (prefs, kPGPPrefMinChars, &iMinPhraseLength);
}
// minimum passphrase quality
prefErr = PGPGetPrefBoolean (prefs, kPGPPrefEnforceMinQuality, &b);
if(IsntPGPError(prefErr)&&(b))
{
PGPGetPrefNumber (prefs, kPGPPrefMinQuality, &iMinPhraseQuality);
}
}
}
if(iMinPhraseLength<1)
iMinPhraseLength=1;
if(prds->dwOptions & kPGPclSelfDecryptingArchive)
{
LoadString (g_hinst, IDS_ENTERPASSPHRASE, StrRes, sizeof(StrRes));
strcpy(szPassTitle,ms->szAppName);
strcat(szPassTitle,StrRes);
LoadString (g_hinst, IDS_ENTERSDAPASS, StrRes, sizeof(StrRes));
UserCancel = PGPclGetPhrase (context,
ms->KeyDB,
ms->hwndWorking,
StrRes,
&(ms->ConvPassPhrase),
NULL,
NULL,
0,
NULL,
NULL,
kPGPclEncryption,
NULL,NULL,
iMinPhraseLength,
iMinPhraseQuality,
ms->tlsContext,NULL,szPassTitle);
if(UserCancel)
return kPGPError_UserAbort;
}
else if(prds->dwOptions & kPGPclPassOnly)
{
LoadString (g_hinst, IDS_ENTERPASSPHRASE, StrRes, sizeof(StrRes));
strcpy(szPassTitle,ms->szAppName);
strcat(szPassTitle,StrRes);
LoadString (g_hinst, IDS_CONVPASSPROMPT, StrRes, sizeof(StrRes));
UserCancel = PGPclGetPhrase (context,
ms->KeyDB,
ms->hwndWorking,
StrRes,
&(ms->ConvPassPhrase),
NULL,
NULL,
0,
NULL,
NULL,
kPGPclEncryption,
NULL,NULL,
iMinPhraseLength,
iMinPhraseQuality,
ms->tlsContext,NULL,szPassTitle);
if(UserCancel)
return kPGPError_UserAbort;
}
}
if(ms->Sign)
{
DWORD *lpOptions;
PGPError err;
LoadString (g_hinst, IDS_ENTERPASSPHRASE, StrRes, sizeof(StrRes));
strcpy(szPassTitle,ms->szAppName);
strcat(szPassTitle,StrRes);
lpOptions=&(prds->dwOptions);
if (ms->Encrypt || (ms->Operation==MS_ENCRYPTCLIPBOARD))
lpOptions=0;
LoadString (g_hinst, IDS_PASSPROMPTABOVEKEY, StrRes, sizeof(StrRes));
err=PGPclGetCachedSigningPhrase (context,
ms->tlsContext,
ms->hwndWorking,
StrRes,
FALSE, // ForceEntry
&ms->PassPhrase,
ms->KeyDB,
&(ms->SignKey),
/// NULL,
lpOptions,
prds->dwFlags,
&ms->PassKey,
&ms->PassKeyLen,
NULL,szPassTitle);
if(err != kPGPError_NoErr)
{
PGPclEncDecErrorBox(ms->hwndWorking,err);
return kPGPError_UserAbort; // UserCancel
}
}
} // END of first operation recipient/sign dialog stuff
ms->fileName=OperationTarget;
if(prds->dwOptions & kPGPclInputIsText)
{
DataIsASCII=TRUE;
}
if(prds->dwOptions & kPGPclSelfDecryptingArchive)
{
// Self Decryptor
err=SDA(ms);
// Inform loop to stop processing files, since we've done
// them all
ms->bDoingSDA=TRUE;
// Don't do anything else like file wiping etc...
return err;
}
// if encrypting, throw in recipients
if(ms->Encrypt)
{
if(prds->dwOptions & kPGPclPassOnly)
{
int ConvPassLen;
ConvPassLen = strlen(ms->ConvPassPhrase);
PGPAppendOptionList(opts,
PGPOConventionalEncrypt(context,
PGPOPassphraseBuffer(context,ms->ConvPassPhrase,
ConvPassLen),
PGPOLastOption(context) ),
PGPOCipherAlgorithm(context,ms->PrefAlg),
PGPOLastOption(context) );
}
else
{
PGPNewKeySet( prds->keydbSelected, &recipientSet );
PGPAppendOptionList(opts,
PGPOEncryptToKeySet(context,recipientSet),
PGPOLastOption(context) );
}
}
if(ms->Sign) // If signing, throw in a passphrase and key
{
// Use passkey if available
if(ms->PassKey)
{
PGPAppendOptionList(opts,
PGPOSignWithKey(context,ms->SignKey,
PGPOPasskeyBuffer(context,
ms->PassKey,ms->PassKeyLen),
PGPOLastOption(context) ),
PGPOLastOption(context) );
}
else
{
PGPAppendOptionList(opts,
PGPOSignWithKey(context,ms->SignKey,
PGPOLastOption(context) ),
PGPOLastOption(context) );
}
}
if((prds->dwOptions & kPGPclDetachedSignature) &&
!(ms->Operation==MS_ENCRYPTCLIPBOARD) &&
(ms->Sign) && !(ms->Encrypt))
{
PGPAppendOptionList(opts,
PGPODetachedSig(context,
PGPOLastOption(context)),
PGPOLastOption(context));
}
else
prds->dwOptions&=(~kPGPclDetachedSignature);
DataIsASCII=DataIsASCII||(ms->Operation==MS_ENCRYPTCLIPBOARD);
// If we have text out arguments....
if(prds->dwOptions & kPGPclASCIIArmor)
{
if((ms->Operation==MS_ENCRYPTCLIPBOARD) &&
(ms->Sign) && !(ms->Encrypt) &&
((prds->dwOptions & kPGPclDetachedSignature)==0))
{ // Clearsign!
PGPAppendOptionList(opts,
PGPOClearSign(context, TRUE),
PGPOLastOption(context));
}
else if(!(ms->Operation==MS_ENCRYPTCLIPBOARD) &&
(ms->Sign) && !(ms->Encrypt) &&
((prds->dwOptions & kPGPclDetachedSignature)==0)&&
FileHasThisExtension(OperationTarget,"txt"))
{ // Clearsign a .txt file
DataIsASCII=TRUE; // Set to ASCII input
PGPAppendOptionList(opts,
PGPOClearSign(context, TRUE),
PGPOLastOption(context));
}
else // Just Ascii Armor*/
{
PGPAppendOptionList(opts,
PGPOArmorOutput(context, TRUE),
PGPOLastOption(context));
}
}
if(*(ms->comment)!=0)
{
PGPAppendOptionList(opts,
PGPOCommentString(context,(ms->comment)),
PGPOLastOption(context));
}
if(ms->Operation!=MS_ENCRYPTCLIPBOARD)
PGPscProgressSetNewFilename(ms->hwndWorking,"From '%s' To '%s'",ms->fileName,TRUE);
if(!(ms->Operation==MS_ENCRYPTCLIPBOARD))
{
char outname[MAX_PATH];
ms->fileRef=0;
strcpy(outname,ms->fileName);
AlterEncryptedFileName(outname,prds->dwOptions);
LoadString (g_hinst, IDS_ENCFILENAMEPROMPT, StrRes, sizeof(StrRes));
UserCancel=SaveOutputFile(context,
ms->hwndWorking,
StrRes,
outname,
&(ms->fileRef),
FALSE);
if(UserCancel)
return kPGPError_UserAbort;
PGPAppendOptionList(opts,
PGPOOutputFile(context,ms->fileRef),
PGPOLastOption(context));
}
// Assume False for For Your Eyes Only
FYEO=FALSE;
// These are the only situations we can have FYEO
if((ms->Operation==MS_ENCRYPTCLIPBOARD) ||
(FileHasThisExtension(OperationTarget,"txt")))
{
// If the recipient dialog has selected it then we're OK
if((prds->dwOptions & kPGPclSecureViewer)==kPGPclSecureViewer)
{
FYEO=TRUE;
}
}
err = PGPEncode(context,
opts,
PGPOPreferredAlgorithms(context,ms->allowedAlgs,ms->nNumAlgs),
PGPOSendNullEvents(context,75),
PGPOEventHandler(context,myEvents,ms),
PGPOVersionString(context,pgpVersionHeaderString()),
PGPOAskUserForEntropy(context, TRUE),
PGPODataIsASCII(context,DataIsASCII),
PGPOForYourEyesOnly(context,FYEO),
PGPOLastOption(context));
if(recipientSet!=NULL)
PGPFreeKeySet(recipientSet);
PGPscProgressSetBar(ms->hwndWorking,100,TRUE);
AddKeys(ms->hwndWorking,prds->keydbAdded,ms);
return err;
}
PGPError EncryptFileListStub (MYSTATE *ms)
{
PGPContextRef context;
PGPFileSpecRef inref;
PGPOptionListRef opts;
PGPError err;
FILELIST *FileCurrent;
UINT WipeReturn;
err=kPGPError_NoErr;
context=ms->context;
FileCurrent=ms->ListHead;
while(!(PGPscProgressGetCancel(ms->hwndWorking))&&(FileCurrent!=0)&&(IsntPGPError(err)))
{
if(FileCurrent->IsDirectory)
{
if(ms->prds->dwOptions & kPGPclWipeOriginal)
_rmdir(FileCurrent->name);
FileCurrent=FileCurrent->next;
continue;
}
// We'll ask for output file in event handler later...
PGPNewFileSpecFromFullPath( context,
FileCurrent->name, &inref);
PGPBuildOptionList(context,&opts,
PGPOInputFile(context,inref),
PGPOLastOption(context));
// For SDA's we only have to do this once, so don't
// do it again on the second+ times
if(!ms->bDoingSDA)
{
err=GenericEncSign(ms,opts,FileCurrent->name);
}
PGPFreeOptionList(opts);
PGPFreeFileSpec( inref );
if(ms->fileRef)
PGPFreeFileSpec(ms->fileRef);
ms->numDone++;
FileCurrent=FileCurrent->next;
}
// Do any file wiping on a second pass
if((IsntPGPError(err))&&(ms->prds->dwOptions & kPGPclWipeOriginal))
{
PGPscProgressSetAVI(ms->hwndWorking,IDR_ERASEAVI);
PGPscProgressSetTitle(ms->hwndWorking,"Wiping File(s)...");
FileCurrent=ms->ListHead;
while(!(PGPscProgressGetCancel(ms->hwndWorking))&&(FileCurrent!=0)&&(IsntPGPError(err)))
{
if(FileCurrent->IsDirectory)
{
// Try to remove directory if we can. Don't
// worry if we fail (full of new files)
if(ms->prds->dwOptions & kPGPclWipeOriginal)
_rmdir(FileCurrent->name);
FileCurrent=FileCurrent->next;
continue;
}
WipeReturn=WipeStreams(ms->context,
ms->hwndWorking,
FileCurrent->name,WIPE_DEFAULT,0);
if(WipeReturn!=WIPE_OK)
{
if (WipeError(ms->hwndWorking,
FileCurrent,WipeReturn))
{
err=kPGPError_UnknownError;
}
}
else
{
WipeReturn=InternalFileWipe(ms->context,
ms->hwndWorking,
FileCurrent->name,WIPE_DEFAULT,0,0);
if(WipeReturn!=WIPE_OK)
{
if (WipeError(ms->hwndWorking,
FileCurrent,WipeReturn))
{
err=kPGPError_UnknownError;
}
}
}
FileCurrent=FileCurrent->next;
}
}
return err;
}
BOOL PGPscEncryptFileList(HWND hwnd,char *szApp,
void *PGPsc,
void *PGPtls,
FILELIST *ListHead,
BOOL bEncrypt,
BOOL bSign)
{
PGPContextRef context;
PPGPclRecipientDialogStruct prds;
MYSTATE *ms;
char comment[80];
PGPUInt32 PrefAlg;
PGPCipherAlgorithm allowedAlgs[20];
int nNumAlgs;
PGPtlsContextRef tls;
PGPError err;
char StrRes[500];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -