... | ... |
@@ -39,8 +39,8 @@ |
39 | 39 |
int cli_crt_init(cli_crt *x509) { |
40 | 40 |
int ret; |
41 | 41 |
if((ret = mp_init_multi(&x509->n, &x509->e, &x509->sig, NULL))) { |
42 |
- cli_errmsg("cli_crt_init: mp_init_multi failed with %d\n", ret); |
|
43 |
- return 1; |
|
42 |
+ cli_errmsg("cli_crt_init: mp_init_multi failed with %d\n", ret); |
|
43 |
+ return 1; |
|
44 | 44 |
} |
45 | 45 |
x509->name = NULL; |
46 | 46 |
x509->isBlacklisted = 0; |
... | ... |
@@ -58,17 +58,17 @@ void cli_crt_clear(cli_crt *x509) { |
58 | 58 |
cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509) { |
59 | 59 |
cli_crt *i; |
60 | 60 |
for(i = m->crts; i; i = i->next) { |
61 |
- if(x509->not_before >= i->not_before && |
|
62 |
- x509->not_after <= i->not_after && |
|
63 |
- (i->certSign | x509->certSign) == i->certSign && |
|
64 |
- (i->codeSign | x509->codeSign) == i->codeSign && |
|
65 |
- (i->timeSign | x509->timeSign) == i->timeSign && |
|
66 |
- !memcmp(x509->subject, i->subject, sizeof(i->subject)) && |
|
67 |
- !memcmp(x509->serial, i->serial, sizeof(i->serial)) && |
|
68 |
- !mp_cmp(&x509->n, &i->n) && |
|
69 |
- !mp_cmp(&x509->e, &i->e) && !(i->isBlacklisted)) { |
|
70 |
- return i; |
|
71 |
- } |
|
61 |
+ if(x509->not_before >= i->not_before && |
|
62 |
+ x509->not_after <= i->not_after && |
|
63 |
+ (i->certSign | x509->certSign) == i->certSign && |
|
64 |
+ (i->codeSign | x509->codeSign) == i->codeSign && |
|
65 |
+ (i->timeSign | x509->timeSign) == i->timeSign && |
|
66 |
+ !memcmp(x509->subject, i->subject, sizeof(i->subject)) && |
|
67 |
+ !memcmp(x509->serial, i->serial, sizeof(i->serial)) && |
|
68 |
+ !mp_cmp(&x509->n, &i->n) && |
|
69 |
+ !mp_cmp(&x509->e, &i->e) && !(i->isBlacklisted)) { |
|
70 |
+ return i; |
|
71 |
+ } |
|
72 | 72 |
} |
73 | 73 |
return NULL; |
74 | 74 |
} |
... | ... |
@@ -78,66 +78,66 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) { |
78 | 78 |
int ret = 0; |
79 | 79 |
|
80 | 80 |
for(i = m->crts; i; i = i->next) { |
81 |
- if(!memcmp(x509->subject, i->subject, sizeof(i->subject)) && |
|
82 |
- !memcmp(x509->serial, i->subject, sizeof(i->serial)) && |
|
83 |
- !mp_cmp(&x509->n, &i->n) && |
|
84 |
- !mp_cmp(&x509->e, &i->e)) { |
|
85 |
- if(x509->not_before >= i->not_before && x509->not_after <= i->not_after) { |
|
86 |
- /* Already same or broader */ |
|
87 |
- ret = 1; |
|
88 |
- } |
|
89 |
- if(i->not_before > x509->not_before && i->not_before <= x509->not_after) { |
|
90 |
- /* Extend left */ |
|
91 |
- i->not_before = x509->not_before; |
|
92 |
- ret = 1; |
|
93 |
- } |
|
94 |
- if(i->not_after >= x509->not_before && i->not_after < x509->not_after) { |
|
95 |
- /* Extend right */ |
|
96 |
- i->not_after = x509->not_after; |
|
97 |
- ret = 1; |
|
98 |
- } |
|
99 |
- if(!ret) |
|
100 |
- continue; |
|
101 |
- i->certSign |= x509->certSign; |
|
102 |
- i->codeSign |= x509->codeSign; |
|
103 |
- i->timeSign |= x509->timeSign; |
|
104 |
- |
|
105 |
- return 0; |
|
106 |
- } |
|
107 |
- |
|
108 |
- /* If certs match, we're likely just revoking it */ |
|
109 |
- if (!memcmp(x509->subject, i->subject, sizeof(x509->subject)) && |
|
110 |
- !memcmp(x509->issuer, i->issuer, sizeof(x509->issuer)) && |
|
111 |
- !memcmp(x509->serial, i->serial, sizeof(x509->serial)) && |
|
112 |
- !mp_cmp(&x509->n, &i->n) && |
|
113 |
- !mp_cmp(&x509->e, &i->e)) { |
|
114 |
- if (i->isBlacklisted != x509->isBlacklisted) |
|
115 |
- i->isBlacklisted = x509->isBlacklisted; |
|
81 |
+ if(!memcmp(x509->subject, i->subject, sizeof(i->subject)) && |
|
82 |
+ !memcmp(x509->serial, i->subject, sizeof(i->serial)) && |
|
83 |
+ !mp_cmp(&x509->n, &i->n) && |
|
84 |
+ !mp_cmp(&x509->e, &i->e)) { |
|
85 |
+ if(x509->not_before >= i->not_before && x509->not_after <= i->not_after) { |
|
86 |
+ /* Already same or broader */ |
|
87 |
+ ret = 1; |
|
88 |
+ } |
|
89 |
+ if(i->not_before > x509->not_before && i->not_before <= x509->not_after) { |
|
90 |
+ /* Extend left */ |
|
91 |
+ i->not_before = x509->not_before; |
|
92 |
+ ret = 1; |
|
93 |
+ } |
|
94 |
+ if(i->not_after >= x509->not_before && i->not_after < x509->not_after) { |
|
95 |
+ /* Extend right */ |
|
96 |
+ i->not_after = x509->not_after; |
|
97 |
+ ret = 1; |
|
98 |
+ } |
|
99 |
+ if(!ret) |
|
100 |
+ continue; |
|
101 |
+ i->certSign |= x509->certSign; |
|
102 |
+ i->codeSign |= x509->codeSign; |
|
103 |
+ i->timeSign |= x509->timeSign; |
|
116 | 104 |
|
117 | 105 |
return 0; |
118 |
- } |
|
106 |
+ } |
|
107 |
+ |
|
108 |
+ /* If certs match, we're likely just revoking it */ |
|
109 |
+ if (!memcmp(x509->subject, i->subject, sizeof(x509->subject)) && |
|
110 |
+ !memcmp(x509->issuer, i->issuer, sizeof(x509->issuer)) && |
|
111 |
+ !memcmp(x509->serial, i->serial, sizeof(x509->serial)) && |
|
112 |
+ !mp_cmp(&x509->n, &i->n) && |
|
113 |
+ !mp_cmp(&x509->e, &i->e)) { |
|
114 |
+ if (i->isBlacklisted != x509->isBlacklisted) |
|
115 |
+ i->isBlacklisted = x509->isBlacklisted; |
|
116 |
+ |
|
117 |
+ return 0; |
|
118 |
+ } |
|
119 | 119 |
} |
120 | 120 |
|
121 | 121 |
i = cli_malloc(sizeof(*i)); |
122 | 122 |
if(!i) |
123 |
- return 1; |
|
123 |
+ return 1; |
|
124 | 124 |
|
125 | 125 |
if((ret = mp_init_multi(&i->n, &i->e, &i->sig, NULL))) { |
126 |
- cli_warnmsg("crtmgr_add: failed to mp_init failed with %d\n", ret); |
|
127 |
- free(i); |
|
128 |
- return 1; |
|
126 |
+ cli_warnmsg("crtmgr_add: failed to mp_init failed with %d\n", ret); |
|
127 |
+ free(i); |
|
128 |
+ return 1; |
|
129 | 129 |
} |
130 | 130 |
if((ret = mp_copy(&x509->n, &i->n)) || (ret = mp_copy(&x509->e, &i->e)) || (ret = mp_copy(&x509->sig, &i->sig))) { |
131 |
- cli_warnmsg("crtmgr_add: failed to mp_init failed with %d\n", ret); |
|
132 |
- cli_crt_clear(i); |
|
133 |
- free(i); |
|
134 |
- return 1; |
|
131 |
+ cli_warnmsg("crtmgr_add: failed to mp_init failed with %d\n", ret); |
|
132 |
+ cli_crt_clear(i); |
|
133 |
+ free(i); |
|
134 |
+ return 1; |
|
135 | 135 |
} |
136 | 136 |
|
137 | 137 |
if ((x509->name)) |
138 |
- i->name = strdup(x509->name); |
|
138 |
+ i->name = strdup(x509->name); |
|
139 | 139 |
else |
140 |
- i->name = NULL; |
|
140 |
+ i->name = NULL; |
|
141 | 141 |
|
142 | 142 |
memcpy(i->raw_subject, x509->raw_subject, sizeof(i->raw_subject)); |
143 | 143 |
memcpy(i->raw_issuer, x509->raw_issuer, sizeof(i->raw_issuer)); |
... | ... |
@@ -156,7 +156,7 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) { |
156 | 156 |
i->next = m->crts; |
157 | 157 |
i->prev = NULL; |
158 | 158 |
if(m->crts) |
159 |
- m->crts->prev = i; |
|
159 |
+ m->crts->prev = i; |
|
160 | 160 |
m->crts = i; |
161 | 161 |
|
162 | 162 |
m->items++; |
... | ... |
@@ -171,26 +171,26 @@ void crtmgr_init(crtmgr *m) { |
171 | 171 |
void crtmgr_del(crtmgr *m, cli_crt *x509) { |
172 | 172 |
cli_crt *i; |
173 | 173 |
for(i = m->crts; i; i = i->next) { |
174 |
- if(i==x509) { |
|
175 |
- if(i->prev) |
|
176 |
- i->prev->next = i->next; |
|
177 |
- else |
|
178 |
- m->crts = i->next; |
|
179 |
- if(i->next) |
|
180 |
- i->next->prev = i->prev; |
|
181 |
- cli_crt_clear(x509); |
|
182 |
- if ((x509->name)) |
|
183 |
- free(x509->name); |
|
184 |
- free(x509); |
|
185 |
- m->items--; |
|
186 |
- return; |
|
187 |
- } |
|
174 |
+ if(i==x509) { |
|
175 |
+ if(i->prev) |
|
176 |
+ i->prev->next = i->next; |
|
177 |
+ else |
|
178 |
+ m->crts = i->next; |
|
179 |
+ if(i->next) |
|
180 |
+ i->next->prev = i->prev; |
|
181 |
+ cli_crt_clear(x509); |
|
182 |
+ if ((x509->name)) |
|
183 |
+ free(x509->name); |
|
184 |
+ free(x509); |
|
185 |
+ m->items--; |
|
186 |
+ return; |
|
187 |
+ } |
|
188 | 188 |
} |
189 | 189 |
} |
190 | 190 |
|
191 | 191 |
void crtmgr_free(crtmgr *m) { |
192 | 192 |
while(m->items) |
193 |
- crtmgr_del(m, m->crts); |
|
193 |
+ crtmgr_del(m, m->crts); |
|
194 | 194 |
} |
195 | 195 |
|
196 | 196 |
static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashtype, const uint8_t *refhash) { |
... | ... |
@@ -211,94 +211,94 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty |
211 | 211 |
} |
212 | 212 |
|
213 | 213 |
if((ret = mp_init(&x))) { |
214 |
- cli_errmsg("crtmgr_rsa_verify: mp_init failed with %d\n", ret); |
|
215 |
- return 1; |
|
214 |
+ cli_errmsg("crtmgr_rsa_verify: mp_init failed with %d\n", ret); |
|
215 |
+ return 1; |
|
216 | 216 |
} |
217 | 217 |
|
218 | 218 |
do { |
219 |
- if(MAX(keylen, siglen) - MIN(keylen, siglen) > 1) |
|
220 |
- break; |
|
221 |
- if((ret = mp_exptmod(sig, &x509->e, &x509->n, &x))) { |
|
222 |
- cli_warnmsg("crtmgr_rsa_verify: verification failed: mp_exptmod failed with %d\n", ret); |
|
223 |
- break; |
|
224 |
- } |
|
225 |
- if(mp_unsigned_bin_size(&x) != keylen - 1) |
|
226 |
- break; |
|
227 |
- if((ret = mp_to_unsigned_bin(&x, d))) { |
|
228 |
- cli_warnmsg("crtmgr_rsa_verify: mp_unsigned_bin_size failed with %d\n", ret); |
|
229 |
- break; |
|
230 |
- } |
|
231 |
- if(*d != 1) /* block type 1 */ |
|
232 |
- break; |
|
233 |
- |
|
234 |
- keylen -= 1; /* 0xff padding */ |
|
235 |
- for(j=1; j<keylen-2; j++) |
|
236 |
- if(d[j] != 0xff) |
|
237 |
- break; |
|
238 |
- if(j == keylen - 2) |
|
239 |
- break; |
|
240 |
- if(d[j] != 0) /* 0x00 separator */ |
|
241 |
- break; |
|
242 |
- |
|
243 |
- j++; |
|
244 |
- keylen -= j; /* asn1 size */ |
|
245 |
- |
|
246 |
- if(keylen < hashlen) |
|
247 |
- break; |
|
248 |
- if(keylen > hashlen) { |
|
249 |
- /* hash is asn1 der encoded */ |
|
250 |
- /* SEQ { SEQ { OID, NULL }, OCTET STRING */ |
|
251 |
- if(keylen < 2 || d[j] != 0x30 || d[j+1] + 2 != keylen) |
|
252 |
- break; |
|
253 |
- keylen -= 2; |
|
254 |
- j+=2; |
|
255 |
- |
|
256 |
- if(keylen <2 || d[j] != 0x30) |
|
257 |
- break; |
|
258 |
- |
|
259 |
- objlen = d[j+1]; |
|
260 |
- |
|
261 |
- keylen -= 2; |
|
262 |
- j+=2; |
|
263 |
- if(keylen < objlen) |
|
264 |
- break; |
|
265 |
- if(objlen == 9) { |
|
219 |
+ if(MAX(keylen, siglen) - MIN(keylen, siglen) > 1) |
|
220 |
+ break; |
|
221 |
+ if((ret = mp_exptmod(sig, &x509->e, &x509->n, &x))) { |
|
222 |
+ cli_warnmsg("crtmgr_rsa_verify: verification failed: mp_exptmod failed with %d\n", ret); |
|
223 |
+ break; |
|
224 |
+ } |
|
225 |
+ if(mp_unsigned_bin_size(&x) != keylen - 1) |
|
226 |
+ break; |
|
227 |
+ if((ret = mp_to_unsigned_bin(&x, d))) { |
|
228 |
+ cli_warnmsg("crtmgr_rsa_verify: mp_unsigned_bin_size failed with %d\n", ret); |
|
229 |
+ break; |
|
230 |
+ } |
|
231 |
+ if(*d != 1) /* block type 1 */ |
|
232 |
+ break; |
|
233 |
+ |
|
234 |
+ keylen -= 1; /* 0xff padding */ |
|
235 |
+ for(j=1; j<keylen-2; j++) |
|
236 |
+ if(d[j] != 0xff) |
|
237 |
+ break; |
|
238 |
+ if(j == keylen - 2) |
|
239 |
+ break; |
|
240 |
+ if(d[j] != 0) /* 0x00 separator */ |
|
241 |
+ break; |
|
242 |
+ |
|
243 |
+ j++; |
|
244 |
+ keylen -= j; /* asn1 size */ |
|
245 |
+ |
|
246 |
+ if(keylen < hashlen) |
|
247 |
+ break; |
|
248 |
+ if(keylen > hashlen) { |
|
249 |
+ /* hash is asn1 der encoded */ |
|
250 |
+ /* SEQ { SEQ { OID, NULL }, OCTET STRING */ |
|
251 |
+ if(keylen < 2 || d[j] != 0x30 || d[j+1] + 2 != keylen) |
|
252 |
+ break; |
|
253 |
+ keylen -= 2; |
|
254 |
+ j+=2; |
|
255 |
+ |
|
256 |
+ if(keylen <2 || d[j] != 0x30) |
|
257 |
+ break; |
|
258 |
+ |
|
259 |
+ objlen = d[j+1]; |
|
260 |
+ |
|
261 |
+ keylen -= 2; |
|
262 |
+ j+=2; |
|
263 |
+ if(keylen < objlen) |
|
264 |
+ break; |
|
265 |
+ if(objlen == 9) { |
|
266 | 266 |
// Check for OID type indicating a length of 5, OID_sha1, and the NULL type/value |
267 |
- if(hashtype != CLI_SHA1RSA || memcmp(&d[j], "\x06\x05" OID_sha1 "\x05\x00", 9)) { |
|
268 |
- cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n"); |
|
269 |
- break; |
|
270 |
- } |
|
271 |
- } else if(objlen == 12) { |
|
267 |
+ if(hashtype != CLI_SHA1RSA || memcmp(&d[j], "\x06\x05" OID_sha1 "\x05\x00", 9)) { |
|
268 |
+ cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n"); |
|
269 |
+ break; |
|
270 |
+ } |
|
271 |
+ } else if(objlen == 12) { |
|
272 | 272 |
// Check for OID type indicating a length of 8, OID_md5, and the NULL type/value |
273 |
- if(hashtype != CLI_MD5RSA || memcmp(&d[j], "\x06\x08" OID_md5 "\x05\x00", 12)) { |
|
274 |
- cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n"); |
|
275 |
- break; |
|
276 |
- } |
|
277 |
- } else if(objlen == 13) { |
|
273 |
+ if(hashtype != CLI_MD5RSA || memcmp(&d[j], "\x06\x08" OID_md5 "\x05\x00", 12)) { |
|
274 |
+ cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n"); |
|
275 |
+ break; |
|
276 |
+ } |
|
277 |
+ } else if(objlen == 13) { |
|
278 | 278 |
// Check for OID type indicating a length of 9, OID_sha256, and the NULL type/value |
279 |
- if(hashtype != CLI_SHA256RSA || memcmp(&d[j], "\x06\x09" OID_sha256 "\x05\x00", 13)) { |
|
280 |
- cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n"); |
|
281 |
- break; |
|
282 |
- } |
|
283 |
- } else { |
|
284 |
- cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n"); |
|
285 |
- break; |
|
286 |
- } |
|
287 |
- |
|
288 |
- keylen -= objlen; |
|
289 |
- j += objlen; |
|
290 |
- if(keylen < 2 || d[j] != 0x04 || d[j+1] != hashlen) |
|
291 |
- break; |
|
292 |
- keylen -= 2; |
|
293 |
- j+=2; |
|
294 |
- if(keylen != hashlen) |
|
295 |
- break; |
|
296 |
- } |
|
297 |
- if(memcmp(&d[j], refhash, hashlen)) |
|
298 |
- break; |
|
299 |
- |
|
300 |
- mp_clear(&x); |
|
301 |
- return 0; |
|
279 |
+ if(hashtype != CLI_SHA256RSA || memcmp(&d[j], "\x06\x09" OID_sha256 "\x05\x00", 13)) { |
|
280 |
+ cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n"); |
|
281 |
+ break; |
|
282 |
+ } |
|
283 |
+ } else { |
|
284 |
+ cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n"); |
|
285 |
+ break; |
|
286 |
+ } |
|
287 |
+ |
|
288 |
+ keylen -= objlen; |
|
289 |
+ j += objlen; |
|
290 |
+ if(keylen < 2 || d[j] != 0x04 || d[j+1] != hashlen) |
|
291 |
+ break; |
|
292 |
+ keylen -= 2; |
|
293 |
+ j+=2; |
|
294 |
+ if(keylen != hashlen) |
|
295 |
+ break; |
|
296 |
+ } |
|
297 |
+ if(memcmp(&d[j], refhash, hashlen)) |
|
298 |
+ break; |
|
299 |
+ |
|
300 |
+ mp_clear(&x); |
|
301 |
+ return 0; |
|
302 | 302 |
|
303 | 303 |
} while(0); |
304 | 304 |
|
... | ... |
@@ -320,18 +320,18 @@ cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509) { |
320 | 320 |
} |
321 | 321 |
|
322 | 322 |
for(i = m->crts; i; i = i->next) { |
323 |
- if(i->certSign && |
|
324 |
- !memcmp(i->subject, x509->issuer, sizeof(i->subject)) && |
|
325 |
- !crtmgr_rsa_verify(i, &x509->sig, x509->hashtype, x509->tbshash)) { |
|
326 |
- int curscore; |
|
327 |
- if((x509->codeSign & i->codeSign) == x509->codeSign && (x509->timeSign & i->timeSign) == x509->timeSign) |
|
328 |
- return i; |
|
329 |
- curscore = (x509->codeSign & i->codeSign) + (x509->timeSign & i->timeSign); |
|
330 |
- if(curscore > score) { |
|
331 |
- best = i; |
|
332 |
- score = curscore; |
|
333 |
- } |
|
334 |
- } |
|
323 |
+ if(i->certSign && |
|
324 |
+ !memcmp(i->subject, x509->issuer, sizeof(i->subject)) && |
|
325 |
+ !crtmgr_rsa_verify(i, &x509->sig, x509->hashtype, x509->tbshash)) { |
|
326 |
+ int curscore; |
|
327 |
+ if((x509->codeSign & i->codeSign) == x509->codeSign && (x509->timeSign & i->timeSign) == x509->timeSign) |
|
328 |
+ return i; |
|
329 |
+ curscore = (x509->codeSign & i->codeSign) + (x509->timeSign & i->timeSign); |
|
330 |
+ if(curscore > score) { |
|
331 |
+ best = i; |
|
332 |
+ score = curscore; |
|
333 |
+ } |
|
334 |
+ } |
|
335 | 335 |
} |
336 | 336 |
return best; |
337 | 337 |
} |
... | ... |
@@ -342,28 +342,28 @@ cli_crt *crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *se |
342 | 342 |
int ret; |
343 | 343 |
|
344 | 344 |
if(signature_len < 1024/8 || signature_len > 4096/8+1) { |
345 |
- cli_dbgmsg("crtmgr_verify_pkcs7: unsupported sig len: %u\n", signature_len); |
|
346 |
- return NULL; |
|
345 |
+ cli_dbgmsg("crtmgr_verify_pkcs7: unsupported sig len: %u\n", signature_len); |
|
346 |
+ return NULL; |
|
347 | 347 |
} |
348 | 348 |
if((ret = mp_init(&sig))) { |
349 |
- cli_errmsg("crtmgr_verify_pkcs7: mp_init failed with %d\n", ret); |
|
350 |
- return NULL; |
|
349 |
+ cli_errmsg("crtmgr_verify_pkcs7: mp_init failed with %d\n", ret); |
|
350 |
+ return NULL; |
|
351 | 351 |
} |
352 | 352 |
|
353 | 353 |
if((ret=mp_read_unsigned_bin(&sig, signature, signature_len))) { |
354 |
- cli_warnmsg("crtmgr_verify_pkcs7: mp_read_unsigned_bin failed with %d\n", ret); |
|
355 |
- return NULL; |
|
354 |
+ cli_warnmsg("crtmgr_verify_pkcs7: mp_read_unsigned_bin failed with %d\n", ret); |
|
355 |
+ return NULL; |
|
356 | 356 |
} |
357 | 357 |
|
358 | 358 |
for(i = m->crts; i; i = i->next) { |
359 |
- if(vrfytype == VRFY_CODE && !i->codeSign) |
|
360 |
- continue; |
|
361 |
- if(vrfytype == VRFY_TIME && !i->timeSign) |
|
362 |
- continue; |
|
363 |
- if(!memcmp(i->issuer, issuer, sizeof(i->issuer)) && |
|
364 |
- !memcmp(i->serial, serial, sizeof(i->serial)) && |
|
365 |
- !crtmgr_rsa_verify(i, &sig, hashtype, refhash)) { |
|
366 |
- break; |
|
359 |
+ if(vrfytype == VRFY_CODE && !i->codeSign) |
|
360 |
+ continue; |
|
361 |
+ if(vrfytype == VRFY_TIME && !i->timeSign) |
|
362 |
+ continue; |
|
363 |
+ if(!memcmp(i->issuer, issuer, sizeof(i->issuer)) && |
|
364 |
+ !memcmp(i->serial, serial, sizeof(i->serial)) && |
|
365 |
+ !crtmgr_rsa_verify(i, &sig, hashtype, refhash)) { |
|
366 |
+ break; |
|
367 | 367 |
} |
368 | 368 |
} |
369 | 369 |
mp_clear(&sig); |
... | ... |
@@ -90,11 +90,11 @@ |
90 | 90 |
|
91 | 91 |
#define DCONF ctx->dconf->pe |
92 | 92 |
|
93 |
-#define PE_IMAGE_DOS_SIGNATURE 0x5a4d /* MZ */ |
|
93 |
+#define PE_IMAGE_DOS_SIGNATURE 0x5a4d /* MZ */ |
|
94 | 94 |
#define PE_IMAGE_DOS_SIGNATURE_OLD 0x4d5a /* ZM */ |
95 |
-#define PE_IMAGE_NT_SIGNATURE 0x00004550 |
|
96 |
-#define PE32_SIGNATURE 0x010b |
|
97 |
-#define PE32P_SIGNATURE 0x020b |
|
95 |
+#define PE_IMAGE_NT_SIGNATURE 0x00004550 |
|
96 |
+#define PE32_SIGNATURE 0x010b |
|
97 |
+#define PE32P_SIGNATURE 0x020b |
|
98 | 98 |
|
99 | 99 |
#define optional_hdr64 pe_opt.opt64 |
100 | 100 |
#define optional_hdr32 pe_opt.opt32 |
... | ... |
@@ -118,9 +118,9 @@ |
118 | 118 |
#define PESALIGN(o,a) (((a))?(((o)/(a)+((o)%(a)!=0))*(a)):(o)) |
119 | 119 |
|
120 | 120 |
#define CLI_UNPSIZELIMITS(NAME,CHK) \ |
121 |
-if(cli_checklimits(NAME, ctx, (CHK), 0, 0)!=CL_CLEAN) { \ |
|
122 |
- free(exe_sections); \ |
|
123 |
- return CL_CLEAN; \ |
|
121 |
+if(cli_checklimits(NAME, ctx, (CHK), 0, 0)!=CL_CLEAN) { \ |
|
122 |
+ free(exe_sections); \ |
|
123 |
+ return CL_CLEAN; \ |
|
124 | 124 |
} |
125 | 125 |
|
126 | 126 |
#define CLI_UNPTEMP(NAME,FREEME) \ |
... | ... |
@@ -349,62 +349,62 @@ void findres(uint32_t by_type, uint32_t by_name, uint32_t res_rva, fmap_t *map, |
349 | 349 |
uint16_t type_cnt, name_cnt, lang_cnt; |
350 | 350 |
|
351 | 351 |
if (!(resdir = fmap_need_off_once(map, cli_rawaddr(res_rva, exe_sections, nsections, &err, map->len, hdr_size), 16)) || err) |
352 |
- return; |
|
352 |
+ return; |
|
353 | 353 |
|
354 | 354 |
type_cnt = (uint16_t)cli_readint16(resdir+12); |
355 | 355 |
type_entry = resdir+16; |
356 | 356 |
if(!(by_type>>31)) { |
357 |
- type_entry += type_cnt * 8; |
|
358 |
- type_cnt = (uint16_t)cli_readint16(resdir+14); |
|
357 |
+ type_entry += type_cnt * 8; |
|
358 |
+ type_cnt = (uint16_t)cli_readint16(resdir+14); |
|
359 | 359 |
} |
360 | 360 |
|
361 | 361 |
while(type_cnt--) { |
362 |
- if(!fmap_need_ptr_once(map, type_entry, 8)) |
|
363 |
- return; |
|
364 |
- type = cli_readint32(type_entry); |
|
365 |
- type_offs = cli_readint32(type_entry+4); |
|
366 |
- if(type == by_type && (type_offs>>31)) { |
|
367 |
- type_offs &= 0x7fffffff; |
|
368 |
- if (!(resdir = fmap_need_off_once(map, cli_rawaddr(res_rva + type_offs, exe_sections, nsections, &err, map->len, hdr_size), 16)) || err) |
|
369 |
- return; |
|
370 |
- |
|
371 |
- name_cnt = (uint16_t)cli_readint16(resdir+12); |
|
372 |
- name_entry = resdir+16; |
|
373 |
- if(by_name == 0xffffffff) |
|
374 |
- name_cnt += (uint16_t)cli_readint16(resdir+14); |
|
375 |
- else if(!(by_name>>31)) { |
|
376 |
- name_entry += name_cnt * 8; |
|
377 |
- name_cnt = (uint16_t)cli_readint16(resdir+14); |
|
378 |
- } |
|
379 |
- while(name_cnt--) { |
|
380 |
- if(!fmap_need_ptr_once(map, name_entry, 8)) |
|
381 |
- return; |
|
382 |
- name = cli_readint32(name_entry); |
|
383 |
- name_offs = cli_readint32(name_entry+4); |
|
384 |
- if((by_name == 0xffffffff || name == by_name) && (name_offs>>31)) { |
|
385 |
- name_offs &= 0x7fffffff; |
|
386 |
- if (!(resdir = fmap_need_off_once(map, cli_rawaddr(res_rva + name_offs, exe_sections, nsections, &err, map->len, hdr_size), 16)) || err) |
|
387 |
- return; |
|
388 |
- |
|
389 |
- lang_cnt = (uint16_t)cli_readint16(resdir+12) + (uint16_t)cli_readint16(resdir+14); |
|
390 |
- lang_entry = resdir+16; |
|
391 |
- while(lang_cnt--) { |
|
392 |
- if(!fmap_need_ptr_once(map, lang_entry, 8)) |
|
393 |
- return; |
|
394 |
- lang = cli_readint32(lang_entry); |
|
395 |
- lang_offs = cli_readint32(lang_entry+4); |
|
396 |
- if(!(lang_offs >>31)) { |
|
397 |
- if(cb(opaque, type, name, lang, res_rva + lang_offs)) |
|
398 |
- return; |
|
399 |
- } |
|
400 |
- lang_entry += 8; |
|
401 |
- } |
|
402 |
- } |
|
403 |
- name_entry += 8; |
|
404 |
- } |
|
405 |
- return; /* FIXME: unless we want to find ALL types */ |
|
406 |
- } |
|
407 |
- type_entry += 8; |
|
362 |
+ if(!fmap_need_ptr_once(map, type_entry, 8)) |
|
363 |
+ return; |
|
364 |
+ type = cli_readint32(type_entry); |
|
365 |
+ type_offs = cli_readint32(type_entry+4); |
|
366 |
+ if(type == by_type && (type_offs>>31)) { |
|
367 |
+ type_offs &= 0x7fffffff; |
|
368 |
+ if (!(resdir = fmap_need_off_once(map, cli_rawaddr(res_rva + type_offs, exe_sections, nsections, &err, map->len, hdr_size), 16)) || err) |
|
369 |
+ return; |
|
370 |
+ |
|
371 |
+ name_cnt = (uint16_t)cli_readint16(resdir+12); |
|
372 |
+ name_entry = resdir+16; |
|
373 |
+ if(by_name == 0xffffffff) |
|
374 |
+ name_cnt += (uint16_t)cli_readint16(resdir+14); |
|
375 |
+ else if(!(by_name>>31)) { |
|
376 |
+ name_entry += name_cnt * 8; |
|
377 |
+ name_cnt = (uint16_t)cli_readint16(resdir+14); |
|
378 |
+ } |
|
379 |
+ while(name_cnt--) { |
|
380 |
+ if(!fmap_need_ptr_once(map, name_entry, 8)) |
|
381 |
+ return; |
|
382 |
+ name = cli_readint32(name_entry); |
|
383 |
+ name_offs = cli_readint32(name_entry+4); |
|
384 |
+ if((by_name == 0xffffffff || name == by_name) && (name_offs>>31)) { |
|
385 |
+ name_offs &= 0x7fffffff; |
|
386 |
+ if (!(resdir = fmap_need_off_once(map, cli_rawaddr(res_rva + name_offs, exe_sections, nsections, &err, map->len, hdr_size), 16)) || err) |
|
387 |
+ return; |
|
388 |
+ |
|
389 |
+ lang_cnt = (uint16_t)cli_readint16(resdir+12) + (uint16_t)cli_readint16(resdir+14); |
|
390 |
+ lang_entry = resdir+16; |
|
391 |
+ while(lang_cnt--) { |
|
392 |
+ if(!fmap_need_ptr_once(map, lang_entry, 8)) |
|
393 |
+ return; |
|
394 |
+ lang = cli_readint32(lang_entry); |
|
395 |
+ lang_offs = cli_readint32(lang_entry+4); |
|
396 |
+ if(!(lang_offs >>31)) { |
|
397 |
+ if(cb(opaque, type, name, lang, res_rva + lang_offs)) |
|
398 |
+ return; |
|
399 |
+ } |
|
400 |
+ lang_entry += 8; |
|
401 |
+ } |
|
402 |
+ } |
|
403 |
+ name_entry += 8; |
|
404 |
+ } |
|
405 |
+ return; /* FIXME: unless we want to find ALL types */ |
|
406 |
+ } |
|
407 |
+ type_entry += 8; |
|
408 | 408 |
} |
409 | 409 |
} |
410 | 410 |
|
... | ... |
@@ -419,82 +419,82 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, fmap_t *map, struc |
419 | 419 |
if(level>2 || !*maxres) return; |
420 | 420 |
*maxres-=1; |
421 | 421 |
if(err || !(resdir = fmap_need_off_once(map, rawaddr, 16))) |
422 |
- return; |
|
422 |
+ return; |
|
423 | 423 |
named = (uint16_t)cli_readint16(resdir+12); |
424 | 424 |
unnamed = (uint16_t)cli_readint16(resdir+14); |
425 | 425 |
|
426 | 426 |
entries = /*named+*/unnamed; |
427 | 427 |
if (!entries) |
428 |
- return; |
|
428 |
+ return; |
|
429 | 429 |
rawaddr += named*8; /* skip named */ |
430 | 430 |
/* this is just used in a heuristic detection, so don't give error on failure */ |
431 | 431 |
if(!(entry = fmap_need_off(map, rawaddr+16, entries*8))) { |
432 |
- cli_dbgmsg("cli_parseres_special: failed to read resource directory at:%lu\n", (unsigned long)rawaddr+16); |
|
433 |
- return; |
|
432 |
+ cli_dbgmsg("cli_parseres_special: failed to read resource directory at:%lu\n", (unsigned long)rawaddr+16); |
|
433 |
+ return; |
|
434 | 434 |
} |
435 | 435 |
oentry = entry; |
436 | 436 |
/*for (i=0; i<named; i++) { |
437 |
- uint32_t id, offs; |
|
438 |
- id = cli_readint32(entry); |
|
439 |
- offs = cli_readint32(entry+4); |
|
440 |
- if(offs>>31) |
|
441 |
- cli_parseres( base, base + (offs&0x7fffffff), srcfd, exe_sections, nsections, fsize, hdr_size, level+1, type, maxres, stats); |
|
442 |
- entry+=8; |
|
437 |
+ uint32_t id, offs; |
|
438 |
+ id = cli_readint32(entry); |
|
439 |
+ offs = cli_readint32(entry+4); |
|
440 |
+ if(offs>>31) |
|
441 |
+ cli_parseres( base, base + (offs&0x7fffffff), srcfd, exe_sections, nsections, fsize, hdr_size, level+1, type, maxres, stats); |
|
442 |
+ entry+=8; |
|
443 | 443 |
}*/ |
444 | 444 |
for (i=0; i<unnamed; i++, entry += 8) { |
445 |
- uint32_t id, offs; |
|
446 |
- if (stats->errors >= SWIZZ_MAXERRORS) { |
|
447 |
- cli_dbgmsg("cli_parseres_special: resources broken, ignoring\n"); |
|
448 |
- return; |
|
449 |
- } |
|
450 |
- id = cli_readint32(entry)&0x7fffffff; |
|
451 |
- if(level==0) { |
|
452 |
- type = 0; |
|
453 |
- switch(id) { |
|
454 |
- case 4: /* menu */ |
|
455 |
- case 5: /* dialog */ |
|
456 |
- case 6: /* string */ |
|
457 |
- case 11:/* msgtable */ |
|
458 |
- type = id; |
|
459 |
- break; |
|
460 |
- case 16: |
|
461 |
- type = id; |
|
462 |
- /* 14: version */ |
|
463 |
- stats->has_version = 1; |
|
464 |
- break; |
|
465 |
- case 24: /* manifest */ |
|
466 |
- stats->has_manifest = 1; |
|
467 |
- break; |
|
468 |
- /* otherwise keep it 0, we don't want it */ |
|
469 |
- } |
|
470 |
- } |
|
471 |
- if (!type) { |
|
472 |
- /* if we are not interested in this type, skip */ |
|
473 |
- continue; |
|
474 |
- } |
|
475 |
- offs = cli_readint32(entry+4); |
|
476 |
- if(offs>>31) |
|
477 |
- cli_parseres_special(base, base + (offs&0x7fffffff), map, exe_sections, nsections, fsize, hdr_size, level+1, type, maxres, stats); |
|
478 |
- else { |
|
479 |
- offs = cli_readint32(entry+4); |
|
480 |
- rawaddr = cli_rawaddr(base + offs, exe_sections, nsections, &err, fsize, hdr_size); |
|
481 |
- if (!err && (resdir = fmap_need_off_once(map, rawaddr, 16))) { |
|
482 |
- uint32_t isz = cli_readint32(resdir+4); |
|
483 |
- const uint8_t *str; |
|
484 |
- rawaddr = cli_rawaddr(cli_readint32(resdir), exe_sections, nsections, &err, fsize, hdr_size); |
|
485 |
- if (err || !isz || isz >= fsize || rawaddr+isz >= fsize) { |
|
486 |
- cli_dbgmsg("cli_parseres_special: invalid resource table entry: %lu + %lu\n", |
|
487 |
- (unsigned long)rawaddr, |
|
488 |
- (unsigned long)isz); |
|
489 |
- stats->errors++; |
|
490 |
- continue; |
|
491 |
- } |
|
492 |
- if ((id&0xff) != 0x09) /* english res only */ |
|
493 |
- continue; |
|
494 |
- if((str = fmap_need_off_once(map, rawaddr, isz))) |
|
495 |
- cli_detect_swizz_str(str, isz, stats, type); |
|
496 |
- } |
|
497 |
- } |
|
445 |
+ uint32_t id, offs; |
|
446 |
+ if (stats->errors >= SWIZZ_MAXERRORS) { |
|
447 |
+ cli_dbgmsg("cli_parseres_special: resources broken, ignoring\n"); |
|
448 |
+ return; |
|
449 |
+ } |
|
450 |
+ id = cli_readint32(entry)&0x7fffffff; |
|
451 |
+ if(level==0) { |
|
452 |
+ type = 0; |
|
453 |
+ switch(id) { |
|
454 |
+ case 4: /* menu */ |
|
455 |
+ case 5: /* dialog */ |
|
456 |
+ case 6: /* string */ |
|
457 |
+ case 11:/* msgtable */ |
|
458 |
+ type = id; |
|
459 |
+ break; |
|
460 |
+ case 16: |
|
461 |
+ type = id; |
|
462 |
+ /* 14: version */ |
|
463 |
+ stats->has_version = 1; |
|
464 |
+ break; |
|
465 |
+ case 24: /* manifest */ |
|
466 |
+ stats->has_manifest = 1; |
|
467 |
+ break; |
|
468 |
+ /* otherwise keep it 0, we don't want it */ |
|
469 |
+ } |
|
470 |
+ } |
|
471 |
+ if (!type) { |
|
472 |
+ /* if we are not interested in this type, skip */ |
|
473 |
+ continue; |
|
474 |
+ } |
|
475 |
+ offs = cli_readint32(entry+4); |
|
476 |
+ if(offs>>31) |
|
477 |
+ cli_parseres_special(base, base + (offs&0x7fffffff), map, exe_sections, nsections, fsize, hdr_size, level+1, type, maxres, stats); |
|
478 |
+ else { |
|
479 |
+ offs = cli_readint32(entry+4); |
|
480 |
+ rawaddr = cli_rawaddr(base + offs, exe_sections, nsections, &err, fsize, hdr_size); |
|
481 |
+ if (!err && (resdir = fmap_need_off_once(map, rawaddr, 16))) { |
|
482 |
+ uint32_t isz = cli_readint32(resdir+4); |
|
483 |
+ const uint8_t *str; |
|
484 |
+ rawaddr = cli_rawaddr(cli_readint32(resdir), exe_sections, nsections, &err, fsize, hdr_size); |
|
485 |
+ if (err || !isz || isz >= fsize || rawaddr+isz >= fsize) { |
|
486 |
+ cli_dbgmsg("cli_parseres_special: invalid resource table entry: %lu + %lu\n", |
|
487 |
+ (unsigned long)rawaddr, |
|
488 |
+ (unsigned long)isz); |
|
489 |
+ stats->errors++; |
|
490 |
+ continue; |
|
491 |
+ } |
|
492 |
+ if ((id&0xff) != 0x09) /* english res only */ |
|
493 |
+ continue; |
|
494 |
+ if((str = fmap_need_off_once(map, rawaddr, isz))) |
|
495 |
+ cli_detect_swizz_str(str, isz, stats, type); |
|
496 |
+ } |
|
497 |
+ } |
|
498 | 498 |
} |
499 | 499 |
fmap_unneed_ptr(map, oentry, entries*8); |
500 | 500 |
} |
... | ... |
@@ -3447,13 +3447,13 @@ int cli_scanpe(cli_ctx *ctx) |
3447 | 3447 |
|
3448 | 3448 |
/* CLI_UNPTEMP("DISASM",(exe_sections,0)); */ |
3449 | 3449 |
/* if(disasmbuf((unsigned char*)epbuff, epsize, ndesc)) */ |
3450 |
- /* ret = cli_scandesc(ndesc, ctx, CL_TYPE_PE_DISASM, 1, NULL, AC_SCAN_VIR); */ |
|
3450 |
+ /* ret = cli_scandesc(ndesc, ctx, CL_TYPE_PE_DISASM, 1, NULL, AC_SCAN_VIR); */ |
|
3451 | 3451 |
/* close(ndesc); */ |
3452 | 3452 |
/* CLI_TMPUNLK(); */ |
3453 | 3453 |
/* free(tempfile); */ |
3454 | 3454 |
/* if(ret == CL_VIRUS) { */ |
3455 |
- /* free(exe_sections); */ |
|
3456 |
- /* return ret; */ |
|
3455 |
+ /* free(exe_sections); */ |
|
3456 |
+ /* return ret; */ |
|
3457 | 3457 |
/* } */ |
3458 | 3458 |
|
3459 | 3459 |
if(overlays) { |
... | ... |
@@ -4601,20 +4601,20 @@ int cli_scanpe(cli_ctx *ctx) |
4601 | 4601 |
|
4602 | 4602 |
for(i = 0 ; i < nsections; i++) { |
4603 | 4603 |
if(exe_sections[i].raw) { |
4604 |
- unsigned int r_ret; |
|
4604 |
+ unsigned int r_ret; |
|
4605 | 4605 |
|
4606 |
- if (!exe_sections[i].rsz) |
|
4607 |
- goto out_no_petite; |
|
4606 |
+ if (!exe_sections[i].rsz) |
|
4607 |
+ goto out_no_petite; |
|
4608 | 4608 |
|
4609 |
- if (!CLI_ISCONTAINED(dest, dsize, |
|
4610 |
- dest + exe_sections[i].rva - min, |
|
4611 |
- exe_sections[i].ursz)) |
|
4612 |
- goto out_no_petite; |
|
4609 |
+ if (!CLI_ISCONTAINED(dest, dsize, |
|
4610 |
+ dest + exe_sections[i].rva - min, |
|
4611 |
+ exe_sections[i].ursz)) |
|
4612 |
+ goto out_no_petite; |
|
4613 | 4613 |
|
4614 |
- r_ret = fmap_readn(map, dest + exe_sections[i].rva - min, |
|
4615 |
- exe_sections[i].raw, |
|
4616 |
- exe_sections[i].ursz); |
|
4617 |
- if (r_ret != exe_sections[i].ursz) { |
|
4614 |
+ r_ret = fmap_readn(map, dest + exe_sections[i].rva - min, |
|
4615 |
+ exe_sections[i].raw, |
|
4616 |
+ exe_sections[i].ursz); |
|
4617 |
+ if (r_ret != exe_sections[i].ursz) { |
|
4618 | 4618 |
out_no_petite: |
4619 | 4619 |
free(exe_sections); |
4620 | 4620 |
free(dest); |
... | ... |
@@ -5588,10 +5588,10 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uin |
5588 | 5588 |
// and that the certificate table is the last thing in the file |
5589 | 5589 |
// (according to the MS13-098 bulletin, this is a requirement) |
5590 | 5590 |
if (fsize != EC32(dirs[4].Size) + EC32(dirs[4].VirtualAddress)) { |
5591 |
+ cli_dbgmsg("cli_checkfp_pe: expected authenticode data at the end of the file\n"); |
|
5591 | 5592 |
if (flags & CL_CHECKFP_PE_FLAG_STATS) { |
5592 | 5593 |
flags ^= CL_CHECKFP_PE_FLAG_AUTHENTICODE; |
5593 | 5594 |
} else { |
5594 |
- cli_dbgmsg("cli_checkfp_pe: expected authenticode data at the end of the file\n"); |
|
5595 | 5595 |
free(exe_sections); |
5596 | 5596 |
if (hashctx) |
5597 | 5597 |
cl_hash_destroy(hashctx); |