Esempio n. 1
1
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;
}
Esempio n. 2
0
//! 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
	}