|
|
1.1 ! root 1: /* ! 2: This code is not copyrighted and is put in the public domain. It ! 3: was originally written in Europe and can be freely distributed from ! 4: any country except the U.S.A. If this code is imported in the U.S.A, ! 5: it cannot be re-exported from the U.S.A to another country. (This ! 6: restriction might seem curious but this is what US law requires.) ! 7: */ ! 8: ! 9: /* This encryption code is a direct transcription of the algorithm from ! 10: Roger Schlafly, described by Phil Katz in the file appnote.txt. This ! 11: file is distributed with the PKZIP program (even in the version without ! 12: encryption capabilities). ! 13: */ ! 14: ! 15: #include "zip.h" ! 16: ! 17: #ifndef SKIP_TIME_H /* time.h already included in UnZip version */ ! 18: # include <time.h> ! 19: #endif /* !SKIP_TIME_H */ ! 20: ! 21: #if ((defined(MSDOS) || defined(__MSDOS__) || defined(WIN32)) && !defined(__GO32__)) ! 22: # include <process.h> ! 23: #else ! 24: int getpid OF((void)); ! 25: #endif ! 26: ! 27: #ifndef __GNUC__ ! 28: void srand OF((unsigned int)); ! 29: #endif ! 30: int rand OF((void)); ! 31: ! 32: int decrypt_byte OF((void)); ! 33: void update_keys OF((int c)); ! 34: void init_keys OF((char *passwd)); ! 35: int zencode OF((int c)); ! 36: int zdecode OF((int c)); ! 37: ! 38: local ulg keys[3]; /* keys defining the pseudo random sequence */ ! 39: ! 40: /*********************************************************************** ! 41: * Return the next byte in the pseudo-random sequence ! 42: */ ! 43: int decrypt_byte() ! 44: { ! 45: ush temp; ! 46: ! 47: temp = (ush)keys[2] | 2; ! 48: return (int)(((ush)(temp * (temp ^ 1)) >> 8) & 0xff); ! 49: } ! 50: ! 51: /*********************************************************************** ! 52: * Update the encryption keys with the next byte of plain text ! 53: */ ! 54: void update_keys(c) ! 55: int c; /* byte of plain text */ ! 56: { ! 57: keys[0] = crc32(keys[0], c); ! 58: keys[1] += keys[0] & 0xff; ! 59: keys[1] = keys[1] * 134775813L + 1; ! 60: keys[2] = crc32(keys[2], (int)(keys[1] >> 24)); ! 61: } ! 62: ! 63: ! 64: /*********************************************************************** ! 65: * Initialize the encryption keys and the random header according to ! 66: * the given password. ! 67: */ ! 68: void init_keys(passwd) ! 69: char *passwd; /* password string to modify keys with */ ! 70: { ! 71: keys[0] = 305419896L; ! 72: keys[1] = 591751049L; ! 73: keys[2] = 878082192L; ! 74: while (*passwd != '\0') { ! 75: update_keys((int)*passwd); ! 76: passwd++; ! 77: } ! 78: } ! 79: ! 80: /*********************************************************************** ! 81: * Return the encoded value of the byte c of the plain text ! 82: */ ! 83: int zencode(c) ! 84: int c; ! 85: { ! 86: int temp = decrypt_byte(); ! 87: ! 88: update_keys(c); ! 89: return temp ^ c; ! 90: } ! 91: ! 92: /*********************************************************************** ! 93: * Return the decoded value of the byte c of the cypher text ! 94: */ ! 95: int zdecode(c) ! 96: int c; ! 97: { ! 98: int temp = c ^ decrypt_byte(); ! 99: ! 100: update_keys(temp); ! 101: return temp; ! 102: } ! 103: ! 104: ! 105: /*********************************************************************** ! 106: * Write encryption header to file zfile using the password passwd ! 107: * and the cyclic redundancy check crc. Note: we use the rand() library ! 108: * function, which is quite bad on many systems. But since we only ! 109: * need 10 values, this is not important. ! 110: */ ! 111: void crypthead(passwd, crc, zfile) ! 112: char *passwd; /* password string */ ! 113: ulg crc; /* crc of file being encrypted */ ! 114: FILE *zfile; /* where to write header to */ ! 115: { ! 116: int n = 10; /* size of random header */ ! 117: ! 118: init_keys(passwd); ! 119: ! 120: /* Encrypt random header (last two bytes is high word of crc) */ ! 121: ! 122: srand((unsigned int)time(NULL) ^ getpid()); /* initialize generator */ ! 123: while (n--) { ! 124: putc(zencode(rand() >> 7), zfile); ! 125: } ! 126: putc(zencode((int)(crc >> 16) & 0xff), zfile); ! 127: putc(zencode((int)(crc >> 24)), zfile); ! 128: } ! 129: ! 130: ! 131: #ifdef UTIL ! 132: ! 133: /*********************************************************************** ! 134: * Encrypt the zip entry described by z from file source to file dest ! 135: * using the password passwd. Return an error code in the ZE_ class. ! 136: */ ! 137: int zipcloak(z, source, dest, passwd) ! 138: struct zlist far *z; /* zip entry to encrypt */ ! 139: FILE *source, *dest; /* source and destination files */ ! 140: char *passwd; /* password string */ ! 141: { ! 142: int c; /* input byte */ ! 143: int res; /* result code */ ! 144: ulg n; /* holds offset and counts size */ ! 145: ush flag; /* previous flags */ ! 146: ! 147: /* Set encrypted bit, clear extended local header bit and write local ! 148: header to output file */ ! 149: if ((n = ftell(dest)) == -1L) return ZE_TEMP; ! 150: z->off = n; ! 151: flag = z->flg; ! 152: z->flg |= 1, z->flg &= ~8; ! 153: z->lflg |= 1, z->lflg &= ~8; ! 154: z->siz += 12; ! 155: if ((res = putlocal(z, dest)) != ZE_OK) return res; ! 156: ! 157: /* Initialize keys with password and write random header */ ! 158: crypthead(passwd, z->crc, dest); ! 159: ! 160: /* Skip local header in input file */ ! 161: if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext), ! 162: SEEK_CUR)) { ! 163: return ferror(source) ? ZE_READ : ZE_EOF; ! 164: } ! 165: ! 166: /* Encrypt data */ ! 167: for (n = z->siz - 12; n; n--) { ! 168: if ((c = getc(source)) == EOF) { ! 169: return ferror(source) ? ZE_READ : ZE_EOF; ! 170: } ! 171: putc(zencode(c), dest); ! 172: } ! 173: /* Skip extended local header in input file if there is one */ ! 174: if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) { ! 175: return ferror(source) ? ZE_READ : ZE_EOF; ! 176: } ! 177: if (fflush(dest) == EOF) return ZE_TEMP; ! 178: return ZE_OK; ! 179: } ! 180: ! 181: /*********************************************************************** ! 182: * Decrypt the zip entry described by z from file source to file dest ! 183: * using the password passwd. Return an error code in the ZE_ class. ! 184: */ ! 185: int zipbare(z, source, dest, passwd) ! 186: struct zlist far *z; /* zip entry to encrypt */ ! 187: FILE *source, *dest; /* source and destination files */ ! 188: char *passwd; /* password string */ ! 189: { ! 190: int c0, c1; /* last two input bytes */ ! 191: ulg offset; /* used for file offsets */ ! 192: ulg size; /* size of input data */ ! 193: int r; /* size of encryption header */ ! 194: int res; /* return code */ ! 195: ush flag; /* previous flags */ ! 196: ! 197: /* Save position and skip local header in input file */ ! 198: if ((offset = ftell(source)) == -1L || ! 199: fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext), ! 200: SEEK_CUR)) { ! 201: return ferror(source) ? ZE_READ : ZE_EOF; ! 202: } ! 203: /* Initialize keys with password */ ! 204: init_keys(passwd); ! 205: ! 206: /* Decrypt encryption header, save last two bytes */ ! 207: c1 = 0; ! 208: for (r = 12; r; r--) { ! 209: c0 = c1; ! 210: if ((c1 = zdecode(getc(source))) == EOF) { ! 211: return ferror(source) ? ZE_READ : ZE_EOF; ! 212: } ! 213: } ! 214: ! 215: /* If last two bytes of header don't match crc (or file time in the ! 216: case of an extended local header), back up and just copy */ ! 217: if ((ush)(c0 | (c1<<8)) != ! 218: (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) { ! 219: if (fseek(source, offset, SEEK_SET)) { ! 220: return ferror(source) ? ZE_READ : ZE_EOF; ! 221: } ! 222: if ((res = zipcopy(z, source, dest)) != ZE_OK) return res; ! 223: return ZE_MISS; ! 224: } ! 225: ! 226: /* Clear encrypted bit and local header bit, and write local header to ! 227: output file */ ! 228: if ((offset = ftell(dest)) == -1L) return ZE_TEMP; ! 229: z->off = offset; ! 230: flag = z->flg; ! 231: z->flg &= ~9; ! 232: z->lflg &= ~9; ! 233: z->siz -= 12; ! 234: if ((res = putlocal(z, dest)) != ZE_OK) return res; ! 235: ! 236: /* Decrypt data */ ! 237: for (size = z->siz; size; size--) { ! 238: if ((c1 = getc(source)) == EOF) { ! 239: return ferror(source) ? ZE_READ : ZE_EOF; ! 240: } ! 241: putc(zdecode(c1), dest); ! 242: } ! 243: /* Skip extended local header in input file if there is one */ ! 244: if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) { ! 245: return ferror(source) ? ZE_READ : ZE_EOF; ! 246: } ! 247: if (fflush(dest) == EOF) return ZE_TEMP; ! 248: ! 249: return ZE_OK; ! 250: } ! 251: ! 252: ! 253: #else /* !UTIL */ ! 254: ! 255: /*********************************************************************** ! 256: * If requested, encrypt the data in buf, and in any case call fwrite() ! 257: * with the arguments to zfwrite(). Return what fwrite() returns. ! 258: */ ! 259: unsigned zfwrite(buf, item_size, nb, f) ! 260: voidp *buf; /* data buffer */ ! 261: extent item_size; /* size of each item in bytes */ ! 262: extent nb; /* number of items */ ! 263: FILE *f; /* file to write to */ ! 264: { ! 265: if (key != (char *)NULL) { /* key is the global password pointer */ ! 266: ulg size; /* buffer size */ ! 267: char *p = (char*)buf; /* steps through buffer */ ! 268: ! 269: /* Encrypt data in buffer */ ! 270: for (size = item_size*(ulg)nb; size != 0; p++, size--) { ! 271: *p = (char)zencode(*p); ! 272: } ! 273: } ! 274: /* Write the buffer out */ ! 275: return fwrite(buf, item_size, nb, f); ! 276: } ! 277: ! 278: /*********************************************************************** ! 279: * Encrypt the byte c and then do a putc(). The macro zputc defined in ! 280: * crypt.h checks keys and calls zfputc if needed. Return what putc() ! 281: * returns. This function is only provided for compatibility with zip 1.0. ! 282: */ ! 283: int zfputc(c, f) ! 284: int c; /* character to write */ ! 285: FILE *f; /* file to write it to */ ! 286: { ! 287: return putc(zencode(c), f); ! 288: } ! 289: ! 290: #endif /* ?UTIL */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.