Line | Source | Count |
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 | | - |
37 | | - |
38 | | - |
39 | | - |
40 | | - |
41 | | - |
42 | | - |
43 | | - |
44 | | - |
45 | | - |
46 | | - |
47 | | - |
48 | | - |
49 | | - |
50 | | - |
51 | | - |
52 | | - |
53 | | - |
54 | | - |
55 | | - |
56 | | - |
57 | | - |
58 | | - |
59 | #include <stdio.h> | - |
60 | #include <string.h> | - |
61 | | - |
62 | #include <openssl/err.h> | - |
63 | #include <openssl/objects.h> | - |
64 | #include <openssl/pkcs7.h> | - |
65 | #include <openssl/ts.h> | - |
66 | | - |
67 | | - |
68 | | - |
69 | static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, | - |
70 | X509 *signer, STACK_OF(X509) **chain); | - |
71 | static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); | - |
72 | static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); | - |
73 | static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); | - |
74 | static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo); | - |
75 | static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, | - |
76 | PKCS7 *token, TS_TST_INFO *tst_info); | - |
77 | static int TS_check_status_info(TS_RESP *response); | - |
78 | static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text); | - |
79 | static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info); | - |
80 | static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, | - |
81 | X509_ALGOR **md_alg, | - |
82 | unsigned char **imprint, unsigned *imprint_len); | - |
83 | static int TS_check_imprints(X509_ALGOR *algor_a, | - |
84 | unsigned char *imprint_a, unsigned len_a, | - |
85 | TS_TST_INFO *tst_info); | - |
86 | static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); | - |
87 | static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); | - |
88 | static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name); | - |
89 | | - |
90 | | - |
91 | | - |
92 | | - |
93 | | - |
94 | | - |
95 | static const char *TS_status_text[] = { | - |
96 | "granted", | - |
97 | "grantedWithMods", | - |
98 | "rejection", | - |
99 | "waiting", | - |
100 | "revocationWarning", | - |
101 | "revocationNotification" | - |
102 | }; | - |
103 | | - |
104 | #define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text)) | - |
105 | | - |
106 | | - |
107 | | - |
108 | | - |
109 | | - |
110 | #define TS_STATUS_BUF_SIZE 256 | - |
111 | | - |
112 | static struct { | - |
113 | int code; | - |
114 | const char *text; | - |
115 | } TS_failure_info[] = { | - |
116 | { TS_INFO_BAD_ALG, "badAlg" }, | - |
117 | { TS_INFO_BAD_REQUEST, "badRequest" }, | - |
118 | { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" }, | - |
119 | { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" }, | - |
120 | { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" }, | - |
121 | { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" }, | - |
122 | { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" }, | - |
123 | { TS_INFO_SYSTEM_FAILURE, "systemFailure" } | - |
124 | }; | - |
125 | | - |
126 | #define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \ | - |
127 | sizeof(*TS_failure_info)) | - |
128 | | - |
129 | | - |
130 | | - |
131 | | - |
132 | | - |
133 | | - |
134 | | - |
135 | | - |
136 | | - |
137 | | - |
138 | | - |
139 | | - |
140 | | - |
141 | | - |
142 | | - |
143 | int | - |
144 | TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, | - |
145 | X509_STORE *store, X509 **signer_out) | - |
146 | { | - |
147 | STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; | - |
148 | PKCS7_SIGNER_INFO *si; | - |
149 | STACK_OF(X509) *signers = NULL; | - |
150 | X509 *signer; | - |
151 | STACK_OF(X509) *chain = NULL; | - |
152 | char buf[4096]; | - |
153 | int i, j = 0, ret = 0; | - |
154 | BIO *p7bio = NULL; | - |
155 | | - |
156 | | - |
157 | if (!token) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
158 | TSerror(TS_R_INVALID_NULL_POINTER); | - |
159 | goto err; never executed: goto err; | 0 |
160 | } | - |
161 | | - |
162 | | - |
163 | if (!PKCS7_type_is_signed(token)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
164 | TSerror(TS_R_WRONG_CONTENT_TYPE); | - |
165 | goto err; never executed: goto err; | 0 |
166 | } | - |
167 | | - |
168 | | - |
169 | sinfos = PKCS7_get_signer_info(token); | - |
170 | if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
171 | TSerror(TS_R_THERE_MUST_BE_ONE_SIGNER); | - |
172 | goto err; never executed: goto err; | 0 |
173 | } | - |
174 | si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); | - |
175 | | - |
176 | | - |
177 | if (PKCS7_get_detached(token)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
178 | TSerror(TS_R_NO_CONTENT); | - |
179 | goto err; never executed: goto err; | 0 |
180 | } | - |
181 | | - |
182 | | - |
183 | | - |
184 | signers = PKCS7_get0_signers(token, certs, 0); | - |
185 | if (!signers || sk_X509_num(signers) != 1)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
186 | goto err; never executed: goto err; | 0 |
187 | signer = sk_X509_value(signers, 0); | - |
188 | | - |
189 | | - |
190 | if (!TS_verify_cert(store, certs, signer, &chain))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
191 | goto err; never executed: goto err; | 0 |
192 | | - |
193 | | - |
194 | | - |
195 | if (!TS_check_signing_certs(si, chain))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
196 | goto err; never executed: goto err; | 0 |
197 | | - |
198 | | - |
199 | p7bio = PKCS7_dataInit(token, NULL); | - |
200 | | - |
201 | | - |
202 | while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
203 | ; never executed: ; | 0 |
204 | | - |
205 | | - |
206 | j = PKCS7_signatureVerify(p7bio, token, si, signer); | - |
207 | if (j <= 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
208 | TSerror(TS_R_SIGNATURE_FAILURE); | - |
209 | goto err; never executed: goto err; | 0 |
210 | } | - |
211 | | - |
212 | | - |
213 | if (signer_out) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
214 | *signer_out = signer; | - |
215 | CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); | - |
216 | } never executed: end of block | 0 |
217 | | - |
218 | ret = 1; | - |
219 | | - |
220 | err: code before this statement never executed: err: | 0 |
221 | BIO_free_all(p7bio); | - |
222 | sk_X509_pop_free(chain, X509_free); | - |
223 | sk_X509_free(signers); | - |
224 | | - |
225 | return ret; never executed: return ret; | 0 |
226 | } | - |
227 | | - |
228 | | - |
229 | | - |
230 | | - |
231 | | - |
232 | static int | - |
233 | TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, X509 *signer, | - |
234 | STACK_OF(X509) **chain) | - |
235 | { | - |
236 | X509_STORE_CTX cert_ctx; | - |
237 | int i; | - |
238 | int ret = 0; | - |
239 | | - |
240 | | - |
241 | *chain = NULL; | - |
242 | if (X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted) == 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
243 | TSerror(ERR_R_X509_LIB); | - |
244 | goto err; never executed: goto err; | 0 |
245 | } | - |
246 | if (X509_STORE_CTX_set_purpose(&cert_ctx,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
247 | X509_PURPOSE_TIMESTAMP_SIGN) == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
248 | goto err; never executed: goto err; | 0 |
249 | i = X509_verify_cert(&cert_ctx); | - |
250 | if (i <= 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
251 | int j = X509_STORE_CTX_get_error(&cert_ctx); | - |
252 | | - |
253 | TSerror(TS_R_CERTIFICATE_VERIFY_ERROR); | - |
254 | ERR_asprintf_error_data("Verify error:%s", | - |
255 | X509_verify_cert_error_string(j)); | - |
256 | goto err; never executed: goto err; | 0 |
257 | } else { | - |
258 | | - |
259 | *chain = X509_STORE_CTX_get1_chain(&cert_ctx); | - |
260 | ret = 1; | - |
261 | } never executed: end of block | 0 |
262 | | - |
263 | err: code before this statement never executed: err: | 0 |
264 | X509_STORE_CTX_cleanup(&cert_ctx); | - |
265 | | - |
266 | return ret; never executed: return ret; | 0 |
267 | } | - |
268 | | - |
269 | static int | - |
270 | TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain) | - |
271 | { | - |
272 | ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si); | - |
273 | STACK_OF(ESS_CERT_ID) *cert_ids = NULL; | - |
274 | X509 *cert; | - |
275 | int i = 0; | - |
276 | int ret = 0; | - |
277 | | - |
278 | if (!ss)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
279 | goto err; never executed: goto err; | 0 |
280 | cert_ids = ss->cert_ids; | - |
281 | | - |
282 | cert = sk_X509_value(chain, 0); | - |
283 | if (TS_find_cert(cert_ids, cert) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
284 | goto err; never executed: goto err; | 0 |
285 | | - |
286 | | - |
287 | | - |
288 | if (sk_ESS_CERT_ID_num(cert_ids) > 1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
289 | | - |
290 | for (i = 1; i < sk_X509_num(chain); ++i) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
291 | cert = sk_X509_value(chain, i); | - |
292 | if (TS_find_cert(cert_ids, cert) < 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
293 | goto err; never executed: goto err; | 0 |
294 | } never executed: end of block | 0 |
295 | } never executed: end of block | 0 |
296 | ret = 1; | - |
297 | | - |
298 | err: code before this statement never executed: err: | 0 |
299 | if (!ret)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
300 | TSerror(TS_R_ESS_SIGNING_CERTIFICATE_ERROR); never executed: ERR_put_error(47,(0xfff),(101),__FILE__,300); | 0 |
301 | ESS_SIGNING_CERT_free(ss); | - |
302 | return ret; never executed: return ret; | 0 |
303 | } | - |
304 | | - |
305 | static ESS_SIGNING_CERT * | - |
306 | ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) | - |
307 | { | - |
308 | ASN1_TYPE *attr; | - |
309 | const unsigned char *p; | - |
310 | | - |
311 | attr = PKCS7_get_signed_attribute(si, | - |
312 | NID_id_smime_aa_signingCertificate); | - |
313 | if (!attr)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
314 | return NULL; never executed: return ((void *)0) ; | 0 |
315 | if (attr->type != V_ASN1_SEQUENCE)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
316 | return NULL; never executed: return ((void *)0) ; | 0 |
317 | p = attr->value.sequence->data; | - |
318 | return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); never executed: return d2i_ESS_SIGNING_CERT( ((void *)0) , &p, attr->value.sequence->length); | 0 |
319 | } | - |
320 | | - |
321 | | - |
322 | static int | - |
323 | TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) | - |
324 | { | - |
325 | int i; | - |
326 | | - |
327 | if (!cert_ids || !cert)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
328 | return -1; never executed: return -1; | 0 |
329 | | - |
330 | | - |
331 | X509_check_purpose(cert, -1, 0); | - |
332 | | - |
333 | | - |
334 | for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
335 | ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); | - |
336 | | - |
337 | | - |
338 | if (cid->hash->length == sizeof(cert->sha1_hash) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
339 | !memcmp(cid->hash->data, cert->sha1_hash,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
340 | sizeof(cert->sha1_hash))) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
341 | | - |
342 | ESS_ISSUER_SERIAL *is = cid->issuer_serial; | - |
343 | if (!is || !TS_issuer_serial_cmp(is, cert->cert_info))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
344 | return i; never executed: return i; | 0 |
345 | } never executed: end of block | 0 |
346 | } never executed: end of block | 0 |
347 | | - |
348 | return -1; never executed: return -1; | 0 |
349 | } | - |
350 | | - |
351 | static int | - |
352 | TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo) | - |
353 | { | - |
354 | GENERAL_NAME *issuer; | - |
355 | | - |
356 | if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
357 | return -1; never executed: return -1; | 0 |
358 | | - |
359 | | - |
360 | issuer = sk_GENERAL_NAME_value(is->issuer, 0); | - |
361 | if (issuer->type != GEN_DIRNAME ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
362 | X509_NAME_cmp(issuer->d.dirn, cinfo->issuer))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
363 | return -1; never executed: return -1; | 0 |
364 | | - |
365 | | - |
366 | if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
367 | return -1; never executed: return -1; | 0 |
368 | | - |
369 | return 0; never executed: return 0; | 0 |
370 | } | - |
371 | | - |
372 | | - |
373 | | - |
374 | | - |
375 | | - |
376 | | - |
377 | | - |
378 | int | - |
379 | TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response) | - |
380 | { | - |
381 | PKCS7 *token = TS_RESP_get_token(response); | - |
382 | TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); | - |
383 | int ret = 0; | - |
384 | | - |
385 | | - |
386 | if (!TS_check_status_info(response))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
387 | goto err; never executed: goto err; | 0 |
388 | | - |
389 | | - |
390 | if (!int_TS_RESP_verify_token(ctx, token, tst_info))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
391 | goto err; never executed: goto err; | 0 |
392 | | - |
393 | ret = 1; | - |
394 | | - |
395 | err: code before this statement never executed: err: | 0 |
396 | return ret; never executed: return ret; | 0 |
397 | } | - |
398 | | - |
399 | | - |
400 | | - |
401 | | - |
402 | | - |
403 | int | - |
404 | TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token) | - |
405 | { | - |
406 | TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token); | - |
407 | int ret = 0; | - |
408 | | - |
409 | if (tst_info) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
410 | ret = int_TS_RESP_verify_token(ctx, token, tst_info); | - |
411 | TS_TST_INFO_free(tst_info); | - |
412 | } never executed: end of block | 0 |
413 | return ret; never executed: return ret; | 0 |
414 | } | - |
415 | | - |
416 | | - |
417 | | - |
418 | | - |
419 | | - |
420 | | - |
421 | | - |
422 | | - |
423 | | - |
424 | | - |
425 | | - |
426 | | - |
427 | | - |
428 | static int | - |
429 | int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token, | - |
430 | TS_TST_INFO *tst_info) | - |
431 | { | - |
432 | X509 *signer = NULL; | - |
433 | GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info); | - |
434 | X509_ALGOR *md_alg = NULL; | - |
435 | unsigned char *imprint = NULL; | - |
436 | unsigned imprint_len = 0; | - |
437 | int ret = 0; | - |
438 | | - |
439 | | - |
440 | if ((ctx->flags & TS_VFY_SIGNATURE) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
441 | !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
442 | goto err; never executed: goto err; | 0 |
443 | | - |
444 | | - |
445 | if ((ctx->flags & TS_VFY_VERSION) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
446 | TS_TST_INFO_get_version(tst_info) != 1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
447 | TSerror(TS_R_UNSUPPORTED_VERSION); | - |
448 | goto err; never executed: goto err; | 0 |
449 | } | - |
450 | | - |
451 | | - |
452 | if ((ctx->flags & TS_VFY_POLICY) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
453 | !TS_check_policy(ctx->policy, tst_info))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
454 | goto err; never executed: goto err; | 0 |
455 | | - |
456 | | - |
457 | if ((ctx->flags & TS_VFY_IMPRINT) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
458 | !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
459 | tst_info))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
460 | goto err; never executed: goto err; | 0 |
461 | | - |
462 | | - |
463 | if ((ctx->flags & TS_VFY_DATA) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
464 | (!TS_compute_imprint(ctx->data, tst_info,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
465 | &md_alg, &imprint, &imprint_len) ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
466 | !TS_check_imprints(md_alg, imprint, imprint_len, tst_info)))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
467 | goto err; never executed: goto err; | 0 |
468 | | - |
469 | | - |
470 | if ((ctx->flags & TS_VFY_NONCE) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
471 | !TS_check_nonces(ctx->nonce, tst_info))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
472 | goto err; never executed: goto err; | 0 |
473 | | - |
474 | | - |
475 | if ((ctx->flags & TS_VFY_SIGNER) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
476 | tsa_name && !TS_check_signer_name(tsa_name, signer)) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
477 | TSerror(TS_R_TSA_NAME_MISMATCH); | - |
478 | goto err; never executed: goto err; | 0 |
479 | } | - |
480 | | - |
481 | | - |
482 | if ((ctx->flags & TS_VFY_TSA_NAME) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
483 | !TS_check_signer_name(ctx->tsa_name, signer)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
484 | TSerror(TS_R_TSA_UNTRUSTED); | - |
485 | goto err; never executed: goto err; | 0 |
486 | } | - |
487 | | - |
488 | ret = 1; | - |
489 | | - |
490 | err: code before this statement never executed: err: | 0 |
491 | X509_free(signer); | - |
492 | X509_ALGOR_free(md_alg); | - |
493 | free(imprint); | - |
494 | return ret; never executed: return ret; | 0 |
495 | } | - |
496 | | - |
497 | static int | - |
498 | TS_check_status_info(TS_RESP *response) | - |
499 | { | - |
500 | TS_STATUS_INFO *info = TS_RESP_get_status_info(response); | - |
501 | long status = ASN1_INTEGER_get(info->status); | - |
502 | const char *status_text = NULL; | - |
503 | char *embedded_status_text = NULL; | - |
504 | char failure_text[TS_STATUS_BUF_SIZE] = ""; | - |
505 | | - |
506 | | - |
507 | if (status == 0 || status == 1)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
508 | return 1; never executed: return 1; | 0 |
509 | | - |
510 | | - |
511 | if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
512 | status_text = TS_status_text[status]; never executed: status_text = TS_status_text[status]; | 0 |
513 | else | - |
514 | status_text = "unknown code"; never executed: status_text = "unknown code"; | 0 |
515 | | - |
516 | | - |
517 | if (sk_ASN1_UTF8STRING_num(info->text) > 0 &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
518 | !(embedded_status_text = TS_get_status_text(info->text)))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
519 | return 0; never executed: return 0; | 0 |
520 | | - |
521 | | - |
522 | if (info->failure_info) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
523 | int i; | - |
524 | int first = 1; | - |
525 | for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
526 | if (ASN1_BIT_STRING_get_bit(info->failure_info,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
527 | TS_failure_info[i].code)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
528 | if (!first)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
529 | strlcat(failure_text, ",", never executed: strlcat(failure_text, ",", 256); | 0 |
530 | TS_STATUS_BUF_SIZE); never executed: strlcat(failure_text, ",", 256); | 0 |
531 | else | - |
532 | first = 0; never executed: first = 0; | 0 |
533 | strlcat(failure_text, TS_failure_info[i].text, | - |
534 | TS_STATUS_BUF_SIZE); | - |
535 | } never executed: end of block | 0 |
536 | } never executed: end of block | 0 |
537 | } never executed: end of block | 0 |
538 | if (failure_text[0] == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
539 | strlcpy(failure_text, "unspecified", TS_STATUS_BUF_SIZE); never executed: strlcpy(failure_text, "unspecified", 256); | 0 |
540 | | - |
541 | | - |
542 | TSerror(TS_R_NO_TIME_STAMP_TOKEN); | - |
543 | ERR_asprintf_error_data | - |
544 | ("status code: %s, status text: %s, failure codes: %s", | - |
545 | status_text, | - |
546 | embedded_status_text ? embedded_status_text : "unspecified", | - |
547 | failure_text); | - |
548 | free(embedded_status_text); | - |
549 | | - |
550 | return 0; never executed: return 0; | 0 |
551 | } | - |
552 | | - |
553 | static char * | - |
554 | TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) | - |
555 | { | - |
556 | int i; | - |
557 | unsigned int length = 0; | - |
558 | char *result = NULL; | - |
559 | | - |
560 | | - |
561 | for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
562 | ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); | - |
563 | length += ASN1_STRING_length(current); | - |
564 | length += 1; | - |
565 | } never executed: end of block | 0 |
566 | | - |
567 | if (!(result = malloc(length))) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
568 | TSerror(ERR_R_MALLOC_FAILURE); | - |
569 | return NULL; never executed: return ((void *)0) ; | 0 |
570 | } | - |
571 | | - |
572 | result[0] = '\0'; | - |
573 | for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
574 | ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); | - |
575 | if (i > 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
576 | strlcat(result, "/", length); never executed: strlcat(result, "/", length); | 0 |
577 | strlcat(result, (const char *)ASN1_STRING_data(current), length); | - |
578 | } never executed: end of block | 0 |
579 | return result; never executed: return result; | 0 |
580 | } | - |
581 | | - |
582 | static int | - |
583 | TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info) | - |
584 | { | - |
585 | ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info); | - |
586 | | - |
587 | if (OBJ_cmp(req_oid, resp_oid) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
588 | TSerror(TS_R_POLICY_MISMATCH); | - |
589 | return 0; never executed: return 0; | 0 |
590 | } | - |
591 | | - |
592 | return 1; never executed: return 1; | 0 |
593 | } | - |
594 | | - |
595 | static int | - |
596 | TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, X509_ALGOR **md_alg, | - |
597 | unsigned char **imprint, unsigned *imprint_len) | - |
598 | { | - |
599 | TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info); | - |
600 | X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint); | - |
601 | const EVP_MD *md; | - |
602 | EVP_MD_CTX md_ctx; | - |
603 | unsigned char buffer[4096]; | - |
604 | int length; | - |
605 | | - |
606 | *md_alg = NULL; | - |
607 | *imprint = NULL; | - |
608 | | - |
609 | | - |
610 | if (!(*md_alg = X509_ALGOR_dup(md_alg_resp)))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
611 | goto err; never executed: goto err; | 0 |
612 | | - |
613 | | - |
614 | if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
615 | TSerror(TS_R_UNSUPPORTED_MD_ALGORITHM); | - |
616 | goto err; never executed: goto err; | 0 |
617 | } | - |
618 | | - |
619 | | - |
620 | length = EVP_MD_size(md); | - |
621 | if (length < 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
622 | goto err; never executed: goto err; | 0 |
623 | *imprint_len = length; | - |
624 | if (!(*imprint = malloc(*imprint_len))) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
625 | TSerror(ERR_R_MALLOC_FAILURE); | - |
626 | goto err; never executed: goto err; | 0 |
627 | } | - |
628 | | - |
629 | if (!EVP_DigestInit(&md_ctx, md))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
630 | goto err; never executed: goto err; | 0 |
631 | while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
632 | if (!EVP_DigestUpdate(&md_ctx, buffer, length))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
633 | goto err; never executed: goto err; | 0 |
634 | } never executed: end of block | 0 |
635 | if (!EVP_DigestFinal(&md_ctx, *imprint, NULL))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
636 | goto err; never executed: goto err; | 0 |
637 | | - |
638 | return 1; never executed: return 1; | 0 |
639 | | - |
640 | err: | - |
641 | X509_ALGOR_free(*md_alg); | - |
642 | free(*imprint); | - |
643 | *imprint = NULL; | - |
644 | *imprint_len = 0; | - |
645 | return 0; never executed: return 0; | 0 |
646 | } | - |
647 | | - |
648 | static int | - |
649 | TS_check_imprints(X509_ALGOR *algor_a, unsigned char *imprint_a, unsigned len_a, | - |
650 | TS_TST_INFO *tst_info) | - |
651 | { | - |
652 | TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info); | - |
653 | X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b); | - |
654 | int ret = 0; | - |
655 | | - |
656 | | - |
657 | if (algor_a) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
658 | | - |
659 | if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
660 | goto err; never executed: goto err; | 0 |
661 | | - |
662 | | - |
663 | if ((algor_a->parameter &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
664 | ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
665 | (algor_b->parameter &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
666 | ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
667 | goto err; never executed: goto err; | 0 |
668 | } never executed: end of block | 0 |
669 | | - |
670 | | - |
671 | ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
672 | memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0;TRUE | never evaluated | FALSE | never evaluated |
| 0 |
673 | | - |
674 | err: code before this statement never executed: err: | 0 |
675 | if (!ret)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
676 | TSerror(TS_R_MESSAGE_IMPRINT_MISMATCH); never executed: ERR_put_error(47,(0xfff),(103),__FILE__,676); | 0 |
677 | return ret; never executed: return ret; | 0 |
678 | } | - |
679 | | - |
680 | static int | - |
681 | TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) | - |
682 | { | - |
683 | const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info); | - |
684 | | - |
685 | | - |
686 | if (!b) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
687 | TSerror(TS_R_NONCE_NOT_RETURNED); | - |
688 | return 0; never executed: return 0; | 0 |
689 | } | - |
690 | | - |
691 | | - |
692 | if (ASN1_INTEGER_cmp(a, b) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
693 | TSerror(TS_R_NONCE_MISMATCH); | - |
694 | return 0; never executed: return 0; | 0 |
695 | } | - |
696 | | - |
697 | return 1; never executed: return 1; | 0 |
698 | } | - |
699 | | - |
700 | | - |
701 | | - |
702 | static int | - |
703 | TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer) | - |
704 | { | - |
705 | STACK_OF(GENERAL_NAME) *gen_names = NULL; | - |
706 | int idx = -1; | - |
707 | int found = 0; | - |
708 | | - |
709 | if (signer == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
710 | return 0; never executed: return 0; | 0 |
711 | | - |
712 | | - |
713 | if (tsa_name->type == GEN_DIRNAME &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
714 | X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
715 | return 1; never executed: return 1; | 0 |
716 | | - |
717 | | - |
718 | gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, | - |
719 | NULL, &idx); | - |
720 | while (gen_names != NULL &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
721 | !(found = (TS_find_name(gen_names, tsa_name) >= 0))) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
722 | | - |
723 | | - |
724 | GENERAL_NAMES_free(gen_names); | - |
725 | gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, | - |
726 | NULL, &idx); | - |
727 | } never executed: end of block | 0 |
728 | if (gen_names)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
729 | GENERAL_NAMES_free(gen_names); never executed: GENERAL_NAMES_free(gen_names); | 0 |
730 | | - |
731 | return found; never executed: return found; | 0 |
732 | } | - |
733 | | - |
734 | | - |
735 | static int | - |
736 | TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name) | - |
737 | { | - |
738 | int i, found; | - |
739 | for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names);TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
740 | ++i) { | - |
741 | GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i); | - |
742 | found = GENERAL_NAME_cmp(current, name) == 0; | - |
743 | } never executed: end of block | 0 |
744 | return found ? i - 1 : -1; never executed: return found ? i - 1 : -1; TRUE | never evaluated | FALSE | never evaluated |
| 0 |
745 | } | - |
| | |