|
|
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.