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 #include <stdlib.h>
36 #include <string.h>
37
38 #include "zipint.h"
39
40 struct trad_pkware {
41 zip_error_t error;
42 zip_uint32_t key[3];
43 };
44
45 #define HEADERLEN 12
46 #define KEY0 305419896
47 #define KEY1 591751049
48 #define KEY2 878082192
49
50
51 static void decrypt(struct trad_pkware *, zip_uint8_t *,
52 const zip_uint8_t *, zip_uint64_t, int);
53 static int decrypt_header(zip_source_t *, struct trad_pkware *);
54 static zip_int64_t pkware_decrypt(zip_source_t *, void *, void *,
55 zip_uint64_t, zip_source_cmd_t);
56 static void pkware_free(struct trad_pkware *);
57
58
59 zip_source_t *
60 zip_source_pkware(zip_t *za, zip_source_t *src,
61 zip_uint16_t em, int flags, const char *password)
62 {
63 struct trad_pkware *ctx;
64 zip_source_t *s2;
65
66 if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
67 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
68 return NULL;
69 }
70 if (flags & ZIP_CODEC_ENCODE) {
71 zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
72 return NULL;
73 }
74
75 if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
76 zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
77 return NULL;
78 }
79
80 zip_error_init(&ctx->error);
81
82 ctx->key[0] = KEY0;
83 ctx->key[1] = KEY1;
84 ctx->key[2] = KEY2;
85 decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
86
87 if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
88 pkware_free(ctx);
89 return NULL;
90 }
91
92 return s2;
93 }
94
95
96 static void
97 decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
98 zip_uint64_t len, int update_only)
99 {
100 zip_uint16_t tmp;
101 zip_uint64_t i;
102 Bytef b;
103
104 for (i=0; i<len; i++) {
105 b = in[i];
106
107 if (!update_only) {
108
109 tmp = (zip_uint16_t)(ctx->key[2] | 2);
110 tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8);
111 b ^= (Bytef)tmp;
112 }
113
114
115 if (out)
116 out[i] = b;
117
118
119 ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
120 ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
121 b = (Bytef)(ctx->key[1] >> 24);
122 ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
123 }
124 }
125
126
127 static int
128 decrypt_header(zip_source_t *src, struct trad_pkware *ctx)
129 {
130 zip_uint8_t header[HEADERLEN];
131 struct zip_stat st;
132 zip_int64_t n;
133 unsigned short dostime, dosdate;
134
135 if ((n=zip_source_read(src, header, HEADERLEN)) < 0) {
136 _zip_error_set_from_source(&ctx->error, src);
137 return -1;
138 }
139
140 if (n != HEADERLEN) {
141 zip_error_set(&ctx->error, ZIP_ER_EOF, 0);
142 return -1;
143 }
144
145 decrypt(ctx, header, header, HEADERLEN, 0);
146
147 if (zip_source_stat(src, &st) < 0) {
148
149 return 0;
150 }
151
152 _zip_u2d_time(st.mtime, &dostime, &dosdate);
153
154 if (header[HEADERLEN-1] != st.crc>>24 && header[HEADERLEN-1] != dostime>>8) {
155 zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0);
156 return -1;
157 }
158
159 return 0;
160 }
161
162
163 static zip_int64_t
164 pkware_decrypt(zip_source_t *src, void *ud, void *data,
165 zip_uint64_t len, zip_source_cmd_t cmd)
166 {
167 struct trad_pkware *ctx;
168 zip_int64_t n;
169
170 ctx = (struct trad_pkware *)ud;
171
172 switch (cmd) {
173 case ZIP_SOURCE_OPEN:
174 if (decrypt_header(src, ctx) < 0)
175 return -1;
176 return 0;
177
178 case ZIP_SOURCE_READ:
179 if ((n=zip_source_read(src, data, len)) < 0) {
180 _zip_error_set_from_source(&ctx->error, src);
181 return -1;
182 }
183
184 decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0);
185 return n;
186
187 case ZIP_SOURCE_CLOSE:
188 return 0;
189
190 case ZIP_SOURCE_STAT:
191 {
192 zip_stat_t *st;
193
194 st = (zip_stat_t *)data;
195
196 st->encryption_method = ZIP_EM_NONE;
197 st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
198
199 if (st->valid & ZIP_STAT_COMP_SIZE)
200 st->comp_size -= HEADERLEN;
201
202 return 0;
203 }
204
205 case ZIP_SOURCE_SUPPORTS:
206 return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
207
208 case ZIP_SOURCE_ERROR:
209 return zip_error_to_data(&ctx->error, data, len);
210
211 case ZIP_SOURCE_FREE:
212 pkware_free(ctx);
213 return 0;
214
215 default:
216 zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
217 return -1;
218 }
219 }
220
221
222 static void
223 pkware_free(struct trad_pkware *ctx)
224 {
225 free(ctx);
226 }