]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/ts/ts_rsp_sign.c
9ae584ff123f205148328f28ad91e11a2e53baf8
[thirdparty/openssl.git] / crypto / ts / ts_rsp_sign.c
1 /*
2 * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include "e_os.h"
11 #include "internal/cryptlib.h"
12
13 #include <openssl/objects.h>
14 #include <openssl/ts.h>
15 #include <openssl/pkcs7.h>
16 #include <openssl/crypto.h>
17 #include "ts_local.h"
18 #include "crypto/ess.h"
19
20 DEFINE_STACK_OF_CONST(EVP_MD)
21
22 static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
23 static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
24 static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
25
26 static void ts_RESP_CTX_init(TS_RESP_CTX *ctx);
27 static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
28 static int ts_RESP_check_request(TS_RESP_CTX *ctx);
29 static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx);
30 static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
31 ASN1_OBJECT *policy);
32 static int ts_RESP_process_extensions(TS_RESP_CTX *ctx);
33 static int ts_RESP_sign(TS_RESP_CTX *ctx);
34
35 static int ts_TST_INFO_content_new(PKCS7 *p7);
36
37 static ASN1_GENERALIZEDTIME
38 *TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long,
39 unsigned);
40
41 /* Default callback for response generation. */
42 static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
43 {
44 ASN1_INTEGER *serial = ASN1_INTEGER_new();
45
46 if (serial == NULL)
47 goto err;
48 if (!ASN1_INTEGER_set(serial, 1))
49 goto err;
50 return serial;
51
52 err:
53 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
54 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
55 "Error during serial number generation.");
56 ASN1_INTEGER_free(serial);
57 return NULL;
58 }
59
60 #if defined(OPENSSL_SYS_UNIX)
61
62 static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
63 long *sec, long *usec)
64 {
65 struct timeval tv;
66 if (gettimeofday(&tv, NULL) != 0) {
67 ERR_raise(ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR);
68 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
69 "Time is not available.");
70 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
71 return 0;
72 }
73 *sec = tv.tv_sec;
74 *usec = tv.tv_usec;
75
76 return 1;
77 }
78
79 #else
80
81 static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
82 long *sec, long *usec)
83 {
84 time_t t;
85 if (time(&t) == (time_t)-1) {
86 ERR_raise(ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR);
87 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
88 "Time is not available.");
89 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
90 return 0;
91 }
92 *sec = (long)t;
93 *usec = 0;
94
95 return 1;
96 }
97
98 #endif
99
100 static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
101 void *data)
102 {
103 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
104 "Unsupported extension.");
105 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
106 return 0;
107 }
108
109 /* TS_RESP_CTX management functions. */
110
111 TS_RESP_CTX *TS_RESP_CTX_new(void)
112 {
113 TS_RESP_CTX *ctx;
114
115 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
116 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
117 return NULL;
118 }
119
120 ctx->signer_md = EVP_sha256();
121
122 ctx->serial_cb = def_serial_cb;
123 ctx->time_cb = def_time_cb;
124 ctx->extension_cb = def_extension_cb;
125
126 return ctx;
127 }
128
129 void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
130 {
131 if (!ctx)
132 return;
133
134 X509_free(ctx->signer_cert);
135 EVP_PKEY_free(ctx->signer_key);
136 sk_X509_pop_free(ctx->certs, X509_free);
137 sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
138 ASN1_OBJECT_free(ctx->default_policy);
139 sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */
140 ASN1_INTEGER_free(ctx->seconds);
141 ASN1_INTEGER_free(ctx->millis);
142 ASN1_INTEGER_free(ctx->micros);
143 OPENSSL_free(ctx);
144 }
145
146 int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
147 {
148 if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) {
149 ERR_raise(ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
150 return 0;
151 }
152 X509_free(ctx->signer_cert);
153 ctx->signer_cert = signer;
154 X509_up_ref(ctx->signer_cert);
155 return 1;
156 }
157
158 int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
159 {
160 EVP_PKEY_free(ctx->signer_key);
161 ctx->signer_key = key;
162 EVP_PKEY_up_ref(ctx->signer_key);
163
164 return 1;
165 }
166
167 int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, const EVP_MD *md)
168 {
169 ctx->signer_md = md;
170 return 1;
171 }
172
173 int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy)
174 {
175 ASN1_OBJECT_free(ctx->default_policy);
176 if ((ctx->default_policy = OBJ_dup(def_policy)) == NULL)
177 goto err;
178 return 1;
179 err:
180 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
181 return 0;
182 }
183
184 int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
185 {
186
187 sk_X509_pop_free(ctx->certs, X509_free);
188 ctx->certs = NULL;
189 if (!certs)
190 return 1;
191 if ((ctx->certs = X509_chain_up_ref(certs)) == NULL) {
192 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
193 return 0;
194 }
195
196 return 1;
197 }
198
199 int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy)
200 {
201 ASN1_OBJECT *copy = NULL;
202
203 if (ctx->policies == NULL
204 && (ctx->policies = sk_ASN1_OBJECT_new_null()) == NULL)
205 goto err;
206 if ((copy = OBJ_dup(policy)) == NULL)
207 goto err;
208 if (!sk_ASN1_OBJECT_push(ctx->policies, copy))
209 goto err;
210
211 return 1;
212 err:
213 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
214 ASN1_OBJECT_free(copy);
215 return 0;
216 }
217
218 int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
219 {
220 if (ctx->mds == NULL
221 && (ctx->mds = sk_EVP_MD_new_null()) == NULL)
222 goto err;
223 if (!sk_EVP_MD_push(ctx->mds, md))
224 goto err;
225
226 return 1;
227 err:
228 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
229 return 0;
230 }
231
232 #define TS_RESP_CTX_accuracy_free(ctx) \
233 ASN1_INTEGER_free(ctx->seconds); \
234 ctx->seconds = NULL; \
235 ASN1_INTEGER_free(ctx->millis); \
236 ctx->millis = NULL; \
237 ASN1_INTEGER_free(ctx->micros); \
238 ctx->micros = NULL;
239
240 int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
241 int secs, int millis, int micros)
242 {
243
244 TS_RESP_CTX_accuracy_free(ctx);
245 if (secs
246 && ((ctx->seconds = ASN1_INTEGER_new()) == NULL
247 || !ASN1_INTEGER_set(ctx->seconds, secs)))
248 goto err;
249 if (millis
250 && ((ctx->millis = ASN1_INTEGER_new()) == NULL
251 || !ASN1_INTEGER_set(ctx->millis, millis)))
252 goto err;
253 if (micros
254 && ((ctx->micros = ASN1_INTEGER_new()) == NULL
255 || !ASN1_INTEGER_set(ctx->micros, micros)))
256 goto err;
257
258 return 1;
259 err:
260 TS_RESP_CTX_accuracy_free(ctx);
261 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
262 return 0;
263 }
264
265 void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
266 {
267 ctx->flags |= flags;
268 }
269
270 void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
271 {
272 ctx->serial_cb = cb;
273 ctx->serial_cb_data = data;
274 }
275
276 void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
277 {
278 ctx->time_cb = cb;
279 ctx->time_cb_data = data;
280 }
281
282 void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
283 TS_extension_cb cb, void *data)
284 {
285 ctx->extension_cb = cb;
286 ctx->extension_cb_data = data;
287 }
288
289 int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
290 int status, const char *text)
291 {
292 TS_STATUS_INFO *si = NULL;
293 ASN1_UTF8STRING *utf8_text = NULL;
294 int ret = 0;
295
296 if ((si = TS_STATUS_INFO_new()) == NULL)
297 goto err;
298 if (!ASN1_INTEGER_set(si->status, status))
299 goto err;
300 if (text) {
301 if ((utf8_text = ASN1_UTF8STRING_new()) == NULL
302 || !ASN1_STRING_set(utf8_text, text, strlen(text)))
303 goto err;
304 if (si->text == NULL
305 && (si->text = sk_ASN1_UTF8STRING_new_null()) == NULL)
306 goto err;
307 if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text))
308 goto err;
309 utf8_text = NULL; /* Ownership is lost. */
310 }
311 if (!TS_RESP_set_status_info(ctx->response, si))
312 goto err;
313 ret = 1;
314 err:
315 if (!ret)
316 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
317 TS_STATUS_INFO_free(si);
318 ASN1_UTF8STRING_free(utf8_text);
319 return ret;
320 }
321
322 int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
323 int status, const char *text)
324 {
325 int ret = 1;
326 TS_STATUS_INFO *si = ctx->response->status_info;
327
328 if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) {
329 ret = TS_RESP_CTX_set_status_info(ctx, status, text);
330 }
331 return ret;
332 }
333
334 int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
335 {
336 TS_STATUS_INFO *si = ctx->response->status_info;
337 if (si->failure_info == NULL
338 && (si->failure_info = ASN1_BIT_STRING_new()) == NULL)
339 goto err;
340 if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
341 goto err;
342 return 1;
343 err:
344 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
345 return 0;
346 }
347
348 TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
349 {
350 return ctx->request;
351 }
352
353 TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
354 {
355 return ctx->tst_info;
356 }
357
358 int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
359 unsigned precision)
360 {
361 if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
362 return 0;
363 ctx->clock_precision_digits = precision;
364 return 1;
365 }
366
367 /* Main entry method of the response generation. */
368 TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
369 {
370 ASN1_OBJECT *policy;
371 TS_RESP *response;
372 int result = 0;
373
374 ts_RESP_CTX_init(ctx);
375
376 if ((ctx->response = TS_RESP_new()) == NULL) {
377 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
378 goto end;
379 }
380 if ((ctx->request = d2i_TS_REQ_bio(req_bio, NULL)) == NULL) {
381 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
382 "Bad request format or system error.");
383 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
384 goto end;
385 }
386 if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
387 goto end;
388 if (!ts_RESP_check_request(ctx))
389 goto end;
390 if ((policy = ts_RESP_get_policy(ctx)) == NULL)
391 goto end;
392 if ((ctx->tst_info = ts_RESP_create_tst_info(ctx, policy)) == NULL)
393 goto end;
394 if (!ts_RESP_process_extensions(ctx))
395 goto end;
396 if (!ts_RESP_sign(ctx))
397 goto end;
398 result = 1;
399
400 end:
401 if (!result) {
402 ERR_raise(ERR_LIB_TS, TS_R_RESPONSE_SETUP_ERROR);
403 if (ctx->response != NULL) {
404 if (TS_RESP_CTX_set_status_info_cond(ctx,
405 TS_STATUS_REJECTION,
406 "Error during response "
407 "generation.") == 0) {
408 TS_RESP_free(ctx->response);
409 ctx->response = NULL;
410 }
411 }
412 }
413 response = ctx->response;
414 ctx->response = NULL; /* Ownership will be returned to caller. */
415 ts_RESP_CTX_cleanup(ctx);
416 return response;
417 }
418
419 /* Initializes the variable part of the context. */
420 static void ts_RESP_CTX_init(TS_RESP_CTX *ctx)
421 {
422 ctx->request = NULL;
423 ctx->response = NULL;
424 ctx->tst_info = NULL;
425 }
426
427 /* Cleans up the variable part of the context. */
428 static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
429 {
430 TS_REQ_free(ctx->request);
431 ctx->request = NULL;
432 TS_RESP_free(ctx->response);
433 ctx->response = NULL;
434 TS_TST_INFO_free(ctx->tst_info);
435 ctx->tst_info = NULL;
436 }
437
438 /* Checks the format and content of the request. */
439 static int ts_RESP_check_request(TS_RESP_CTX *ctx)
440 {
441 TS_REQ *request = ctx->request;
442 TS_MSG_IMPRINT *msg_imprint;
443 X509_ALGOR *md_alg;
444 int md_alg_id;
445 const ASN1_OCTET_STRING *digest;
446 const EVP_MD *md = NULL;
447 int i;
448
449 if (TS_REQ_get_version(request) != 1) {
450 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
451 "Bad request version.");
452 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
453 return 0;
454 }
455
456 msg_imprint = request->msg_imprint;
457 md_alg = msg_imprint->hash_algo;
458 md_alg_id = OBJ_obj2nid(md_alg->algorithm);
459 for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) {
460 const EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
461 if (md_alg_id == EVP_MD_type(current_md))
462 md = current_md;
463 }
464 if (!md) {
465 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
466 "Message digest algorithm is "
467 "not supported.");
468 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
469 return 0;
470 }
471
472 if (md_alg->parameter && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) {
473 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
474 "Superfluous message digest "
475 "parameter.");
476 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
477 return 0;
478 }
479 digest = msg_imprint->hashed_msg;
480 if (digest->length != EVP_MD_size(md)) {
481 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
482 "Bad message digest.");
483 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
484 return 0;
485 }
486
487 return 1;
488 }
489
490 /* Returns the TSA policy based on the requested and acceptable policies. */
491 static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx)
492 {
493 ASN1_OBJECT *requested = ctx->request->policy_id;
494 ASN1_OBJECT *policy = NULL;
495 int i;
496
497 if (ctx->default_policy == NULL) {
498 ERR_raise(ERR_LIB_TS, TS_R_INVALID_NULL_POINTER);
499 return NULL;
500 }
501 if (!requested || !OBJ_cmp(requested, ctx->default_policy))
502 policy = ctx->default_policy;
503
504 /* Check if the policy is acceptable. */
505 for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) {
506 ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
507 if (!OBJ_cmp(requested, current))
508 policy = current;
509 }
510 if (policy == NULL) {
511 ERR_raise(ERR_LIB_TS, TS_R_UNACCEPTABLE_POLICY);
512 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
513 "Requested policy is not " "supported.");
514 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
515 }
516 return policy;
517 }
518
519 /* Creates the TS_TST_INFO object based on the settings of the context. */
520 static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
521 ASN1_OBJECT *policy)
522 {
523 int result = 0;
524 TS_TST_INFO *tst_info = NULL;
525 ASN1_INTEGER *serial = NULL;
526 ASN1_GENERALIZEDTIME *asn1_time = NULL;
527 long sec, usec;
528 TS_ACCURACY *accuracy = NULL;
529 const ASN1_INTEGER *nonce;
530 GENERAL_NAME *tsa_name = NULL;
531
532 if ((tst_info = TS_TST_INFO_new()) == NULL)
533 goto end;
534 if (!TS_TST_INFO_set_version(tst_info, 1))
535 goto end;
536 if (!TS_TST_INFO_set_policy_id(tst_info, policy))
537 goto end;
538 if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
539 goto end;
540 if ((serial = ctx->serial_cb(ctx, ctx->serial_cb_data)) == NULL
541 || !TS_TST_INFO_set_serial(tst_info, serial))
542 goto end;
543 if (!ctx->time_cb(ctx, ctx->time_cb_data, &sec, &usec)
544 || (asn1_time =
545 TS_RESP_set_genTime_with_precision(NULL, sec, usec,
546 ctx->clock_precision_digits)) == NULL
547 || !TS_TST_INFO_set_time(tst_info, asn1_time))
548 goto end;
549
550 if ((ctx->seconds || ctx->millis || ctx->micros)
551 && (accuracy = TS_ACCURACY_new()) == NULL)
552 goto end;
553 if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
554 goto end;
555 if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
556 goto end;
557 if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
558 goto end;
559 if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))
560 goto end;
561
562 if ((ctx->flags & TS_ORDERING)
563 && !TS_TST_INFO_set_ordering(tst_info, 1))
564 goto end;
565
566 if ((nonce = ctx->request->nonce) != NULL
567 && !TS_TST_INFO_set_nonce(tst_info, nonce))
568 goto end;
569
570 if (ctx->flags & TS_TSA_NAME) {
571 if ((tsa_name = GENERAL_NAME_new()) == NULL)
572 goto end;
573 tsa_name->type = GEN_DIRNAME;
574 tsa_name->d.dirn =
575 X509_NAME_dup(X509_get_subject_name(ctx->signer_cert));
576 if (!tsa_name->d.dirn)
577 goto end;
578 if (!TS_TST_INFO_set_tsa(tst_info, tsa_name))
579 goto end;
580 }
581
582 result = 1;
583 end:
584 if (!result) {
585 TS_TST_INFO_free(tst_info);
586 tst_info = NULL;
587 ERR_raise(ERR_LIB_TS, TS_R_TST_INFO_SETUP_ERROR);
588 TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
589 "Error during TSTInfo "
590 "generation.");
591 }
592 GENERAL_NAME_free(tsa_name);
593 TS_ACCURACY_free(accuracy);
594 ASN1_GENERALIZEDTIME_free(asn1_time);
595 ASN1_INTEGER_free(serial);
596
597 return tst_info;
598 }
599
600 /* Processing the extensions of the request. */
601 static int ts_RESP_process_extensions(TS_RESP_CTX *ctx)
602 {
603 STACK_OF(X509_EXTENSION) *exts = ctx->request->extensions;
604 int i;
605 int ok = 1;
606
607 for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) {
608 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
609 /*
610 * The last argument was previously (void *)ctx->extension_cb,
611 * but ISO C doesn't permit converting a function pointer to void *.
612 * For lack of better information, I'm placing a NULL there instead.
613 * The callback can pick its own address out from the ctx anyway...
614 */
615 ok = (*ctx->extension_cb) (ctx, ext, NULL);
616 }
617
618 return ok;
619 }
620
621 /* Functions for signing the TS_TST_INFO structure of the context. */
622 static int ts_RESP_sign(TS_RESP_CTX *ctx)
623 {
624 int ret = 0;
625 PKCS7 *p7 = NULL;
626 PKCS7_SIGNER_INFO *si;
627 STACK_OF(X509) *certs; /* Certificates to include in sc. */
628 ESS_SIGNING_CERT_V2 *sc2 = NULL;
629 ESS_SIGNING_CERT *sc = NULL;
630 ASN1_OBJECT *oid;
631 BIO *p7bio = NULL;
632 int i;
633
634 if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
635 ERR_raise(ERR_LIB_TS, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
636 goto err;
637 }
638
639 if ((p7 = PKCS7_new()) == NULL) {
640 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
641 goto err;
642 }
643 if (!PKCS7_set_type(p7, NID_pkcs7_signed))
644 goto err;
645 if (!ASN1_INTEGER_set(p7->d.sign->version, 3))
646 goto err;
647
648 if (ctx->request->cert_req) {
649 PKCS7_add_certificate(p7, ctx->signer_cert);
650 if (ctx->certs) {
651 for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
652 X509 *cert = sk_X509_value(ctx->certs, i);
653 PKCS7_add_certificate(p7, cert);
654 }
655 }
656 }
657
658 if ((si = PKCS7_add_signature(p7, ctx->signer_cert,
659 ctx->signer_key, ctx->signer_md)) == NULL) {
660 ERR_raise(ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
661 goto err;
662 }
663
664 oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
665 if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
666 V_ASN1_OBJECT, oid)) {
667 ERR_raise(ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
668 goto err;
669 }
670
671 certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
672 if (ctx->ess_cert_id_digest == NULL
673 || ctx->ess_cert_id_digest == EVP_sha1()) {
674 if ((sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs, 0)) == NULL)
675 goto err;
676
677 if (!ESS_SIGNING_CERT_add(si, sc)) {
678 ERR_raise(ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
679 goto err;
680 }
681 } else {
682 sc2 = ESS_SIGNING_CERT_V2_new_init(ctx->ess_cert_id_digest,
683 ctx->signer_cert, certs, 0);
684 if (sc2 == NULL)
685 goto err;
686
687 if (!ESS_SIGNING_CERT_V2_add(si, sc2)) {
688 ERR_raise(ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR);
689 goto err;
690 }
691 }
692
693 if (!ts_TST_INFO_content_new(p7))
694 goto err;
695 if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
696 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
697 goto err;
698 }
699 if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) {
700 ERR_raise(ERR_LIB_TS, TS_R_TS_DATASIGN);
701 goto err;
702 }
703 if (!PKCS7_dataFinal(p7, p7bio)) {
704 ERR_raise(ERR_LIB_TS, TS_R_TS_DATASIGN);
705 goto err;
706 }
707 TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
708 p7 = NULL; /* Ownership is lost. */
709 ctx->tst_info = NULL; /* Ownership is lost. */
710
711 ret = 1;
712 err:
713 if (!ret)
714 TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
715 "Error during signature "
716 "generation.");
717 BIO_free_all(p7bio);
718 ESS_SIGNING_CERT_V2_free(sc2);
719 ESS_SIGNING_CERT_free(sc);
720 PKCS7_free(p7);
721 return ret;
722 }
723
724 static int ts_TST_INFO_content_new(PKCS7 *p7)
725 {
726 PKCS7 *ret = NULL;
727 ASN1_OCTET_STRING *octet_string = NULL;
728
729 /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
730 if ((ret = PKCS7_new()) == NULL)
731 goto err;
732 if ((ret->d.other = ASN1_TYPE_new()) == NULL)
733 goto err;
734 ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
735 if ((octet_string = ASN1_OCTET_STRING_new()) == NULL)
736 goto err;
737 ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
738 octet_string = NULL;
739
740 /* Add encapsulated content to signed PKCS7 structure. */
741 if (!PKCS7_set_content(p7, ret))
742 goto err;
743
744 return 1;
745 err:
746 ASN1_OCTET_STRING_free(octet_string);
747 PKCS7_free(ret);
748 return 0;
749 }
750
751 static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
752 ASN1_GENERALIZEDTIME *asn1_time, long sec, long usec,
753 unsigned precision)
754 {
755 time_t time_sec = (time_t)sec;
756 struct tm *tm = NULL, tm_result;
757 char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
758 char *p = genTime_str;
759 char *p_end = genTime_str + sizeof(genTime_str);
760
761 if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
762 goto err;
763
764 if ((tm = OPENSSL_gmtime(&time_sec, &tm_result)) == NULL)
765 goto err;
766
767 /*
768 * Put "genTime_str" in GeneralizedTime format. We work around the
769 * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST
770 * NOT include fractional seconds") and OpenSSL related functions to
771 * meet the rfc3161 requirement: "GeneralizedTime syntax can include
772 * fraction-of-second details".
773 */
774 p += BIO_snprintf(p, p_end - p,
775 "%04d%02d%02d%02d%02d%02d",
776 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
777 tm->tm_hour, tm->tm_min, tm->tm_sec);
778 if (precision > 0) {
779 BIO_snprintf(p, 2 + precision, ".%06ld", usec);
780 p += strlen(p);
781
782 /*
783 * To make things a bit harder, X.690 | ISO/IEC 8825-1 provides the
784 * following restrictions for a DER-encoding, which OpenSSL
785 * (specifically ASN1_GENERALIZEDTIME_check() function) doesn't
786 * support: "The encoding MUST terminate with a "Z" (which means
787 * "Zulu" time). The decimal point element, if present, MUST be the
788 * point option ".". The fractional-seconds elements, if present,
789 * MUST omit all trailing 0's; if the elements correspond to 0, they
790 * MUST be wholly omitted, and the decimal point element also MUST be
791 * omitted."
792 */
793 /*
794 * Remove trailing zeros. The dot guarantees the exit condition of
795 * this loop even if all the digits are zero.
796 */
797 while (*--p == '0')
798 continue;
799 if (*p != '.')
800 ++p;
801 }
802 *p++ = 'Z';
803 *p++ = '\0';
804
805 if (asn1_time == NULL
806 && (asn1_time = ASN1_GENERALIZEDTIME_new()) == NULL)
807 goto err;
808 if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) {
809 ASN1_GENERALIZEDTIME_free(asn1_time);
810 goto err;
811 }
812 return asn1_time;
813
814 err:
815 ERR_raise(ERR_LIB_TS, TS_R_COULD_NOT_SET_TIME);
816 return NULL;
817 }
818
819 int TS_RESP_CTX_set_ess_cert_id_digest(TS_RESP_CTX *ctx, const EVP_MD *md)
820 {
821 ctx->ess_cert_id_digest = md;
822 return 1;
823 }