Annotation of embedaddon/php/ext/zip/lib/zip_source_pkware.c, revision 1.1.1.1
1.1 misho 1: /*
2: zip_source_pkware.c -- Traditional PKWARE de/encryption routines
3: Copyright (C) 2009 Dieter Baron and Thomas Klausner
4:
5: This file is part of libzip, a library to manipulate ZIP archives.
6: The authors can be contacted at <libzip@nih.at>
7:
8: Redistribution and use in source and binary forms, with or without
9: modification, are permitted provided that the following conditions
10: are met:
11: 1. Redistributions of source code must retain the above copyright
12: notice, this list of conditions and the following disclaimer.
13: 2. Redistributions in binary form must reproduce the above copyright
14: notice, this list of conditions and the following disclaimer in
15: the documentation and/or other materials provided with the
16: distribution.
17: 3. The names of the authors may not be used to endorse or promote
18: products derived from this software without specific prior
19: written permission.
20:
21: THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22: OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25: DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27: GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29: IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30: OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31: IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
33:
34:
35:
36: #include <stdlib.h>
37: #include <string.h>
38:
39: #include "zipint.h"
40:
41: struct trad_pkware {
42: int e[2];
43:
44: zip_uint32_t key[3];
45: };
46:
47: #define HEADERLEN 12
48: #define KEY0 305419896
49: #define KEY1 591751049
50: #define KEY2 878082192
51:
52: static const uLongf *crc = NULL;
53:
54: #define CRC32(c, b) (crc[((c) ^ (b)) & 0xff] ^ ((c) >> 8))
55:
56:
57:
58: static void decrypt(struct trad_pkware *, zip_uint8_t *,
59: const zip_uint8_t *, zip_uint64_t, int);
60: static int decrypt_header(struct zip_source *, struct trad_pkware *);
61: static zip_int64_t pkware_decrypt(struct zip_source *, void *, void *,
62: zip_uint64_t, enum zip_source_cmd);
63: static void pkware_free(struct trad_pkware *);
64:
65:
66:
67: ZIP_EXTERN(struct zip_source *)
68: zip_source_pkware(struct zip *za, struct zip_source *src,
69: zip_uint16_t em, int flags, const char *password)
70: {
71: struct trad_pkware *ctx;
72: struct zip_source *s2;
73:
74: if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
75: _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
76: return NULL;
77: }
78: if (flags & ZIP_CODEC_ENCODE) {
79: _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
80: return NULL;
81: }
82:
83: if (crc == NULL)
84: crc = get_crc_table();
85:
86: if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
87: _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
88: return NULL;
89: }
90:
91: ctx->e[0] = ctx->e[1] = 0;
92:
93: ctx->key[0] = KEY0;
94: ctx->key[1] = KEY1;
95: ctx->key[2] = KEY2;
96: decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
97:
98: if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
99: pkware_free(ctx);
100: return NULL;
101: }
102:
103: return s2;
104: }
105:
106:
107:
108: static void
109: decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
110: zip_uint64_t len, int update_only)
111: {
112: zip_uint16_t tmp;
113: zip_uint64_t i;
114: Bytef b;
115:
116: for (i=0; i<len; i++) {
117: b = in[i];
118:
119: if (!update_only) {
120: /* decrypt next byte */
121: tmp = ctx->key[2] | 2;
122: tmp = (tmp * (tmp ^ 1)) >> 8;
123: b ^= tmp;
124: }
125:
126: /* store cleartext */
127: if (out)
128: out[i] = b;
129:
130: /* update keys */
131: ctx->key[0] = CRC32(ctx->key[0], b);
132: ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
133: b = ctx->key[1] >> 24;
134: ctx->key[2] = CRC32(ctx->key[2], b);
135: }
136: }
137:
138:
139:
140: static int
141: decrypt_header(struct zip_source *src, struct trad_pkware *ctx)
142: {
143: zip_uint8_t header[HEADERLEN];
144: struct zip_stat st;
145: zip_int64_t n;
146: unsigned short dostime, dosdate;
147:
148: if ((n=zip_source_read(src, header, HEADERLEN)) < 0) {
149: zip_source_error(src, ctx->e, ctx->e+1);
150: return -1;
151: }
152:
153: if (n != HEADERLEN) {
154: ctx->e[0] = ZIP_ER_EOF;
155: ctx->e[1] = 0;
156: return -1;
157: }
158:
159: decrypt(ctx, header, header, HEADERLEN, 0);
160:
161: if (zip_source_stat(src, &st) < 0) {
162: /* stat failed, skip password validation */
163: return 0;
164: }
165:
166: _zip_u2d_time(st.mtime, &dostime, &dosdate);
167:
168: if (header[HEADERLEN-1] != st.crc>>24
169: && header[HEADERLEN-1] != dostime>>8) {
170: ctx->e[0] = ZIP_ER_WRONGPASSWD;
171: ctx->e[1] = 0;
172: return -1;
173: }
174:
175: return 0;
176: }
177:
178:
179:
180: static zip_int64_t
181: pkware_decrypt(struct zip_source *src, void *ud, void *data,
182: zip_uint64_t len, enum zip_source_cmd cmd)
183: {
184: struct trad_pkware *ctx;
185: zip_int64_t n;
186:
187: ctx = (struct trad_pkware *)ud;
188:
189: switch (cmd) {
190: case ZIP_SOURCE_OPEN:
191: if (decrypt_header(src, ctx) < 0)
192: return -1;
193: return 0;
194:
195: case ZIP_SOURCE_READ:
196: if ((n=zip_source_read(src, data, len)) < 0)
197: return ZIP_SOURCE_ERR_LOWER;
198:
199: decrypt(ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n,
200: 0);
201: return n;
202:
203: case ZIP_SOURCE_CLOSE:
204: return 0;
205:
206: case ZIP_SOURCE_STAT:
207: {
208: struct zip_stat *st;
209:
210: st = (struct zip_stat *)data;
211:
212: st->encryption_method = ZIP_EM_NONE;
213: st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
214: /* XXX: deduce HEADERLEN from size for uncompressed */
215: if (st->valid & ZIP_STAT_COMP_SIZE)
216: st->comp_size -= HEADERLEN;
217: }
218: return 0;
219:
220: case ZIP_SOURCE_ERROR:
221: memcpy(data, ctx->e, sizeof(int)*2);
222: return sizeof(int)*2;
223:
224: case ZIP_SOURCE_FREE:
225: pkware_free(ctx);
226: return 0;
227:
228: default:
229: ctx->e[0] = ZIP_ER_INVAL;
230: ctx->e[1] = 0;
231: return -1;
232: }
233: }
234:
235:
236:
237: static void
238: pkware_free(struct trad_pkware *ctx)
239: {
240: free(ctx);
241: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>