#include "stdafx.h"
#pragma hdrstop
#include "dz_errs.h"
#undef _DZ_FILE_
#define _DZ_FILE_ DZ_UNZCRYPT_CPP
/*
* crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
*
* This code is not copyrighted and is put in the public domain. The
* encryption/decryption parts (as opposed to the non-echoing password
* parts) were originally written in Europe; the whole file can there-
* fore be freely distributed from any country except the USA. If this
* code is imported into the USA, it cannot be re-exported from from
* there to another country. (This restriction might seem curious, but
* this is what US law requires.) */
/* This version modified by Chris Vleghert and Eric W. Engler
* for BCB/Delphi Zip, Sep 22, 2000. */
/* This encryption code is a direct transcription of the algorithm from
* Roger Schlafly, described by Phil Katz in the file appnote.txt. This
* file (appnote.txt) is distributed with the PKZIP program (even in the
* version without encryption capabilities). *
Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
parts Copyright (C) 1997 Mike White, Eric W. Engler
************************************************************************
Copyright (C) 2009, 2010 by Russell J. Peters, Roger Aelbrecht
This file is part of TZipMaster Version 1.9.
TZipMaster is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TZipMaster is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TZipMaster. If not, see <http://www.gnu.org/licenses/>.
contact: problems@delphizip.org (include ZipMaster in the subject).
updates: http://www.delphizip.org
DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
************************************************************************/
#define ZCRYPT_INTERNAL
#include "UnzInf.h"
#include "crypt.h"
//#include "ucrypt.h"
//static int testp(UGlobals * pG, uch * h);
//static int testkey(UGlobals * pG, uch * h, char * key);
//# define NEXTBYTE (--fincnt >= 0 ? (int)(*finptr++) : readbyte())
/* ===========================================================================
* Get the password and set up keys for current zipfile member. Return * PK_ class error. */
int UnzInf::decrypt(ulg crc)
{
ush b;
int n, n1;//, r;
char h[RAND_HEAD_LEN];
if (Verbose < 0)
Notify(ITRACE, _T("in crypt.c, [incnt = %d]: "), fincnt); //stout
/* get header once (turn off "encrypted" flag temporarily so we don't * try to decrypt the same data twice) */
// fpInfo->encrypted = false;
Encrypted = false;
defer_leftover_input();
for (n = 0; n < RAND_HEAD_LEN; n++)
{
b = (ush)NEXTBYTE;
/* RCV: ush added */
h[n] = (uch)b;
//Trace((pG, " (%02x)", h[n])); //stdout
}
undefer_input();
Encrypted = true;
if (Verbose < 0)
Notify(ITRACE, _T("EWE - in crypt.c, near fnewzip test"));
if (!fPwdReqCount)
return PK_WARN;
if (fnewzip)
{
fnewzip = false;
if (Verbose < 0)
Notify(ITRACE, _T("newzip was set to false"));
if (fP_flag == true)
{
/* user gave password on command line */
#ifdef ZDEBUG
if (Verbose < 0)
Notify(ITRACE, _T("user set password=%s"), fpwdarg.c_str());
#endif
}
}
if (Verbose < 0)
Notify(ITRACE, _T("EWE- near 'have key already' test"));
/* if have key already, test it; else allocate memory for it */
if (fkey)
{
if (!testkey(h, fkey, crc))
{
if (Verbose < 0)
Notify(ITRACE, _T("existing pwd OK"));
return PK_COOL; // existing password OK (else prompt for new)
}
else
if (fnopwd)
return PK_WARN; // user indicated no more prompting
}
else
if (fnopwd)
return PK_WARN; // user indicated no more prompting
if (Verbose < 0)
Notify(ITRACE, _T("EWE- near 'try a few keys' test"));
/* try a few keys */
n = fPwdReqCount;
n1 = 15;
do
{
// Call the component with a request for a password
CB->Arg1 = n;
CB->Msg = ffilename;
int ucb = CB->UserCB(zacPassword);
if (ucb == CALLBACK_TRUE) // have password
{
fkey = DupStr(DZStrA(CB->Msg));
if (!testkey(h, fkey, crc)) // test local
return PK_COOL;
}
if (ucb == CALLBACK_3) // gave no password
{
fnopwd = true;
n1 = 1;
}
n = MIN((int)CB->Arg1 & 0x0F, n1);
}
while (--n > 0 && --n1 > 0 && !Abort_Flag);
return PK_WARN;
}
/* end function decrypt() */
/* ===========================================================================
*h :: Decrypted header.
*key :: Decryption password to test. */
int UnzInf::testkey(const char *h, const char *key, ulg crc)
{
ush b;
int n;
uch * p;
uch hh[RAND_HEAD_LEN];
/* decrypted header */
/* set keys and save the encrypted header */
init_keys(key, fkeys);
memcpy(hh, h, RAND_HEAD_LEN);
/* check password */
for (n = 0; n < RAND_HEAD_LEN; n++)
{
hh[n] = (uch) zdecode(hh[n], fkeys);
}
b = hh[RAND_HEAD_LEN - 1];
if (b != (ush)crc)
return -1; // bad
//#endif
/* password OK: decrypt current buffer contents before leaving */
for (n = (unsigned)fincnt > (unsigned) fcsize ? (int)fcsize : fincnt, p = finptr; n--; p++)
*p = (uch) zdecode(*p, fkeys);
return 0; // OK
}
/* end function testkey() */