This source file includes following definitions.
- zip_source_pkware
- decrypt
- decrypt_header
- pkware_decrypt
- pkware_free
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
53
54 static void decrypt(struct trad_pkware *, zip_uint8_t *,
55 const zip_uint8_t *, zip_uint64_t, int);
56 static int decrypt_header(struct zip_source *, struct trad_pkware *);
57 static zip_int64_t pkware_decrypt(struct zip_source *, void *, void *,
58 zip_uint64_t, enum zip_source_cmd);
59 static void pkware_free(struct trad_pkware *);
60
61
62
63 struct zip_source *
64 zip_source_pkware(struct zip *za, struct zip_source *src,
65 zip_uint16_t em, int flags, const char *password)
66 {
67 struct trad_pkware *ctx;
68 struct zip_source *s2;
69
70 if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
71 _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
72 return NULL;
73 }
74 if (flags & ZIP_CODEC_ENCODE) {
75 _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
76 return NULL;
77 }
78
79 if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
80 _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
81 return NULL;
82 }
83
84 ctx->e[0] = ctx->e[1] = 0;
85
86 ctx->key[0] = KEY0;
87 ctx->key[1] = KEY1;
88 ctx->key[2] = KEY2;
89 decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
90
91 if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
92 pkware_free(ctx);
93 return NULL;
94 }
95
96 return s2;
97 }
98
99
100
101 static void
102 decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
103 zip_uint64_t len, int update_only)
104 {
105 zip_uint16_t tmp;
106 zip_uint64_t i;
107 Bytef b;
108
109 for (i=0; i<len; i++) {
110 b = in[i];
111
112 if (!update_only) {
113
114 tmp = (zip_uint16_t)(ctx->key[2] | 2);
115 tmp = (tmp * (tmp ^ 1)) >> 8;
116 b ^= tmp;
117 }
118
119
120 if (out)
121 out[i] = b;
122
123
124 ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
125 ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
126 b = ctx->key[1] >> 24;
127 ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
128 }
129 }
130
131
132
133 static int
134 decrypt_header(struct zip_source *src, struct trad_pkware *ctx)
135 {
136 zip_uint8_t header[HEADERLEN];
137 struct zip_stat st;
138 zip_int64_t n;
139 unsigned short dostime, dosdate;
140
141 if ((n=zip_source_read(src, header, HEADERLEN)) < 0) {
142 zip_source_error(src, ctx->e, ctx->e+1);
143 return -1;
144 }
145
146 if (n != HEADERLEN) {
147 ctx->e[0] = ZIP_ER_EOF;
148 ctx->e[1] = 0;
149 return -1;
150 }
151
152 decrypt(ctx, header, header, HEADERLEN, 0);
153
154 if (zip_source_stat(src, &st) < 0) {
155
156 return 0;
157 }
158
159 _zip_u2d_time(st.mtime, &dostime, &dosdate);
160
161 if (header[HEADERLEN-1] != st.crc>>24
162 && header[HEADERLEN-1] != dostime>>8) {
163 ctx->e[0] = ZIP_ER_WRONGPASSWD;
164 ctx->e[1] = 0;
165 return -1;
166 }
167
168 return 0;
169 }
170
171
172
173 static zip_int64_t
174 pkware_decrypt(struct zip_source *src, void *ud, void *data,
175 zip_uint64_t len, enum zip_source_cmd cmd)
176 {
177 struct trad_pkware *ctx;
178 zip_int64_t n;
179
180 ctx = (struct trad_pkware *)ud;
181
182 switch (cmd) {
183 case ZIP_SOURCE_OPEN:
184 if (decrypt_header(src, ctx) < 0)
185 return -1;
186 return 0;
187
188 case ZIP_SOURCE_READ:
189 if ((n=zip_source_read(src, data, len)) < 0)
190 return ZIP_SOURCE_ERR_LOWER;
191
192 decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n,
193 0);
194 return n;
195
196 case ZIP_SOURCE_CLOSE:
197 return 0;
198
199 case ZIP_SOURCE_STAT:
200 {
201 struct zip_stat *st;
202
203 st = (struct zip_stat *)data;
204
205 st->encryption_method = ZIP_EM_NONE;
206 st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
207
208 if (st->valid & ZIP_STAT_COMP_SIZE)
209 st->comp_size -= HEADERLEN;
210 }
211 return 0;
212
213 case ZIP_SOURCE_ERROR:
214 memcpy(data, ctx->e, sizeof(int)*2);
215 return sizeof(int)*2;
216
217 case ZIP_SOURCE_FREE:
218 pkware_free(ctx);
219 return 0;
220
221 default:
222 ctx->e[0] = ZIP_ER_INVAL;
223 ctx->e[1] = 0;
224 return -1;
225 }
226 }
227
228
229
230 static void
231 pkware_free(struct trad_pkware *ctx)
232 {
233 free(ctx);
234 }