Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6725 siemargl 1
/*
2
  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
3
 
4
  See the accompanying file LICENSE, version 2005-Feb-10 or later
5
  (the contents of which are also included in (un)zip.h) for terms of use.
6
  If, for some reason, all these files are missing, the Info-ZIP license
7
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
8
*/
9
/*
10
  crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
11
 
12
  The main encryption/decryption source code for Info-Zip software was
13
  originally written in Europe.  To the best of our knowledge, it can
14
  be freely distributed in both source and object forms from any country,
15
  including the USA under License Exception TSU of the U.S. Export
16
  Administration Regulations (section 740.13(e)) of 6 June 2002.
17
 
18
  NOTE on copyright history:
19
  Previous versions of this source package (up to version 2.8) were
20
  not copyrighted and put in the public domain.  If you cannot comply
21
  with the Info-Zip LICENSE, you may want to look for one of those
22
  public domain versions.
23
 */
24
 
25
/*
26
  This encryption code is a direct transcription of the algorithm from
27
  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
28
  file (appnote.txt) is distributed with the PKZIP program (even in the
29
  version without encryption capabilities).
30
 */
31
 
32
#define ZCRYPT_INTERNAL
33
#include "zip.h"
34
#include "crypt.h"
35
#include "ttyio.h"
36
 
37
#if CRYPT
38
 
39
#ifndef FALSE
40
#  define FALSE 0
41
#endif
42
 
43
#ifdef ZIP
44
   /* For the encoding task used in Zip (and ZipCloak), we want to initialize
45
      the crypt algorithm with some reasonably unpredictable bytes, see
46
      the crypthead() function. The standard rand() library function is
47
      used to supply these `random' bytes, which in turn is initialized by
48
      a srand() call. The srand() function takes an "unsigned" (at least 16bit)
49
      seed value as argument to determine the starting point of the rand()
50
      pseudo-random number generator.
51
      This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
52
      Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
53
      as some (hopefully) nondeterministic bitmask. On many (most) systems,
54
      we use some "process specific" number, as the PID or something similar,
55
      but when nothing unpredictable is available, a fixed number may be
56
      sufficient.
57
      NOTE:
58
      1.) This implementation requires the availability of the following
59
          standard UNIX C runtime library functions: time(), rand(), srand().
60
          On systems where some of them are missing, the environment that
61
          incorporates the crypt routines must supply suitable replacement
62
          functions.
63
      2.) It is a very bad idea to use a second call to time() to set the
64
          "Seed2" number! In this case, both "Seed1" and "Seed2" would be
65
          (almost) identical, resulting in a (mostly) "zero" constant seed
66
          number passed to srand().
67
 
68
      The implementation environment defined in the "zip.h" header should
69
      supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
70
      most implementations of rand() and srand(), only the lower 16 bits are
71
      significant!). An example that works on many systems would be
72
           "#define ZCR_SEED2  (unsigned)getpid()".
73
      The default definition for ZCR_SEED2 supplied below should be regarded
74
      as a fallback to allow successful compilation in "beta state"
75
      environments.
76
    */
77
#  include      /* time() function supplies first part of crypt seed */
78
   /* "last resort" source for second part of crypt seed pattern */
79
#  ifndef ZCR_SEED2
80
#    define ZCR_SEED2 (unsigned)3141592654L     /* use PI as default pattern */
81
#  endif
82
#  ifdef GLOBAL         /* used in Amiga system headers, maybe others too */
83
#    undef GLOBAL
84
#  endif
85
#  define GLOBAL(g) g
86
#else /* !ZIP */
87
#  define GLOBAL(g) G.g
88
#endif /* ?ZIP */
89
 
90
 
91
#ifdef UNZIP
92
   /* char *key = (char *)NULL; moved to globals.h */
93
#  ifndef FUNZIP
94
     local int testp OF((__GPRO__ ZCONST uch *h));
95
     local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
96
#  endif
97
#endif /* UNZIP */
98
 
99
#ifndef UNZIP             /* moved to globals.h for UnZip */
100
#  ifndef Z_UINT4_DEFINED
101
#   if !defined(NO_LIMITS_H)
102
#    if (defined(UINT_MAX) && (UINT_MAX == 0xffffffffUL))
103
       typedef unsigned int     z_uint4;
104
#      define Z_UINT4_DEFINED
105
#    else
106
#    if (defined(ULONG_MAX) && (ULONG_MAX == 0xffffffffUL))
107
       typedef unsigned long    z_uint4;
108
#      define Z_UINT4_DEFINED
109
#    else
110
#    if (defined(USHRT_MAX) && (USHRT_MAX == 0xffffffffUL))
111
       typedef unsigned short   z_uint4;
112
#      define Z_UINT4_DEFINED
113
#    endif
114
#    endif
115
#    endif
116
#   endif /* !NO_LIMITS_H */
117
#  endif /* !Z_UINT4_DEFINED */
118
#  ifndef Z_UINT4_DEFINED
119
     typedef ulg                z_uint4;
120
#    define Z_UINT4_DEFINED
121
#  endif
122
   local z_uint4 keys[3];       /* keys defining the pseudo-random sequence */
123
#endif /* !UNZIP */
124
 
125
#ifndef Trace
126
#  ifdef CRYPT_DEBUG
127
#    define Trace(x) fprintf x
128
#  else
129
#    define Trace(x)
130
#  endif
131
#endif
132
 
133
#include "crc32.h"
134
 
135
#ifdef IZ_CRC_BE_OPTIMIZ
136
   local z_uint4 near crycrctab[256];
137
   local z_uint4 near *cry_crctb_p = NULL;
138
   local z_uint4 near *crytab_init OF((__GPRO));
139
#  define CRY_CRC_TAB  cry_crctb_p
140
#  undef CRC32
141
#  define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
142
#else
143
#  define CRY_CRC_TAB  CRC_32_TAB
144
#endif /* ?IZ_CRC_BE_OPTIMIZ */
145
 
146
/***********************************************************************
147
 * Return the next byte in the pseudo-random sequence
148
 */
149
int decrypt_byte(__G)
150
    __GDEF
151
{
152
    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
153
                     * unpredictable manner on 16-bit systems; not a problem
154
                     * with any known compiler so far, though */
155
 
156
    temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
157
    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
158
}
159
 
160
/***********************************************************************
161
 * Update the encryption keys with the next byte of plain text
162
 */
163
int update_keys(__G__ c)
164
    __GDEF
165
    int c;                      /* byte of plain text */
166
{
167
    GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c, CRY_CRC_TAB);
168
    GLOBAL(keys[1]) = (GLOBAL(keys[1])
169
                       + (GLOBAL(keys[0]) & 0xff))
170
                      * 134775813L + 1;
171
    {
172
      register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
173
      GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift, CRY_CRC_TAB);
174
    }
175
    return c;
176
}
177
 
178
 
179
/***********************************************************************
180
 * Initialize the encryption keys and the random header according to
181
 * the given password.
182
 */
183
void init_keys(__G__ passwd)
184
    __GDEF
185
    ZCONST char *passwd;        /* password string with which to modify keys */
186
{
187
#ifdef IZ_CRC_BE_OPTIMIZ
188
    if (cry_crctb_p == NULL) {
189
        cry_crctb_p = crytab_init(__G);
190
    }
191
#endif
192
    GLOBAL(keys[0]) = 305419896L;
193
    GLOBAL(keys[1]) = 591751049L;
194
    GLOBAL(keys[2]) = 878082192L;
195
    while (*passwd != '\0') {
196
        update_keys(__G__ (int)*passwd);
197
        passwd++;
198
    }
199
}
200
 
201
 
202
/***********************************************************************
203
 * Initialize the local copy of the table of precomputed crc32 values.
204
 * Whereas the public crc32-table is optimized for crc32 calculations
205
 * on arrays of bytes, the crypt code needs the crc32 values in an
206
 * byte-order-independent form as 32-bit unsigned numbers. On systems
207
 * with Big-Endian byte order using the optimized crc32 code, this
208
 * requires inverting the byte-order of the values in the
209
 * crypt-crc32-table.
210
 */
211
#ifdef IZ_CRC_BE_OPTIMIZ
212
local z_uint4 near *crytab_init(__G)
213
    __GDEF
214
{
215
    int i;
216
 
217
    for (i = 0; i < 256; i++) {
218
        crycrctab[i] = REV_BE(CRC_32_TAB[i]);
219
    }
220
    return crycrctab;
221
}
222
#endif
223
 
224
 
225
#ifdef ZIP
226
 
227
/***********************************************************************
228
 * Write encryption header to file zfile using the password passwd
229
 * and the cyclic redundancy check crc.
230
 */
231
void crypthead(passwd, crc, zfile)
232
    ZCONST char *passwd;         /* password string */
233
    ulg crc;                     /* crc of file being encrypted */
234
    FILE *zfile;                 /* where to write header */
235
{
236
    int n;                       /* index in random header */
237
    int t;                       /* temporary */
238
    int c;                       /* random byte */
239
    uch header[RAND_HEAD_LEN];   /* random header */
240
    static unsigned calls = 0;   /* ensure different random header each time */
241
 
242
    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
243
     * output of rand() to get less predictability, since rand() is
244
     * often poorly implemented.
245
     */
246
    if (++calls == 1) {
247
        srand((unsigned)time(NULL) ^ ZCR_SEED2);
248
    }
249
    init_keys(passwd);
250
    for (n = 0; n < RAND_HEAD_LEN-2; n++) {
251
        c = (rand() >> 7) & 0xff;
252
        header[n] = (uch)zencode(c, t);
253
    }
254
    /* Encrypt random header (last two bytes is high word of crc) */
255
    init_keys(passwd);
256
    for (n = 0; n < RAND_HEAD_LEN-2; n++) {
257
        header[n] = (uch)zencode(header[n], t);
258
    }
259
    header[RAND_HEAD_LEN-2] = (uch)zencode((int)(crc >> 16) & 0xff, t);
260
    header[RAND_HEAD_LEN-1] = (uch)zencode((int)(crc >> 24) & 0xff, t);
261
    fwrite(header, 1, RAND_HEAD_LEN, f);
262
}
263
 
264
 
265
#ifdef UTIL
266
 
267
/***********************************************************************
268
 * Encrypt the zip entry described by z from file source to file dest
269
 * using the password passwd.  Return an error code in the ZE_ class.
270
 */
271
int zipcloak(z, source, dest, passwd)
272
    struct zlist far *z;    /* zip entry to encrypt */
273
    FILE *source, *dest;    /* source and destination files */
274
    ZCONST char *passwd;    /* password string */
275
{
276
    int c;                  /* input byte */
277
    int res;                /* result code */
278
    ulg n;                  /* holds offset and counts size */
279
    ush flag;               /* previous flags */
280
    int t;                  /* temporary */
281
    int ztemp;              /* temporary storage for zencode value */
282
 
283
    /* Set encrypted bit, clear extended local header bit and write local
284
       header to output file */
285
    if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
286
    z->off = n;
287
    flag = z->flg;
288
    z->flg |= 1,  z->flg &= ~8;
289
    z->lflg |= 1, z->lflg &= ~8;
290
    z->siz += RAND_HEAD_LEN;
291
    if ((res = putlocal(z, dest)) != ZE_OK) return res;
292
 
293
    /* Initialize keys with password and write random header */
294
    crypthead(passwd, z->crc, dest);
295
 
296
    /* Skip local header in input file */
297
    if (fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext),
298
              SEEK_CUR)) {
299
        return ferror(source) ? ZE_READ : ZE_EOF;
300
    }
301
 
302
    /* Encrypt data */
303
    for (n = z->siz - RAND_HEAD_LEN; n; n--) {
304
        if ((c = getc(source)) == EOF) {
305
            return ferror(source) ? ZE_READ : ZE_EOF;
306
        }
307
        ztemp = zencode(c, t);
308
        putc(ztemp, dest);
309
    }
310
    /* Skip extended local header in input file if there is one */
311
    if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
312
        return ferror(source) ? ZE_READ : ZE_EOF;
313
    }
314
    if (fflush(dest) == EOF) return ZE_TEMP;
315
 
316
    /* Update number of bytes written to output file */
317
    tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz;
318
 
319
    return ZE_OK;
320
}
321
 
322
/***********************************************************************
323
 * Decrypt the zip entry described by z from file source to file dest
324
 * using the password passwd.  Return an error code in the ZE_ class.
325
 */
326
int zipbare(z, source, dest, passwd)
327
    struct zlist far *z;  /* zip entry to encrypt */
328
    FILE *source, *dest;  /* source and destination files */
329
    ZCONST char *passwd;  /* password string */
330
{
331
#ifdef ZIP10
332
    int c0                /* byte preceding the last input byte */
333
#endif
334
    int c1;               /* last input byte */
335
    ulg offset;           /* used for file offsets */
336
    ulg size;             /* size of input data */
337
    int r;                /* size of encryption header */
338
    int res;              /* return code */
339
    ush flag;             /* previous flags */
340
 
341
    /* Save position and skip local header in input file */
342
    if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
343
        fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext),
344
              SEEK_CUR)) {
345
        return ferror(source) ? ZE_READ : ZE_EOF;
346
    }
347
    /* Initialize keys with password */
348
    init_keys(passwd);
349
 
350
    /* Decrypt encryption header, save last two bytes */
351
    c1 = 0;
352
    for (r = RAND_HEAD_LEN; r; r--) {
353
#ifdef ZIP10
354
        c0 = c1;
355
#endif
356
        if ((c1 = getc(source)) == EOF) {
357
            return ferror(source) ? ZE_READ : ZE_EOF;
358
        }
359
        Trace((stdout, " (%02x)", c1));
360
        zdecode(c1);
361
        Trace((stdout, " %02x", c1));
362
    }
363
    Trace((stdout, "\n"));
364
 
365
    /* If last two bytes of header don't match crc (or file time in the
366
     * case of an extended local header), back up and just copy. For
367
     * pkzip 2.0, the check has been reduced to one byte only.
368
     */
369
#ifdef ZIP10
370
    if ((ush)(c0 | (c1<<8)) !=
371
        (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
372
#else
373
    if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
374
#endif
375
        if (fseek(source, offset, SEEK_SET)) {
376
            return ferror(source) ? ZE_READ : ZE_EOF;
377
        }
378
        if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
379
        return ZE_MISS;
380
    }
381
 
382
    /* Clear encrypted bit and local header bit, and write local header to
383
       output file */
384
    if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
385
    z->off = offset;
386
    flag = z->flg;
387
    z->flg &= ~9;
388
    z->lflg &= ~9;
389
    z->siz -= RAND_HEAD_LEN;
390
    if ((res = putlocal(z, dest)) != ZE_OK) return res;
391
 
392
    /* Decrypt data */
393
    for (size = z->siz; size; size--) {
394
        if ((c1 = getc(source)) == EOF) {
395
            return ferror(source) ? ZE_READ : ZE_EOF;
396
        }
397
        zdecode(c1);
398
        putc(c1, dest);
399
    }
400
    /* Skip extended local header in input file if there is one */
401
    if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
402
        return ferror(source) ? ZE_READ : ZE_EOF;
403
    }
404
    if (fflush(dest) == EOF) return ZE_TEMP;
405
 
406
    /* Update number of bytes written to output file */
407
    tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz;
408
 
409
    return ZE_OK;
410
}
411
 
412
 
413
#else /* !UTIL */
414
 
415
/***********************************************************************
416
 * If requested, encrypt the data in buf, and in any case call fwrite()
417
 * with the arguments to zfwrite().  Return what fwrite() returns.
418
 *
419
 * A bug has been found when encrypting large files.  See trees.c
420
 * for details and the fix.
421
 */
422
unsigned zfwrite(buf, item_size, nb, f)
423
    zvoid *buf;                 /* data buffer */
424
    extent item_size;           /* size of each item in bytes */
425
    extent nb;                  /* number of items */
426
    FILE *f;                    /* file to write to */
427
{
428
    int t;                      /* temporary */
429
 
430
    if (key != (char *)NULL) {  /* key is the global password pointer */
431
        ulg size;               /* buffer size */
432
        char *p = (char*)buf;   /* steps through buffer */
433
 
434
        /* Encrypt data in buffer */
435
        for (size = item_size*(ulg)nb; size != 0; p++, size--) {
436
            *p = (char)zencode(*p, t);
437
        }
438
    }
439
    /* Write the buffer out */
440
    return fwrite(buf, item_size, nb, f);
441
}
442
 
443
#endif /* ?UTIL */
444
#endif /* ZIP */
445
 
446
 
447
#if (defined(UNZIP) && !defined(FUNZIP))
448
 
449
/***********************************************************************
450
 * Get the password and set up keys for current zipfile member.
451
 * Return PK_ class error.
452
 */
453
int decrypt(__G__ passwrd)
454
    __GDEF
455
    ZCONST char *passwrd;
456
{
457
    ush b;
458
    int n, r;
459
    uch h[RAND_HEAD_LEN];
460
 
461
    Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
462
 
463
    /* get header once (turn off "encrypted" flag temporarily so we don't
464
     * try to decrypt the same data twice) */
465
    GLOBAL(pInfo->encrypted) = FALSE;
466
    defer_leftover_input(__G);
467
    for (n = 0; n < RAND_HEAD_LEN; n++) {
468
        b = NEXTBYTE;
469
        h[n] = (uch)b;
470
        Trace((stdout, " (%02x)", h[n]));
471
    }
472
    undefer_input(__G);
473
    GLOBAL(pInfo->encrypted) = TRUE;
474
 
475
    if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
476
        GLOBAL(newzip) = FALSE;
477
        if (passwrd != (char *)NULL) { /* user gave password on command line */
478
            if (!GLOBAL(key)) {
479
                if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
480
                    (char *)NULL)
481
                    return PK_MEM2;
482
                strcpy(GLOBAL(key), passwrd);
483
                GLOBAL(nopwd) = TRUE;  /* inhibit password prompting! */
484
            }
485
        } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
486
            free(GLOBAL(key));
487
            GLOBAL(key) = (char *)NULL;
488
        }
489
    }
490
 
491
    /* if have key already, test it; else allocate memory for it */
492
    if (GLOBAL(key)) {
493
        if (!testp(__G__ h))
494
            return PK_COOL;   /* existing password OK (else prompt for new) */
495
        else if (GLOBAL(nopwd))
496
            return PK_WARN;   /* user indicated no more prompting */
497
    } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
498
        return PK_MEM2;
499
 
500
    /* try a few keys */
501
    n = 0;
502
    do {
503
        r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
504
                             GLOBAL(zipfn), GLOBAL(filename));
505
        if (r == IZ_PW_ERROR) {         /* internal error in fetch of PW */
506
            free (GLOBAL(key));
507
            GLOBAL(key) = NULL;
508
            return PK_MEM2;
509
        }
510
        if (r != IZ_PW_ENTERED) {       /* user replied "skip" or "skip all" */
511
            *GLOBAL(key) = '\0';        /*   We try the NIL password, ... */
512
            n = 0;                      /*   and cancel fetch for this item. */
513
        }
514
        if (!testp(__G__ h))
515
            return PK_COOL;
516
        if (r == IZ_PW_CANCELALL)       /* User replied "Skip all" */
517
            GLOBAL(nopwd) = TRUE;       /*   inhibit any further PW prompt! */
518
    } while (n > 0);
519
 
520
    return PK_WARN;
521
 
522
} /* end function decrypt() */
523
 
524
 
525
 
526
/***********************************************************************
527
 * Test the password.  Return -1 if bad, 0 if OK.
528
 */
529
local int testp(__G__ h)
530
    __GDEF
531
    ZCONST uch *h;
532
{
533
    int r;
534
    char *key_translated;
535
 
536
    /* On systems with "obscure" native character coding (e.g., EBCDIC),
537
     * the first test translates the password to the "main standard"
538
     * character coding. */
539
 
540
#ifdef STR_TO_CP1
541
    /* allocate buffer for translated password */
542
    if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
543
        return -1;
544
    /* first try, test password translated "standard" charset */
545
    r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
546
#else /* !STR_TO_CP1 */
547
    /* first try, test password as supplied on the extractor's host */
548
    r = testkey(__G__ h, GLOBAL(key));
549
#endif /* ?STR_TO_CP1 */
550
 
551
#ifdef STR_TO_CP2
552
    if (r != 0) {
553
#ifndef STR_TO_CP1
554
        /* now prepare for second (and maybe third) test with translated pwd */
555
        if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
556
            return -1;
557
#endif
558
        /* second try, password translated to alternate ("standard") charset */
559
        r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
560
#ifdef STR_TO_CP3
561
        if (r != 0)
562
            /* third try, password translated to another "standard" charset */
563
            r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
564
#endif
565
#ifndef STR_TO_CP1
566
        free(key_translated);
567
#endif
568
    }
569
#endif /* STR_TO_CP2 */
570
 
571
#ifdef STR_TO_CP1
572
    free(key_translated);
573
    if (r != 0) {
574
        /* last resort, test password as supplied on the extractor's host */
575
        r = testkey(__G__ h, GLOBAL(key));
576
    }
577
#endif /* STR_TO_CP1 */
578
 
579
    return r;
580
 
581
} /* end function testp() */
582
 
583
 
584
local int testkey(__G__ h, key)
585
    __GDEF
586
    ZCONST uch *h;      /* decrypted header */
587
    ZCONST char *key;   /* decryption password to test */
588
{
589
    ush b;
590
#ifdef ZIP10
591
    ush c;
592
#endif
593
    int n;
594
    uch *p;
595
    uch hh[RAND_HEAD_LEN]; /* decrypted header */
596
 
597
    /* set keys and save the encrypted header */
598
    init_keys(__G__ key);
599
    memcpy(hh, h, RAND_HEAD_LEN);
600
 
601
    /* check password */
602
    for (n = 0; n < RAND_HEAD_LEN; n++) {
603
        zdecode(hh[n]);
604
        Trace((stdout, " %02x", hh[n]));
605
    }
606
 
607
    Trace((stdout,
608
      "\n  lrec.crc= %08lx  crec.crc= %08lx  pInfo->ExtLocHdr= %s\n",
609
      GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
610
      GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
611
    Trace((stdout, "  incnt = %d  unzip offset into zipfile = %ld\n",
612
      GLOBAL(incnt),
613
      GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
614
 
615
    /* same test as in zipbare(): */
616
 
617
#ifdef ZIP10 /* check two bytes */
618
    c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
619
    Trace((stdout,
620
      "  (c | (b<<8)) = %04x  (crc >> 16) = %04x  lrec.time = %04x\n",
621
      (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
622
      ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
623
    if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
624
                           ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
625
                           (ush)(GLOBAL(lrec.crc32) >> 16)))
626
        return -1;  /* bad */
627
#else
628
    b = hh[RAND_HEAD_LEN-1];
629
    Trace((stdout, "  b = %02x  (crc >> 24) = %02x  (lrec.time >> 8) = %02x\n",
630
      b, (ush)(GLOBAL(lrec.crc32) >> 24),
631
      ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
632
    if (b != (GLOBAL(pInfo->ExtLocHdr) ?
633
        ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
634
        (ush)(GLOBAL(lrec.crc32) >> 24)))
635
        return -1;  /* bad */
636
#endif
637
    /* password OK:  decrypt current buffer contents before leaving */
638
    for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
639
             (int)GLOBAL(csize) : GLOBAL(incnt),
640
         p = GLOBAL(inptr); n--; p++)
641
        zdecode(*p);
642
    return 0;       /* OK */
643
 
644
} /* end function testkey() */
645
 
646
#endif /* UNZIP && !FUNZIP */
647
 
648
#else /* !CRYPT */
649
 
650
/* something "externally visible" to shut up compiler/linker warnings */
651
int zcr_dummy;
652
 
653
#endif /* ?CRYPT */