📄 pgpsdacreate.c
字号:
if(IsPGPError(gpi->err))
return 1;
gpi->inbuffer[gpi->to_pointer++] = (unsigned char) invoer;
#ifdef NO_64INT
gpi->SDAHeader->CompLength[0]++;
#else /* !NO_64INT */
gpi->SDAHeader->CompLength++;
#endif /* NO_64INT */
// Total should be 4 GB minus stub and header length
// hard coded here for 1 meg to eliminate unnecessary math
#ifdef NO_64INT
if(gpi->SDAHeader->CompLength[0]==(0xffffffff-0x100000))
#else /* !NO_64INT */
if(gpi->SDAHeader->CompLength==(0xffffffff-0x100000))
#endif /* NO_64INT */
{
SDAEvent Event;
PGPError err;
#ifndef E_BUSINESS_SERVER
FILE *fout;
char szDecoderName[500];
char *szDecoder;
#endif /* !E_BUSINESS_SERVER */
gpi->err=kPGPError_SizeAdviseFailure;
Event.type=kSDAEvent_ErrorEvent;
Event.data.errorData.fileName=gpi->FileName;
Event.data.errorData.err=gpi->err;
err=gpi->err=(gpi->UserProc)(NULL,&Event,gpi->pUserValue);
if(IsPGPError(gpi->err))
{
// Abort over 4 GB SDA
return 1;
}
#ifndef E_BUSINESS_SERVER
// Create decoder stub
strcpy(szDecoderName,gpi->szOutputFileName);
szDecoder=mystrstri(szDecoderName,".sda.exe");
if(szDecoder!=NULL)
{
strcpy(szDecoder,".decoder.sda.exe");
fout=fopen(szDecoderName,"wb");
if(fout==0)
{
err=kPGPError_FileOpFailed;
}
else
{
SDAHEADER SDAHeader;
memset(&SDAHeader,0x00,sizeof(SDAHEADER));
memcpy((char *)&(SDAHeader.szPGPSDA),"PGPSDA",6);
// Do the write out code stub callback
Event.type=kSDAEvent_WriteSDAStubEvent;
Event.data.stubData.fOutput=fout;
err=(gpi->UserProc)(NULL,&Event,gpi->pUserValue);
if(IsntPGPError(err))
{
fwrite(&SDAHeader,1,sizeof(SDAHEADER),fout);
}
fclose(fout);
}
}
if(IsPGPError(err))
{
// Still errors? Clean up
gpi->err=err;
Event.type=kSDAEvent_ErrorEvent;
Event.data.errorData.fileName=szDecoderName;
Event.data.errorData.err=gpi->err;
err=(gpi->UserProc)(NULL,&Event,gpi->pUserValue);
return 1;
}
#endif /* !E_BUSINESS_SERVER */
}
if(gpi->to_pointer==kBlockSize)
{
#ifndef IS_SEA
EncryptBlock512(gpi->CASTContext,
gpi->SDAHeader,
gpi->blockindex,
(const PGPUInt32 *)gpi->inbuffer,
(PGPUInt32 *)gpi->outbuffer);
#else
memcpy(gpi->outbuffer,gpi->inbuffer,kBlockSize);
#endif // IS_SEA
fwrite(gpi->outbuffer,1,gpi->to_pointer,gpi->fout);
gpi->blockindex++;
memset(gpi->inbuffer,0x00,kBlockSize);
gpi->to_pointer=0;
}
return 1;
}
void DoCompress(void *gpi)
{
#if (NOCOMPRESSION_SEA || NOCOMPRESSION_SDA)
int c;
while((c=comp_getc_buffer(gpi))!=EOF)
{
comp_putc_buffer(c,gpi);
}
#else
Deflate_Compress(gpi);
#endif
}
PGPError SDAEncryptFiles(PGPContextRef context,
SDAHEADER *SDAHeader,
PGPSymmetricCipherContextRef CASTContext,
FILELIST *fl,
char *szOutputFileName,
#ifndef IS_SEA
#ifdef E_BUSINESS_SERVER
void *pHashPassphrase,
PGPUInt32 sizeHashedPassphrase,
#endif /* E_BUSINESS_SERVER */
#endif /* IS_SEA */
SDACREATECALLBACK UserProc,void *pUserValue)
{
FILE *fout;
char inbuffer[kBlockSize];
char outbuffer[kBlockSize];
GETPUTINFO gpi;
char *lastslash;
SDAEvent Event;
struct stat statbuffer;
int staterror;
PGPError err;
#ifndef IS_SEA
#ifdef E_BUSINESS_SERVER
EBIZHEADER ebizheader;
#ifdef WORDS_BIGENDIAN
PGPUInt32 encryptedBlockSize;
PGPUInt32 autoExecNum;
#endif /* WORDS_BIGENDIAN */
#endif /* E_BUSINESS_SERVER */
#endif /* !IS_SEA */
#ifdef WORDS_BIGENDIAN
PGPUInt16 hashReps;
PGPUInt32 offset;
#ifndef NO_64INT
PGPUInt64 CompLength;
PGPUInt64 NumFiles;
#else /* NO_64INT */
PGPUInt32 CompLength;
PGPUInt32 NumFiles;
#endif /* !NO_64INT */
#endif /* WORDS_BIGENDIAN */
fout=0;
// Initialize variables for compression call
memset(&gpi,0x00,sizeof(GETPUTINFO));
err=kPGPError_NoErr;
// Open the file
#ifdef WIN32
fout=fopen(szOutputFileName,"wb");
#else /* !WIN32 */
#ifdef NO_64INT
fout=fopen(szOutputFileName,"wb");
#else /* !NO_64INT */
fout=fopen64(szOutputFileName, "wb");
#endif /* NO_64INT */
#endif /* WIN32 */
if(fout==0)
{
err=kPGPError_FileOpFailed;
}
else
{
// Do the write out code stub callback
Event.type=kSDAEvent_WriteSDAStubEvent;
Event.data.stubData.fOutput=fout;
err=(UserProc)(context,&Event,pUserValue);
if(IsntPGPError(err))
{
// Close file to get the size
fclose(fout);
fout=0;
staterror=stat(szOutputFileName, &statbuffer);
// Reopen it
#ifdef WIN32
fout=fopen(szOutputFileName,"ab");
#else /* !WIN32 */
#ifdef NO_64INT
fout=fopen(szOutputFileName,"ab");
#else /* !NO_64INT */
fout=fopen64(szOutputFileName,"ab");
#endif /* NO_64INT */
#endif /* WIN32 */
if((staterror!=0)||(fout==0))
{
err=kPGPError_FileOpFailed;
}
else
{
#ifdef E_BUSINESS_SERVER
/* Determine if user wants to encrypt to adk as well. */
memset(&ebizheader, 0, sizeof(ebizheader));
memcpy((char *)ebizheader.szPGPEBIZ, PGPEBIZ, strlen(PGPEBIZ));
ebizheader.MajorVersion = 7;
ebizheader.MinorVersion = 5;
ebizheader.bEncryptedToADK = FALSE;
if(pHashPassphrase != NULL && sizeHashedPassphrase)
{
Event.type = kSDAEvent_EncryptADKEvent;
memcpy(Event.data.adkencryptData.hashedPassphrase,
pHashPassphrase, sizeHashedPassphrase);
Event.data.adkencryptData.bEncryptToADK = FALSE;
memset(Event.data.adkencryptData.encryptedBlock, 0,
sizeof(Event.data.adkencryptData.encryptedBlock));
err = (UserProc)(context, &Event, pUserValue);
if(IsntPGPError(err))
{
if(Event.data.adkencryptData.bEncryptToADK)
{
ebizheader.bEncryptedToADK = Event.data.adkencryptData.bEncryptToADK;
memcpy(ebizheader.encryptedBlock,
Event.data.adkencryptData.encryptedBlock,
sizeof(Event.data.adkencryptData.encryptedBlock));
ebizheader.size = Event.data.adkencryptData.blockSize;
}
}
else
goto done;
}
/*
* Determine if user wants us to autolaunch a single binary in file.
* Don't ask me why they want this but they do....
*/
Event.type = kSDAEvent_AutoLaunchEvent;
Event.data.autolaunchData.autoExecNum = 0;
err = (UserProc)(context, &Event, pUserValue);
if(IsPGPError(err))
goto done;
else
ebizheader.autoExecNum = Event.data.autolaunchData.autoExecNum;
#endif /* E_BUSINESS_SERVER */
SDAHeader->offset=statbuffer.st_size;
gpi.szOutputFileName=szOutputFileName;
gpi.fout=fout;
gpi.SDAHeader=SDAHeader;
gpi.blockindex=0;
gpi.outbuffer=outbuffer;
gpi.inbuffer=inbuffer;
gpi.CASTContext=CASTContext;
gpi.err=kPGPError_NoErr;
gpi.bFeedFilename=TRUE;
gpi.fl=fl;
gpi.UserProc=UserProc;
gpi.pUserValue=pUserValue;
gpi.context=context;
#ifdef E_BUSINESS_SERVER
Event.type = kSDAEvent_PreserveDirectoriesEvent;
err = (UserProc)(context, &Event, pUserValue);
if(IsPGPError(err))
{
/* Default to preserving directories */
gpi.bPreserveDirectories = TRUE;
}
else
{
gpi.bPreserveDirectories = Event.data.directoryData.bPreserveDirectories;
}
#endif /* E_BUSINESS_SERVER */
lastslash=strrchr(gpi.fl->name,'\\');
if(lastslash==NULL)
lastslash=gpi.fl->name;
else
lastslash++;
#ifdef IS_SEA
// Find beginning of SEA directory tree
gpi.PathHead=strlen(gpi.fl->name)-1;
if(gpi.fl->name[gpi.PathHead]!='\\')
gpi.PathHead++;
gpi.fl=gpi.fl->next;
#else
// Find beginning of SDA directory tree
#ifdef E_BUSINESS_SERVER
/*
* Since we support adding files from somewhere other than
* current directory store entire path.
*/
gpi.PathHead = 0;
#else /* !E_BUSINESS_SERVER */
gpi.PathHead=lastslash-gpi.fl->name;
#endif /* E_BUSINESS_SERVER */
#endif // IS_SEA
DoCompress(&gpi);
if(gpi.fin)
fclose(gpi.fin);
// Write out the last block since compress doesn't
// know how we are delaying writes
if(gpi.to_pointer!=0)
{
#ifndef IS_SEA
EncryptBlock512(gpi.CASTContext,
gpi.SDAHeader,
gpi.blockindex,
(const PGPUInt32 *)gpi.inbuffer,
(PGPUInt32 *)gpi.outbuffer);
#else
memcpy(gpi.outbuffer,gpi.inbuffer,kBlockSize);
#endif // IS_SEA
fwrite(gpi.outbuffer,1,kBlockSize,gpi.fout);
}
#ifdef WORDS_BIGENDIAN
offset = SDAHeader->offset;
PGPUInt32ToEndian(offset, kPGPLittleEndian, (PGPByte *)&SDAHeader->offset);
hashReps = SDAHeader->hashReps;
PGPUInt16ToEndian(hashReps, kPGPLittleEndian, (PGPByte *)&SDAHeader->hashReps);
#ifdef NO_64INT
NumFiles = SDAHeader->NumFiles[0];
PGPUInt32ToEndian(NumFiles, kPGPLittleEndian, (PGPByte *)&SDAHeader->NumFiles[0]);
SDAHeader->NumFiles[1] = 0;
CompLength = SDAHeader->CompLength[0];
PGPUInt32ToEndian(CompLength, kPGPLittleEndian, (PGPByte *)&SDAHeader->CompLength[0]);
SDAHeader->CompLength[1] = 0;
#else /* !NO_64INT */
NumFiles = SDAHeader->NumFiles;
PGPUInt64ToLittleEndian(NumFiles, (PGPByte *)&SDAHeader->NumFiles);
CompLength = SDAHeader->CompLength;
PGPUInt64ToLittleEndian(CompLength, (PGPByte *)&SDAHeader->CompLength);
#endif /* NO_64INT */
#endif /* WORDS_BIGENDIAN */
#ifndef IS_SEA
#ifdef E_BUSINESS_SERVER
/* Write out additional header */
#ifdef WORDS_BIGENDIAN
PGPUInt32ToEndian(ebizheader.autoExecNum, kPGPLittleEndian, (PGPByte *)&autoExecNum);
ebizheader.autoExecNum = autoExecNum;
#endif /* WORDS_BIGENDIAN */
fwrite(&ebizheader.autoExecNum, 1, sizeof(ebizheader.autoExecNum), fout);
fwrite(ebizheader.encryptedBlock, 1, sizeof(ebizheader.encryptedBlock), fout);
#ifdef WORDS_BIGENDIAN
PGPUInt32ToEndian(ebizheader.size, kPGPLittleEndian, (PGPByte *)&encryptedBlockSize);
ebizheader.size = encryptedBlockSize;
#endif /* WORDS_BIGENDIAN */
fwrite(&ebizheader.size, 1, sizeof(ebizheader.size), fout);
fwrite(&ebizheader.bEncryptedToADK, 1, sizeof(ebizheader.bEncryptedToADK), fout);
fwrite(&ebizheader.MinorVersion, 1, sizeof(ebizheader.MinorVersion), fout);
fwrite(&ebizheader.MajorVersion, 1, sizeof(ebizheader.MajorVersion), fout);
fwrite(&ebizheader.szPGPEBIZ, 1, sizeof(ebizheader.szPGPEBIZ), fout);
#endif /* E_BUSINESS_SERVER */
/*
* Write out each member of SDAHEADER individually so we don't have to deal with
* structure size issues. Should have done this in the first place but.....
*/
fwrite(SDAHeader->szPGPSDA, 1, sizeof(SDAHeader->szPGPSDA), fout);
fwrite(&SDAHeader->offset, 1, sizeof(PGPUInt32), fout);
fwrite(&SDAHeader->CompLength, 1, sizeof(SDAHeader->CompLength), fout);
fwrite(&SDAHeader->NumFiles, 1, sizeof(SDAHeader->NumFiles), fout);
fwrite(&SDAHeader->Salt, 1, sizeof(SDAHeader->Salt), fout);
fwrite(&SDAHeader->hashReps, 1, sizeof(SDAHeader->hashReps), fout);
fwrite(SDAHeader->CheckBytes, 1, sizeof(SDAHeader->CheckBytes), fout);
#else /* IS_SEA */
fwrite(SDAHeader,1,sizeof(SDAHEADER),fout);
#endif /* IS_SEA */
memset(inbuffer,0x00,kBlockSize);
memset(outbuffer,0x00,kBlockSize);
}
}
}
#ifndef IS_SEA
#ifdef E_BUSINESS_SERVER
done:
#endif /* E_BUSINESS_SERVER */
#endif /* !IS_SEA */
if(fout!=0)
fclose(fout);
if(IsPGPError(gpi.err))
{
err=gpi.err;
}
if(IsPGPError(err))
{
// Clean up
remove(szOutputFileName);
}
return err;
}
PGPError SDACreate(PGPContextRef context,FILELIST *fl,
char *szOutputFileName,char *ConvPassPhrase,
SDACREATECALLBACK UserProc,void *pUserValue,
PGPUInt32 Flags)
{
#ifdef IS_SEA
SDAHEADER SDAHeader;
PGPError err;
memset(&SDAHeader,0x00,sizeof(SDAHEADER));
memcpy((char *)&(SDAHeader.szPGPSDA),"PGPSEA",6);
SDAHeader.Flags = Flags;
err=SDAEncryptFiles(NULL,
&SDAHeader,NULL,
fl,szOutputFileName,
UserProc,pUserValue);
#else
// SHA is 160 bits (20*8)
PGPByte HashedPassphrase[20];
PGPError err;
PGPHashContextRef SHAContext;
PGPSymmetricCipherContextRef CASTContext;
#ifdef WIN32
PGPUInt64 endTicks;
#else /* !WIN32 */
clock_t endTicks;
#endif /* WIN32 */
PGPUInt8 j;
PGPUInt16 i;
SDAHEADER SDAHeader;
SDAEvent Event;
memset(&SDAHeader,0x00,sizeof(SDAHEADER));
memcpy((char *)&(SDAHeader.szPGPSDA),"PGPSDA",6);
// Get random bits for salt and IV's
do
{
err=PGPContextGetRandomBytes (context,
(char *)&(SDAHeader.Salt.saltBytes), 8);
if(err==kPGPError_OutOfEntropy)
{
Event.type=kSDAEvent_GetSDARandomBitsEvent;
Event.data.randomData.EntropyAmount=8*8;
err=(UserProc)(context,&Event,pUserValue);
if(IsPGPError(err))
return err;
}
} while(err==kPGPError_OutOfEntropy);
// Hash the passphrase
err=PGPNewHashContext(context,
kPGPHashAlgorithm_SHA,&SHAContext);
// Salt it to eliminate common passphrases across files
err=PGPContinueHash(SHAContext,
SDAHeader.Salt.saltBytes,
sizeof(SDAHeader.Salt.saltBytes));
// We hash the passphrase in with a rotating counter byte
// an arbitrary number of times based on the processing
// power of the computer we're running on up to a maximum of
// 16000.
endTicks = clock() + CLOCKS_PER_SEC/2; // 500 ms
for (i=0, j=0; (clock() < endTicks) && (i < 16000);
i++, j++)
{
err=PGPContinueHash(SHAContext,
ConvPassPhrase,strlen(ConvPassPhrase));
err=PGPContinueHash(SHAContext,&j, 1);
}
SDAHeader.hashReps = i;
err=PGPFinalizeHash(SHAContext,HashedPassphrase);
err=PGPFreeHashContext(SHAContext);
err=PGPNewSymmetricCipherContext(context,kPGPCipherAlgorithm_CAST5,
&CASTContext);
err=PGPInitSymmetricCipher( CASTContext,HashedPassphrase);
memcpy(&(SDAHeader.CheckBytes),HashedPassphrase,8);
err=PGPSymmetricCipherEncrypt( CASTContext,
(PGPByte *)&(SDAHeader.CheckBytes),
(PGPByte *)&(SDAHeader.CheckBytes));
err=SDAEncryptFiles(context,
&SDAHeader,CASTContext,
fl,szOutputFileName,
#ifdef E_BUSINESS_SERVER
HashedPassphrase, sizeof(HashedPassphrase),
#endif /* E_BUSINESS_SERVER */
UserProc,pUserValue);
PGPFreeSymmetricCipherContext(CASTContext);
memset(HashedPassphrase,0x00,20);
#endif // IS_SEA
return err;
}
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -