summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ts/ts_rsp_sign.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ts/ts_rsp_sign.c')
-rw-r--r--src/lib/libcrypto/ts/ts_rsp_sign.c1023
1 files changed, 0 insertions, 1023 deletions
diff --git a/src/lib/libcrypto/ts/ts_rsp_sign.c b/src/lib/libcrypto/ts/ts_rsp_sign.c
deleted file mode 100644
index 27659e8f45..0000000000
--- a/src/lib/libcrypto/ts/ts_rsp_sign.c
+++ /dev/null
@@ -1,1023 +0,0 @@
1/* $OpenBSD: ts_rsp_sign.c,v 1.18 2014/07/12 16:03:37 miod Exp $ */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <sys/time.h>
60
61#include <string.h>
62
63#include <openssl/err.h>
64#include <openssl/objects.h>
65#include <openssl/pkcs7.h>
66#include <openssl/ts.h>
67
68/* Private function declarations. */
69
70static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
71static int def_time_cb(struct TS_resp_ctx *, void *, time_t *sec, long *usec);
72static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
73
74static void TS_RESP_CTX_init(TS_RESP_CTX *ctx);
75static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
76static int TS_RESP_check_request(TS_RESP_CTX *ctx);
77static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx);
78static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx,
79 ASN1_OBJECT *policy);
80static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);
81static int TS_RESP_sign(TS_RESP_CTX *ctx);
82
83static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert,
84 STACK_OF(X509) *certs);
85static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);
86static int TS_TST_INFO_content_new(PKCS7 *p7);
87static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
88
89static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
90 ASN1_GENERALIZEDTIME *, time_t, long, unsigned);
91
92/* Default callbacks for response generation. */
93
94static ASN1_INTEGER *
95def_serial_cb(struct TS_resp_ctx *ctx, void *data)
96{
97 ASN1_INTEGER *serial = ASN1_INTEGER_new();
98
99 if (!serial)
100 goto err;
101 if (!ASN1_INTEGER_set(serial, 1))
102 goto err;
103 return serial;
104
105err:
106 TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
107 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
108 "Error during serial number generation.");
109 return NULL;
110}
111
112/* Use the gettimeofday function call. */
113static int
114def_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec)
115{
116 struct timeval tv;
117
118 if (gettimeofday(&tv, NULL) != 0) {
119 TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
120 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
121 "Time is not available.");
122 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
123 return 0;
124 }
125 /* Return time to caller. */
126 *sec = tv.tv_sec;
127 *usec = tv.tv_usec;
128
129 return 1;
130}
131
132static int
133def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, void *data)
134{
135 /* No extensions are processed here. */
136 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
137 "Unsupported extension.");
138 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
139 return 0;
140}
141
142/* TS_RESP_CTX management functions. */
143
144TS_RESP_CTX *
145TS_RESP_CTX_new(void)
146{
147 TS_RESP_CTX *ctx;
148
149 if (!(ctx = calloc(1, sizeof(TS_RESP_CTX)))) {
150 TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
151 return NULL;
152 }
153
154 /* Setting default callbacks. */
155 ctx->serial_cb = def_serial_cb;
156 ctx->time_cb = def_time_cb;
157 ctx->extension_cb = def_extension_cb;
158
159 return ctx;
160}
161
162void
163TS_RESP_CTX_free(TS_RESP_CTX *ctx)
164{
165 if (!ctx)
166 return;
167
168 X509_free(ctx->signer_cert);
169 EVP_PKEY_free(ctx->signer_key);
170 sk_X509_pop_free(ctx->certs, X509_free);
171 sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
172 ASN1_OBJECT_free(ctx->default_policy);
173 sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */
174 ASN1_INTEGER_free(ctx->seconds);
175 ASN1_INTEGER_free(ctx->millis);
176 ASN1_INTEGER_free(ctx->micros);
177 free(ctx);
178}
179
180int
181TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
182{
183 if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) {
184 TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT,
185 TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
186 return 0;
187 }
188 if (ctx->signer_cert)
189 X509_free(ctx->signer_cert);
190 ctx->signer_cert = signer;
191 CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509);
192 return 1;
193}
194
195int
196TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
197{
198 EVP_PKEY_free(ctx->signer_key);
199 ctx->signer_key = key;
200 CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY);
201
202 return 1;
203}
204
205int
206TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)
207{
208 if (ctx->default_policy)
209 ASN1_OBJECT_free(ctx->default_policy);
210 if (!(ctx->default_policy = OBJ_dup(def_policy)))
211 goto err;
212 return 1;
213
214err:
215 TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
216 return 0;
217}
218
219int
220TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
221{
222 int i;
223
224 if (ctx->certs) {
225 sk_X509_pop_free(ctx->certs, X509_free);
226 ctx->certs = NULL;
227 }
228 if (!certs)
229 return 1;
230 if (!(ctx->certs = sk_X509_dup(certs))) {
231 TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
232 return 0;
233 }
234 for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
235 X509 *cert = sk_X509_value(ctx->certs, i);
236 CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509);
237 }
238
239 return 1;
240}
241
242int
243TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
244{
245 ASN1_OBJECT *copy = NULL;
246
247 /* Create new policy stack if necessary. */
248 if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null()))
249 goto err;
250 if (!(copy = OBJ_dup(policy)))
251 goto err;
252 if (!sk_ASN1_OBJECT_push(ctx->policies, copy))
253 goto err;
254
255 return 1;
256
257err:
258 TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
259 ASN1_OBJECT_free(copy);
260 return 0;
261}
262
263int
264TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
265{
266 /* Create new md stack if necessary. */
267 if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null()))
268 goto err;
269 /* Add the shared md, no copy needed. */
270 if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md))
271 goto err;
272
273 return 1;
274
275err:
276 TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
277 return 0;
278}
279
280#define TS_RESP_CTX_accuracy_free(ctx) \
281 ASN1_INTEGER_free(ctx->seconds); \
282 ctx->seconds = NULL; \
283 ASN1_INTEGER_free(ctx->millis); \
284 ctx->millis = NULL; \
285 ASN1_INTEGER_free(ctx->micros); \
286 ctx->micros = NULL;
287
288int
289TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, int secs, int millis, int micros)
290{
291 TS_RESP_CTX_accuracy_free(ctx);
292 if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) ||
293 !ASN1_INTEGER_set(ctx->seconds, secs)))
294 goto err;
295 if (millis && (!(ctx->millis = ASN1_INTEGER_new()) ||
296 !ASN1_INTEGER_set(ctx->millis, millis)))
297 goto err;
298 if (micros && (!(ctx->micros = ASN1_INTEGER_new()) ||
299 !ASN1_INTEGER_set(ctx->micros, micros)))
300 goto err;
301
302 return 1;
303
304err:
305 TS_RESP_CTX_accuracy_free(ctx);
306 TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
307 return 0;
308}
309
310void
311TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
312{
313 ctx->flags |= flags;
314}
315
316void
317TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
318{
319 ctx->serial_cb = cb;
320 ctx->serial_cb_data = data;
321}
322
323void
324TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, TS_extension_cb cb, void *data)
325{
326 ctx->extension_cb = cb;
327 ctx->extension_cb_data = data;
328}
329
330int
331TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, int status, const char *text)
332{
333 TS_STATUS_INFO *si = NULL;
334 ASN1_UTF8STRING *utf8_text = NULL;
335 int ret = 0;
336
337 if (!(si = TS_STATUS_INFO_new()))
338 goto err;
339 if (!ASN1_INTEGER_set(si->status, status))
340 goto err;
341 if (text) {
342 if (!(utf8_text = ASN1_UTF8STRING_new()) ||
343 !ASN1_STRING_set(utf8_text, text, strlen(text)))
344 goto err;
345 if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null()))
346 goto err;
347 if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text))
348 goto err;
349 utf8_text = NULL; /* Ownership is lost. */
350 }
351 if (!TS_RESP_set_status_info(ctx->response, si))
352 goto err;
353 ret = 1;
354
355err:
356 if (!ret)
357 TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
358 TS_STATUS_INFO_free(si);
359 ASN1_UTF8STRING_free(utf8_text);
360 return ret;
361}
362
363int
364TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, int status, const char *text)
365{
366 int ret = 1;
367 TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
368
369 if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) {
370 /* Status has not been set, set it now. */
371 ret = TS_RESP_CTX_set_status_info(ctx, status, text);
372 }
373 return ret;
374}
375
376int
377TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
378{
379 TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
380
381 if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new()))
382 goto err;
383 if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
384 goto err;
385 return 1;
386
387err:
388 TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
389 return 0;
390}
391
392TS_REQ *
393TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
394{
395 return ctx->request;
396}
397
398TS_TST_INFO *
399TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
400{
401 return ctx->tst_info;
402}
403
404int
405TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision)
406{
407 if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
408 return 0;
409 ctx->clock_precision_digits = precision;
410 return 1;
411}
412
413/* Main entry method of the response generation. */
414TS_RESP *
415TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
416{
417 ASN1_OBJECT *policy;
418 TS_RESP *response;
419 int result = 0;
420
421 TS_RESP_CTX_init(ctx);
422
423 /* Creating the response object. */
424 if (!(ctx->response = TS_RESP_new())) {
425 TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
426 goto end;
427 }
428
429 /* Parsing DER request. */
430 if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) {
431 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
432 "Bad request format or "
433 "system error.");
434 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
435 goto end;
436 }
437
438 /* Setting default status info. */
439 if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
440 goto end;
441
442 /* Checking the request format. */
443 if (!TS_RESP_check_request(ctx))
444 goto end;
445
446 /* Checking acceptable policies. */
447 if (!(policy = TS_RESP_get_policy(ctx)))
448 goto end;
449
450 /* Creating the TS_TST_INFO object. */
451 if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy)))
452 goto end;
453
454 /* Processing extensions. */
455 if (!TS_RESP_process_extensions(ctx))
456 goto end;
457
458 /* Generating the signature. */
459 if (!TS_RESP_sign(ctx))
460 goto end;
461
462 /* Everything was successful. */
463 result = 1;
464
465end:
466 if (!result) {
467 TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
468 if (ctx->response != NULL) {
469 if (TS_RESP_CTX_set_status_info_cond(ctx,
470 TS_STATUS_REJECTION, "Error during response "
471 "generation.") == 0) {
472 TS_RESP_free(ctx->response);
473 ctx->response = NULL;
474 }
475 }
476 }
477 response = ctx->response;
478 ctx->response = NULL; /* Ownership will be returned to caller. */
479 TS_RESP_CTX_cleanup(ctx);
480 return response;
481}
482
483/* Initializes the variable part of the context. */
484static void
485TS_RESP_CTX_init(TS_RESP_CTX *ctx)
486{
487 ctx->request = NULL;
488 ctx->response = NULL;
489 ctx->tst_info = NULL;
490}
491
492/* Cleans up the variable part of the context. */
493static void
494TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
495{
496 TS_REQ_free(ctx->request);
497 ctx->request = NULL;
498 TS_RESP_free(ctx->response);
499 ctx->response = NULL;
500 TS_TST_INFO_free(ctx->tst_info);
501 ctx->tst_info = NULL;
502}
503
504/* Checks the format and content of the request. */
505static int
506TS_RESP_check_request(TS_RESP_CTX *ctx)
507{
508 TS_REQ *request = ctx->request;
509 TS_MSG_IMPRINT *msg_imprint;
510 X509_ALGOR *md_alg;
511 int md_alg_id;
512 const ASN1_OCTET_STRING *digest;
513 EVP_MD *md = NULL;
514 int i;
515
516 /* Checking request version. */
517 if (TS_REQ_get_version(request) != 1) {
518 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
519 "Bad request version.");
520 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
521 return 0;
522 }
523
524 /* Checking message digest algorithm. */
525 msg_imprint = TS_REQ_get_msg_imprint(request);
526 md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint);
527 md_alg_id = OBJ_obj2nid(md_alg->algorithm);
528 for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) {
529 EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
530 if (md_alg_id == EVP_MD_type(current_md))
531 md = current_md;
532 }
533 if (!md) {
534 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
535 "Message digest algorithm is "
536 "not supported.");
537 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
538 return 0;
539 }
540
541 /* No message digest takes parameter. */
542 if (md_alg->parameter &&
543 ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) {
544 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
545 "Superfluous message digest "
546 "parameter.");
547 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
548 return 0;
549 }
550 /* Checking message digest size. */
551 digest = TS_MSG_IMPRINT_get_msg(msg_imprint);
552 if (digest->length != EVP_MD_size(md)) {
553 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
554 "Bad message digest.");
555 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
556 return 0;
557 }
558
559 return 1;
560}
561
562/* Returns the TSA policy based on the requested and acceptable policies. */
563static ASN1_OBJECT *
564TS_RESP_get_policy(TS_RESP_CTX *ctx)
565{
566 ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request);
567 ASN1_OBJECT *policy = NULL;
568 int i;
569
570 if (ctx->default_policy == NULL) {
571 TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
572 return NULL;
573 }
574 /* Return the default policy if none is requested or the default is
575 requested. */
576 if (!requested || !OBJ_cmp(requested, ctx->default_policy))
577 policy = ctx->default_policy;
578
579 /* Check if the policy is acceptable. */
580 for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) {
581 ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
582 if (!OBJ_cmp(requested, current))
583 policy = current;
584 }
585 if (!policy) {
586 TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
587 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
588 "Requested policy is not "
589 "supported.");
590 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
591 }
592 return policy;
593}
594
595/* Creates the TS_TST_INFO object based on the settings of the context. */
596static TS_TST_INFO *
597TS_RESP_create_tst_info(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
598{
599 int result = 0;
600 TS_TST_INFO *tst_info = NULL;
601 ASN1_INTEGER *serial = NULL;
602 ASN1_GENERALIZEDTIME *asn1_time = NULL;
603 time_t sec;
604 long usec;
605 TS_ACCURACY *accuracy = NULL;
606 const ASN1_INTEGER *nonce;
607 GENERAL_NAME *tsa_name = NULL;
608
609 if (!(tst_info = TS_TST_INFO_new()))
610 goto end;
611 if (!TS_TST_INFO_set_version(tst_info, 1))
612 goto end;
613 if (!TS_TST_INFO_set_policy_id(tst_info, policy))
614 goto end;
615 if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
616 goto end;
617 if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data)) ||
618 !TS_TST_INFO_set_serial(tst_info, serial))
619 goto end;
620 if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec) ||
621 !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, sec, usec,
622 ctx->clock_precision_digits)) ||
623 !TS_TST_INFO_set_time(tst_info, asn1_time))
624 goto end;
625
626 /* Setting accuracy if needed. */
627 if ((ctx->seconds || ctx->millis || ctx->micros) &&
628 !(accuracy = TS_ACCURACY_new()))
629 goto end;
630
631 if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
632 goto end;
633 if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
634 goto end;
635 if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
636 goto end;
637 if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))
638 goto end;
639
640 /* Setting ordering. */
641 if ((ctx->flags & TS_ORDERING) &&
642 !TS_TST_INFO_set_ordering(tst_info, 1))
643 goto end;
644
645 /* Setting nonce if needed. */
646 if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL &&
647 !TS_TST_INFO_set_nonce(tst_info, nonce))
648 goto end;
649
650 /* Setting TSA name to subject of signer certificate. */
651 if (ctx->flags & TS_TSA_NAME) {
652 if (!(tsa_name = GENERAL_NAME_new()))
653 goto end;
654 tsa_name->type = GEN_DIRNAME;
655 tsa_name->d.dirn =
656 X509_NAME_dup(ctx->signer_cert->cert_info->subject);
657 if (!tsa_name->d.dirn)
658 goto end;
659 if (!TS_TST_INFO_set_tsa(tst_info, tsa_name))
660 goto end;
661 }
662
663 result = 1;
664
665end:
666 if (!result) {
667 TS_TST_INFO_free(tst_info);
668 tst_info = NULL;
669 TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
670 TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
671 "Error during TSTInfo "
672 "generation.");
673 }
674 GENERAL_NAME_free(tsa_name);
675 TS_ACCURACY_free(accuracy);
676 ASN1_GENERALIZEDTIME_free(asn1_time);
677 ASN1_INTEGER_free(serial);
678
679 return tst_info;
680}
681
682/* Processing the extensions of the request. */
683static int
684TS_RESP_process_extensions(TS_RESP_CTX *ctx)
685{
686 STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request);
687 int i;
688 int ok = 1;
689
690 for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) {
691 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
692 /* XXXXX The last argument was previously
693 (void *)ctx->extension_cb, but ISO C doesn't permit
694 converting a function pointer to void *. For lack of
695 better information, I'm placing a NULL there instead.
696 The callback can pick its own address out from the ctx
697 anyway...
698 */
699 ok = (*ctx->extension_cb)(ctx, ext, NULL);
700 }
701
702 return ok;
703}
704
705/* Functions for signing the TS_TST_INFO structure of the context. */
706static int
707TS_RESP_sign(TS_RESP_CTX *ctx)
708{
709 int ret = 0;
710 PKCS7 *p7 = NULL;
711 PKCS7_SIGNER_INFO *si;
712 STACK_OF(X509) *certs; /* Certificates to include in sc. */
713 ESS_SIGNING_CERT *sc = NULL;
714 ASN1_OBJECT *oid;
715 BIO *p7bio = NULL;
716 int i;
717
718 /* Check if signcert and pkey match. */
719 if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
720 TSerr(TS_F_TS_RESP_SIGN,
721 TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
722 goto err;
723 }
724
725 /* Create a new PKCS7 signed object. */
726 if (!(p7 = PKCS7_new())) {
727 TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
728 goto err;
729 }
730 if (!PKCS7_set_type(p7, NID_pkcs7_signed))
731 goto err;
732
733 /* Force SignedData version to be 3 instead of the default 1. */
734 if (!ASN1_INTEGER_set(p7->d.sign->version, 3))
735 goto err;
736
737 /* Add signer certificate and optional certificate chain. */
738 if (TS_REQ_get_cert_req(ctx->request)) {
739 PKCS7_add_certificate(p7, ctx->signer_cert);
740 if (ctx->certs) {
741 for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
742 X509 *cert = sk_X509_value(ctx->certs, i);
743 PKCS7_add_certificate(p7, cert);
744 }
745 }
746 }
747
748 /* Add a new signer info. */
749 if (!(si = PKCS7_add_signature(p7, ctx->signer_cert,
750 ctx->signer_key, EVP_sha1()))) {
751 TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
752 goto err;
753 }
754
755 /* Add content type signed attribute to the signer info. */
756 oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
757 if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
758 V_ASN1_OBJECT, oid)) {
759 TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
760 goto err;
761 }
762
763 /* Create the ESS SigningCertificate attribute which contains
764 the signer certificate id and optionally the certificate chain. */
765 certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
766 if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs)))
767 goto err;
768
769 /* Add SigningCertificate signed attribute to the signer info. */
770 if (!ESS_add_signing_cert(si, sc)) {
771 TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
772 goto err;
773 }
774
775 /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */
776 if (!TS_TST_INFO_content_new(p7))
777 goto err;
778
779 /* Add the DER encoded tst_info to the PKCS7 structure. */
780 if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
781 TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
782 goto err;
783 }
784
785 /* Convert tst_info to DER. */
786 if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) {
787 TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
788 goto err;
789 }
790
791 /* Create the signature and add it to the signer info. */
792 if (!PKCS7_dataFinal(p7, p7bio)) {
793 TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
794 goto err;
795 }
796
797 /* Set new PKCS7 and TST_INFO objects. */
798 TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
799 p7 = NULL; /* Ownership is lost. */
800 ctx->tst_info = NULL; /* Ownership is lost. */
801
802 ret = 1;
803
804err:
805 if (!ret)
806 TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
807 "Error during signature "
808 "generation.");
809 BIO_free_all(p7bio);
810 ESS_SIGNING_CERT_free(sc);
811 PKCS7_free(p7);
812 return ret;
813}
814
815static ESS_SIGNING_CERT *
816ESS_SIGNING_CERT_new_init(X509 *signcert, STACK_OF(X509) *certs)
817{
818 ESS_CERT_ID *cid;
819 ESS_SIGNING_CERT *sc = NULL;
820 int i;
821
822 /* Creating the ESS_CERT_ID stack. */
823 if (!(sc = ESS_SIGNING_CERT_new()))
824 goto err;
825 if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null()))
826 goto err;
827
828 /* Adding the signing certificate id. */
829 if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) ||
830 !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
831 goto err;
832 /* Adding the certificate chain ids. */
833 for (i = 0; i < sk_X509_num(certs); ++i) {
834 X509 *cert = sk_X509_value(certs, i);
835 if (!(cid = ESS_CERT_ID_new_init(cert, 1)) ||
836 !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
837 goto err;
838 }
839
840 return sc;
841
842err:
843 ESS_SIGNING_CERT_free(sc);
844 TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
845 return NULL;
846}
847
848static ESS_CERT_ID *
849ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
850{
851 ESS_CERT_ID *cid = NULL;
852 GENERAL_NAME *name = NULL;
853
854 /* Recompute SHA1 hash of certificate if necessary (side effect). */
855 X509_check_purpose(cert, -1, 0);
856
857 if (!(cid = ESS_CERT_ID_new()))
858 goto err;
859 if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash,
860 sizeof(cert->sha1_hash)))
861 goto err;
862
863 /* Setting the issuer/serial if requested. */
864 if (issuer_needed) {
865 /* Creating issuer/serial structure. */
866 if (!cid->issuer_serial &&
867 !(cid->issuer_serial = ESS_ISSUER_SERIAL_new()))
868 goto err;
869 /* Creating general name from the certificate issuer. */
870 if (!(name = GENERAL_NAME_new()))
871 goto err;
872 name->type = GEN_DIRNAME;
873 if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer)))
874 goto err;
875 if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
876 goto err;
877 name = NULL; /* Ownership is lost. */
878 /* Setting the serial number. */
879 ASN1_INTEGER_free(cid->issuer_serial->serial);
880 if (!(cid->issuer_serial->serial =
881 ASN1_INTEGER_dup(cert->cert_info->serialNumber)))
882 goto err;
883 }
884
885 return cid;
886
887err:
888 GENERAL_NAME_free(name);
889 ESS_CERT_ID_free(cid);
890 TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
891 return NULL;
892}
893
894static int
895TS_TST_INFO_content_new(PKCS7 *p7)
896{
897 PKCS7 *ret = NULL;
898 ASN1_OCTET_STRING *octet_string = NULL;
899
900 /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
901 if (!(ret = PKCS7_new()))
902 goto err;
903 if (!(ret->d.other = ASN1_TYPE_new()))
904 goto err;
905 ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
906 if (!(octet_string = ASN1_OCTET_STRING_new()))
907 goto err;
908 ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
909 octet_string = NULL;
910
911 /* Add encapsulated content to signed PKCS7 structure. */
912 if (!PKCS7_set_content(p7, ret))
913 goto err;
914
915 return 1;
916
917err:
918 ASN1_OCTET_STRING_free(octet_string);
919 PKCS7_free(ret);
920 return 0;
921}
922
923static int
924ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
925{
926 ASN1_STRING *seq = NULL;
927 unsigned char *p, *pp = NULL;
928 int len;
929
930 len = i2d_ESS_SIGNING_CERT(sc, NULL);
931 if (!(pp = malloc(len))) {
932 TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
933 goto err;
934 }
935 p = pp;
936 i2d_ESS_SIGNING_CERT(sc, &p);
937 if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) {
938 TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
939 goto err;
940 }
941 free(pp);
942 pp = NULL;
943 return PKCS7_add_signed_attribute(si,
944 NID_id_smime_aa_signingCertificate, V_ASN1_SEQUENCE, seq);
945
946err:
947 ASN1_STRING_free(seq);
948 free(pp);
949
950 return 0;
951}
952
953
954static ASN1_GENERALIZEDTIME *
955TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,
956 time_t sec, long usec, unsigned precision)
957{
958 struct tm *tm = NULL;
959 char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
960 char usecstr[TS_MAX_CLOCK_PRECISION_DIGITS + 2];
961 char *p;
962 int rv;
963
964 if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
965 goto err;
966
967 if (!(tm = gmtime(&sec)))
968 goto err;
969
970 /*
971 * Put "genTime_str" in GeneralizedTime format. We work around the
972 * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST
973 * NOT include fractional seconds") and OpenSSL related functions to
974 * meet the rfc3161 requirement: "GeneralizedTime syntax can include
975 * fraction-of-second details".
976 */
977 if (precision > 0) {
978 /* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides
979 the following restrictions for a DER-encoding, which OpenSSL
980 (specifically ASN1_GENERALIZEDTIME_check() function) doesn't
981 support:
982 "The encoding MUST terminate with a "Z" (which means "Zulu"
983 time). The decimal point element, if present, MUST be the
984 point option ".". The fractional-seconds elements,
985 if present, MUST omit all trailing 0's;
986 if the elements correspond to 0, they MUST be wholly
987 omitted, and the decimal point element also MUST be
988 omitted." */
989 (void) snprintf(usecstr, sizeof(usecstr), ".%06ld", usec);
990 /* truncate and trim trailing 0 */
991 usecstr[precision + 1] = '\0';
992 p = usecstr + strlen(usecstr) - 1;
993 while (p > usecstr && *p == '0')
994 *p-- = '\0';
995 /* if we've reached the beginning, delete the . too */
996 if (p == usecstr)
997 *p = '\0';
998
999 } else {
1000 /* empty */
1001 usecstr[0] = '\0';
1002 }
1003 rv = snprintf(genTime_str, sizeof(genTime_str),
1004 "%04d%02d%02d%02d%02d%02d%sZ",
1005 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1006 tm->tm_hour, tm->tm_min, tm->tm_sec, usecstr);
1007 if (rv == -1 || rv >= sizeof(genTime_str))
1008 goto err;
1009
1010 /* Now call OpenSSL to check and set our genTime value */
1011 if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new()))
1012 goto err;
1013 if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) {
1014 ASN1_GENERALIZEDTIME_free(asn1_time);
1015 goto err;
1016 }
1017
1018 return asn1_time;
1019
1020err:
1021 TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
1022 return NULL;
1023}