Von C nach Java, Teil 4: Datenkompression und Verschlüsselung

Seite 10: Listing 6

Inhaltsverzeichnis
int processDecompression(char *fileName) {
FILE *ifp, *ofp;
int i, l, ch;
DWORD dwDestLen;
uchar hdr[MD5LEN], originalFileName[300], *outputBuffer;

if ((ifp=fopen(fileName,"rb"))==NULL) {
fprintf(stderr,"unable to open file \"%s\"\nfopen():
%s\n", fileName, strerror(errno));
return -1;
}
fread(hdr, 1, 3, ifp);
if (memcmp(hdr, magicHdr, 3) || ((ch=fgetc(ifp))!=0x80 && ch!=0x81)) {
fprintf(stderr,"invalid magic header -
probably not compressed with this program!\n");
fclose(ifp);
return -1;
}
isCrypt=(ch == 0x81);
if (isCrypt) {
if (!passwd) {
fprintf(stderr,"File %s is encrypted but no password
has been given in the command line\n", fileName);
fclose(ifp);
return -1;
}
fread(hdr, 1, MD5LEN, ifp);
if (memcmp(hdr, getMD5Hash(passwd, strlen(passwd)), MD5LEN)) {
fprintf(stderr,"wrong password!\n");
fclose(ifp);
return -1;
}
}
/**
* now create the output file
* extract the filename for the original file ...
*/
l=fgetc(ifp);
for (i=0;i<l;i++) {
originalFileName[i] = fgetc(ifp) ^ ~rand();
}
originalFileName[i]=0;
if (access(originalFileName, 0)>=0 && !isForce) {
fprintf(stderr,"File \"%s\" exists!\nUse
-f option to force overwrite!\n", originalFileName);
fclose (ifp);
return -1;
}
if ((ofp=fopen(originalFileName, "wb"))==NULL) {
fprintf(stderr,"unable to open file \"%s\"\nfopen():
%s\n", originalFileName, strerror(errno));
return -1;
}
/**
* now read the input BlockSize
*/
blockSizeKB=(fgetc(ifp)|(fgetc(ifp))<<8);
outputBuffer=malloc(blockSizeKB*1024);
if (isDebug) fprintf(stderr,"Input Block Length = %d KB\n", blockSizeKB);
for (;;) {
uchar *inputBuffer;
int blockLength=0;

if (fread(hdr, 1, 4, ifp)<4) break; // EOF
if (isDebug)
fprintf(stderr,"block length bytes: %02x %02x %02x %02x\n",
hdr[0], hdr[1], hdr[2], hdr[3]);
for (i=3;i>=0;i--) {
blockLength <<= 8;
blockLength |= hdr[i];
}
if ((inputBuffer=malloc(blockLength))==NULL) {
fprintf(stderr,"unable to allocate %d
bytes for the input buffer!\nmalloc() returned %d: %s\n",
blockLength, errno, strerror(errno));
fclose(ifp);
return -1;
}
if (fread(inputBuffer, 1, blockLength, ifp)<blockLength)
{ // unexp. EOF
fprintf(stderr,"unexpected EOF reading from input file!\n");
fclose(ifp);
return -1;
}
dwDestLen=blockSizeKB*1024;
if (isCrypt) {
/**
* block has to be de-crypted here ...
*/
#ifdef WIN32
bool bResult;
DWORD dwSize;
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;

if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV,
PROV_RSA_FULL, 0)) {
fprintf(stderr,"CryptAcquireContext() FAILED!\n");
return -1;
}
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
fprintf(stderr,"CryptCreateHash() FAILED!\n");
return -1;
}
if (!CryptHashData(hHash, passwd, strlen(passwd), 0)) {
fprintf(stderr,"CryptHashData() FAILED!\n");
return -1;
}
if (!CryptDeriveKey(hProv, CALG_RC4, hHash,
CRYPT_EXPORTABLE, &hKey)) {
fprintf(stderr,"CryptDeriveKey() FAILED!\n");
return -1;
}
dwSize=blockLength;
if (!CryptDecrypt(hKey, 0, TRUE, 0, inputBuffer, &dwSize)) {
fprintf(stderr,"CryptDecrypt(2) FAILED!\n");
return -1;
}
blockLength=dwSize;
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
#endif
}
if ((l=uncompress(outputBuffer, &dwDestLen, inputBuffer,
blockLength))!=Z_OK) {
fprintf(stderr,"uncompress() failed with %d -
dwDestLen=%d!\n", l, dwDestLen);
fclose(ifp);
return -1;
}
fwrite(outputBuffer, 1, dwDestLen, ofp);
free(inputBuffer);
}
fclose(ifp);
fclose(ofp);
return 1;
}