int main(int argc, char *argv[]) { FILE *inf, *outf; unsigned char buf[1024], tmp_buf1[16], tmp_buf2[16], salt[16], *fname, *cp; fcrypt_ctx zcx[1]; int len, flen, err = 0; unsigned char mode; if(argc != 3) /* the command line is bad */ { err = ERROR_USAGE; goto error_0; } len = (int)strlen(argv[1]); if(len < 8) /* password is too short */ { err = ERROR_PASSWORD_LENGTH; goto error_0; } /* set the key length based on password length assuming that there */ /* are about 4 bits of entropy per password character (the key */ /* length and other mode dependent parameter values are set using */ /* macros defined in fileenc.h) */ mode = (len < 32 ? 1 : len < 48 ? 2 : 3); /* save input file name to a temporary memory area with extra space */ /* for the extension ".enc" to be added */ fname = (unsigned char*)malloc(strlen(argv[2]) + 5); if(fname == NULL) { err = ERROR_OUT_OF_MEMORY; goto error_0; } /* open the input file */ strcpy(fname, argv[2]); if((inf = fopen(fname, "rb")) == NULL) { err = ERROR_INPUT_FILE; goto error_1; } /* if the file name extension is ".enc" assume this is an encrypted */ /* file */ if((cp = strrchr(fname, '.')) && strcmp(cp, ".enc") == 0) { *cp = 0; mode |= 4; /* signal decryption */ } else /* add ".enc" to file name to mark the */ strcat(fname, ".enc"); /* the file as an encrypted one */ /* open output file for binary output */ if((outf = fopen(fname, "wb")) == NULL) { err = ERROR_OUTPUT_FILE; goto error_2; } if(!(mode & 4)) /* encryption operation */ { prng_ctx rng[1]; /* the context for the random number pool */ prng_init(entropy_fun, rng); /* initialise RNG */ prng_rand(salt, SALT_LENGTH(mode), rng); /* and the salt */ /* write salt value */ fwrite(salt, sizeof(unsigned char), SALT_LENGTH(mode), outf); /* initialise encryption and authentication */ #ifdef PASSWORD_VERIFIER fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, tmp_buf1, zcx); /* write password verifier (if used) */ fwrite(tmp_buf1, sizeof(unsigned char), PWD_VER_LENGTH, outf); #else fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, zcx); #endif /* encrypt and authenticate the file */ len = (int)fread(buf, sizeof(unsigned char), 1024, inf); while(len) { fcrypt_encrypt(buf, len, zcx); fwrite(buf, sizeof(unsigned char), len, outf); len = (int)fread(buf, sizeof(unsigned char), len, inf); } /* write the MAC */ fcrypt_end(tmp_buf1, zcx); fwrite(tmp_buf1, sizeof(unsigned char), MAC_LENGTH(mode), outf); /* and close random pool */ prng_end(rng); } else /* decryption operation */ { /* we need to know the file length to avoid reading the MAC */ fseek(inf, 0, SEEK_END); flen = ftell(inf); fseek(inf, 0, SEEK_SET); mode &= 3; /* recover the password salt */ fread(salt, sizeof(unsigned char), SALT_LENGTH(mode), inf); flen -= SALT_LENGTH(mode); #ifdef PASSWORD_VERIFIER /* initialise encryption and authentication */ fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, tmp_buf2, zcx); /* recover the password verifier (if used) */ fread(tmp_buf1, sizeof(unsigned char), PWD_VER_LENGTH, inf); flen -= PWD_VER_LENGTH; /* check password verifier */ if(memcmp(tmp_buf1, tmp_buf2, PWD_VER_LENGTH)) { err = ERROR_BAD_PASSWORD; fclose(outf); goto error_2; } #else /* initialise encryption and authentication */ fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, zcx); #endif flen -= MAC_LENGTH(mode); /* avoid reading the MAC */ /* decrypt the file */ len = (int)fread(buf, sizeof(unsigned char), (size_t)(flen < 1024 ? flen : 1024), inf); while(len) { flen -= len; fcrypt_decrypt(buf, len, zcx); fwrite(buf, sizeof(unsigned char), len, outf); len = (int)fread(buf, sizeof(unsigned char), (size_t)(flen < 1024 ? flen : 1024), inf); } /* calculate the MAC value */ fcrypt_end(tmp_buf2, zcx); /* now read the stored MAC value */ fread(tmp_buf1, sizeof(unsigned char), MAC_LENGTH(mode), inf); /* compare the stored and calculated MAC values */ if(memcmp(tmp_buf1, tmp_buf2, MAC_LENGTH(mode))) { /* authentication failed */ err = ERROR_BAD_AUTHENTICATION; fclose(outf); /* delete the (bad) output file */ remove(fname); goto error_2; } } fclose(outf); error_2: fclose(inf); error_1: free(fname); error_0: if(err) printf(err_string[err - 1], fname); return -err; }
//! opens a file by index IReadFile* CZipReader::createAndOpenFile(u32 index) { // Irrlicht supports 0, 8, 12, 14, 99 //0 - The file is stored (no compression) //1 - The file is Shrunk //2 - The file is Reduced with compression factor 1 //3 - The file is Reduced with compression factor 2 //4 - The file is Reduced with compression factor 3 //5 - The file is Reduced with compression factor 4 //6 - The file is Imploded //7 - Reserved for Tokenizing compression algorithm //8 - The file is Deflated //9 - Reserved for enhanced Deflating //10 - PKWARE Date Compression Library Imploding //12 - bzip2 - Compression Method from libbz2, WinZip 10 //14 - LZMA - Compression Method, WinZip 12 //96 - Jpeg compression - Compression Method, WinZip 12 //97 - WavPack - Compression Method, WinZip 11 //98 - PPMd - Compression Method, WinZip 10 //99 - AES encryption, WinZip 9 const SZipFileEntry &e = FileInfo[Files[index].ID]; wchar_t buf[64]; s16 actualCompressionMethod=e.header.CompressionMethod; IReadFile* decrypted=0; u8* decryptedBuf=0; u32 decryptedSize=e.header.DataDescriptor.CompressedSize; #ifdef _IRR_COMPILE_WITH_ZIP_ENCRYPTION_ if ((e.header.GeneralBitFlag & ZIP_FILE_ENCRYPTED) && (e.header.CompressionMethod == 99)) { os::Printer::log("Reading encrypted file."); u8 salt[16]={0}; const u16 saltSize = (((e.header.Sig & 0x00ff0000) >>16)+1)*4; File->seek(e.Offset); File->read(salt, saltSize); char pwVerification[2]; char pwVerificationFile[2]; File->read(pwVerification, 2); fcrypt_ctx zctx; // the encryption context int rc = fcrypt_init( (e.header.Sig & 0x00ff0000) >>16, (const unsigned char*)Password.c_str(), // the password Password.size(), // number of bytes in password salt, // the salt (unsigned char*)pwVerificationFile, // on return contains password verifier &zctx); // encryption context if (strncmp(pwVerificationFile, pwVerification, 2)) { os::Printer::log("Wrong password"); return 0; } decryptedSize= e.header.DataDescriptor.CompressedSize-saltSize-12; decryptedBuf= new u8[decryptedSize]; u32 c = 0; while ((c+32768)<=decryptedSize) { File->read(decryptedBuf+c, 32768); fcrypt_decrypt( decryptedBuf+c, // pointer to the data to decrypt 32768, // how many bytes to decrypt &zctx); // decryption context c+=32768; } File->read(decryptedBuf+c, decryptedSize-c); fcrypt_decrypt( decryptedBuf+c, // pointer to the data to decrypt decryptedSize-c, // how many bytes to decrypt &zctx); // decryption context char fileMAC[10]; char resMAC[10]; rc = fcrypt_end( (unsigned char*)resMAC, // on return contains the authentication code &zctx); // encryption context if (rc != 10) { os::Printer::log("Error on encryption closing"); delete [] decryptedBuf; return 0; } File->read(fileMAC, 10); if (strncmp(fileMAC, resMAC, 10)) { os::Printer::log("Error on encryption check"); delete [] decryptedBuf; return 0; } decrypted = io::createMemoryReadFile(decryptedBuf, decryptedSize, Files[index].FullName, true); actualCompressionMethod = (e.header.Sig & 0xffff); #if 0 if ((e.header.Sig & 0xff000000)==0x01000000) { } else if ((e.header.Sig & 0xff000000)==0x02000000) { } else { os::Printer::log("Unknown encryption method"); return 0; } #endif }