ts_rsp_sign.c 32.2 KB
Newer Older
1
/*
P
Pauli 已提交
2
 * Copyright 2006-2017 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9
 */

P
Pauli 已提交
10
#include "e_os.h"
11
#include "internal/cryptlib.h"
12 13 14 15

#include <openssl/objects.h>
#include <openssl/ts.h>
#include <openssl/pkcs7.h>
R
Rich Salz 已提交
16
#include "ts_lcl.h"
17 18 19 20 21

static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);

R
Rich Salz 已提交
22 23 24 25 26
static void ts_RESP_CTX_init(TS_RESP_CTX *ctx);
static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
static int ts_RESP_check_request(TS_RESP_CTX *ctx);
static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx);
static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
27
                                            ASN1_OBJECT *policy);
R
Rich Salz 已提交
28 29
static int ts_RESP_process_extensions(TS_RESP_CTX *ctx);
static int ts_RESP_sign(TS_RESP_CTX *ctx);
30

R
Rich Salz 已提交
31
static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert,
32
                                                   STACK_OF(X509) *certs);
R
Rich Salz 已提交
33 34
static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed);
static int ts_TST_INFO_content_new(PKCS7 *p7);
M
Marek Klein 已提交
35 36 37 38 39 40 41 42 43 44
static int ess_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);

static ESS_SIGNING_CERT_V2 *ess_signing_cert_v2_new_init(const EVP_MD *hash_alg,
                                                         X509 *signcert,
                                                         STACK_OF(X509)
                                                         *certs);
static ESS_CERT_ID_V2 *ess_cert_id_v2_new_init(const EVP_MD *hash_alg,
                                               X509 *cert, int issuer_needed);
static int ess_add_signing_cert_v2(PKCS7_SIGNER_INFO *si,
                                   ESS_SIGNING_CERT_V2 *sc);
45

46 47 48
static ASN1_GENERALIZEDTIME
*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long,
                                    unsigned);
49

50
/* Default callback for response generation. */
51
static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
52 53
{
    ASN1_INTEGER *serial = ASN1_INTEGER_new();
54

55
    if (serial == NULL)
56 57 58 59
        goto err;
    if (!ASN1_INTEGER_set(serial, 1))
        goto err;
    return serial;
60

61
 err:
62 63 64 65 66
    TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                "Error during serial number generation.");
    return NULL;
}
67 68 69

#if defined(OPENSSL_SYS_UNIX)

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
                       long *sec, long *usec)
{
    struct timeval tv;
    if (gettimeofday(&tv, NULL) != 0) {
        TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                    "Time is not available.");
        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
        return 0;
    }
    *sec = tv.tv_sec;
    *usec = tv.tv_usec;

    return 1;
}
86 87 88

#else

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
                       long *sec, long *usec)
{
    time_t t;
    if (time(&t) == (time_t)-1) {
        TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                    "Time is not available.");
        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
        return 0;
    }
    *sec = (long)t;
    *usec = 0;

    return 1;
}
105 106 107 108

#endif

static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
109 110 111 112 113 114 115
                            void *data)
{
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                "Unsupported extension.");
    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
    return 0;
}
116 117 118 119

/* TS_RESP_CTX management functions. */

TS_RESP_CTX *TS_RESP_CTX_new()
120 121
{
    TS_RESP_CTX *ctx;
122

R
Rich Salz 已提交
123
    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
124 125 126
        TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
127

128 129
    ctx->signer_md = EVP_sha256();

130 131 132
    ctx->serial_cb = def_serial_cb;
    ctx->time_cb = def_time_cb;
    ctx->extension_cb = def_extension_cb;
133

134 135
    return ctx;
}
136 137

void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
{
    if (!ctx)
        return;

    X509_free(ctx->signer_cert);
    EVP_PKEY_free(ctx->signer_key);
    sk_X509_pop_free(ctx->certs, X509_free);
    sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
    ASN1_OBJECT_free(ctx->default_policy);
    sk_EVP_MD_free(ctx->mds);   /* No EVP_MD_free method exists. */
    ASN1_INTEGER_free(ctx->seconds);
    ASN1_INTEGER_free(ctx->millis);
    ASN1_INTEGER_free(ctx->micros);
    OPENSSL_free(ctx);
}
153 154

int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
155 156 157 158 159 160
{
    if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) {
        TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT,
              TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
        return 0;
    }
R
Rich Salz 已提交
161
    X509_free(ctx->signer_cert);
162
    ctx->signer_cert = signer;
D
Dr. Stephen Henson 已提交
163
    X509_up_ref(ctx->signer_cert);
164 165
    return 1;
}
166 167

int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
168
{
R
Rich Salz 已提交
169
    EVP_PKEY_free(ctx->signer_key);
170
    ctx->signer_key = key;
D
Dr. Stephen Henson 已提交
171
    EVP_PKEY_up_ref(ctx->signer_key);
172

173 174
    return 1;
}
175

176 177 178 179 180 181
int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, const EVP_MD *md)
{
    ctx->signer_md = md;
    return 1;
}

182
int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy)
183
{
R
Rich Salz 已提交
184
    ASN1_OBJECT_free(ctx->default_policy);
185
    if ((ctx->default_policy = OBJ_dup(def_policy)) == NULL)
186 187
        goto err;
    return 1;
188
 err:
189 190 191
    TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
    return 0;
}
192 193

int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
194 195
{

R
Rich Salz 已提交
196 197
    sk_X509_pop_free(ctx->certs, X509_free);
    ctx->certs = NULL;
198 199
    if (!certs)
        return 1;
200
    if ((ctx->certs = X509_chain_up_ref(certs)) == NULL) {
201 202 203 204 205 206
        TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    return 1;
}
207

208
int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy)
209 210 211
{
    ASN1_OBJECT *copy = NULL;

212 213
    if (ctx->policies == NULL
        && (ctx->policies = sk_ASN1_OBJECT_new_null()) == NULL)
214
        goto err;
215
    if ((copy = OBJ_dup(policy)) == NULL)
216 217 218 219 220
        goto err;
    if (!sk_ASN1_OBJECT_push(ctx->policies, copy))
        goto err;

    return 1;
221
 err:
222 223 224 225
    TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
    ASN1_OBJECT_free(copy);
    return 0;
}
226 227

int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
228
{
229 230
    if (ctx->mds == NULL
        && (ctx->mds = sk_EVP_MD_new_null()) == NULL)
231
        goto err;
232
    if (!sk_EVP_MD_push(ctx->mds, md))
233 234 235
        goto err;

    return 1;
236
 err:
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
    TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
    return 0;
}

#define TS_RESP_CTX_accuracy_free(ctx)          \
        ASN1_INTEGER_free(ctx->seconds);        \
        ctx->seconds = NULL;                    \
        ASN1_INTEGER_free(ctx->millis);         \
        ctx->millis = NULL;                     \
        ASN1_INTEGER_free(ctx->micros);         \
        ctx->micros = NULL;

int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
                             int secs, int millis, int micros)
{

    TS_RESP_CTX_accuracy_free(ctx);
254 255 256
    if (secs
        && ((ctx->seconds = ASN1_INTEGER_new()) == NULL
            || !ASN1_INTEGER_set(ctx->seconds, secs)))
257
        goto err;
258 259 260
    if (millis
        && ((ctx->millis = ASN1_INTEGER_new()) == NULL
            || !ASN1_INTEGER_set(ctx->millis, millis)))
261
        goto err;
262 263 264
    if (micros
        && ((ctx->micros = ASN1_INTEGER_new()) == NULL
            || !ASN1_INTEGER_set(ctx->micros, micros)))
265 266 267
        goto err;

    return 1;
268
 err:
269 270 271 272
    TS_RESP_CTX_accuracy_free(ctx);
    TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
    return 0;
}
273 274

void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
275 276 277
{
    ctx->flags |= flags;
}
278 279

void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
280 281 282 283
{
    ctx->serial_cb = cb;
    ctx->serial_cb_data = data;
}
284 285

void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
{
    ctx->time_cb = cb;
    ctx->time_cb_data = data;
}

void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
                                  TS_extension_cb cb, void *data)
{
    ctx->extension_cb = cb;
    ctx->extension_cb_data = data;
}

int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
                                int status, const char *text)
{
    TS_STATUS_INFO *si = NULL;
    ASN1_UTF8STRING *utf8_text = NULL;
    int ret = 0;

305
    if ((si = TS_STATUS_INFO_new()) == NULL)
306 307 308 309
        goto err;
    if (!ASN1_INTEGER_set(si->status, status))
        goto err;
    if (text) {
310
        if ((utf8_text = ASN1_UTF8STRING_new()) == NULL
311 312
            || !ASN1_STRING_set(utf8_text, text, strlen(text)))
            goto err;
313 314
        if (si->text == NULL
            && (si->text = sk_ASN1_UTF8STRING_new_null()) == NULL)
315 316 317 318 319 320 321 322
            goto err;
        if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text))
            goto err;
        utf8_text = NULL;       /* Ownership is lost. */
    }
    if (!TS_RESP_set_status_info(ctx->response, si))
        goto err;
    ret = 1;
323
 err:
324 325 326 327 328 329 330 331 332 333 334
    if (!ret)
        TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
    TS_STATUS_INFO_free(si);
    ASN1_UTF8STRING_free(utf8_text);
    return ret;
}

int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
                                     int status, const char *text)
{
    int ret = 1;
R
Rich Salz 已提交
335
    TS_STATUS_INFO *si = ctx->response->status_info;
336 337 338 339 340 341

    if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) {
        ret = TS_RESP_CTX_set_status_info(ctx, status, text);
    }
    return ret;
}
342 343

int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
344
{
R
Rich Salz 已提交
345
    TS_STATUS_INFO *si = ctx->response->status_info;
346 347
    if (si->failure_info == NULL
        && (si->failure_info = ASN1_BIT_STRING_new()) == NULL)
348 349 350 351
        goto err;
    if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
        goto err;
    return 1;
352
 err:
353 354 355
    TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
    return 0;
}
356 357

TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
358 359 360
{
    return ctx->request;
}
361 362

TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
363 364 365 366 367 368 369 370 371 372 373 374
{
    return ctx->tst_info;
}

int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
                                           unsigned precision)
{
    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
        return 0;
    ctx->clock_precision_digits = precision;
    return 1;
}
375 376 377

/* Main entry method of the response generation. */
TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
378 379 380 381 382
{
    ASN1_OBJECT *policy;
    TS_RESP *response;
    int result = 0;

R
Rich Salz 已提交
383
    ts_RESP_CTX_init(ctx);
384

385
    if ((ctx->response = TS_RESP_new()) == NULL) {
386 387 388
        TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
        goto end;
    }
389
    if ((ctx->request = d2i_TS_REQ_bio(req_bio, NULL)) == NULL) {
390
        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
391
                                    "Bad request format or system error.");
392 393 394 395 396
        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
        goto end;
    }
    if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
        goto end;
R
Rich Salz 已提交
397
    if (!ts_RESP_check_request(ctx))
398
        goto end;
R
Rich Salz 已提交
399
    if ((policy = ts_RESP_get_policy(ctx)) == NULL)
400
        goto end;
R
Rich Salz 已提交
401
    if ((ctx->tst_info = ts_RESP_create_tst_info(ctx, policy)) == NULL)
402
        goto end;
R
Rich Salz 已提交
403
    if (!ts_RESP_process_extensions(ctx))
404
        goto end;
R
Rich Salz 已提交
405
    if (!ts_RESP_sign(ctx))
406 407
        goto end;
    result = 1;
408

409
 end:
410 411 412 413 414 415 416 417 418 419 420 421 422 423
    if (!result) {
        TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
        if (ctx->response != NULL) {
            if (TS_RESP_CTX_set_status_info_cond(ctx,
                                                 TS_STATUS_REJECTION,
                                                 "Error during response "
                                                 "generation.") == 0) {
                TS_RESP_free(ctx->response);
                ctx->response = NULL;
            }
        }
    }
    response = ctx->response;
    ctx->response = NULL;       /* Ownership will be returned to caller. */
R
Rich Salz 已提交
424
    ts_RESP_CTX_cleanup(ctx);
425 426
    return response;
}
427 428

/* Initializes the variable part of the context. */
R
Rich Salz 已提交
429
static void ts_RESP_CTX_init(TS_RESP_CTX *ctx)
430 431 432 433 434
{
    ctx->request = NULL;
    ctx->response = NULL;
    ctx->tst_info = NULL;
}
435 436

/* Cleans up the variable part of the context. */
R
Rich Salz 已提交
437
static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
438 439 440 441 442 443 444 445
{
    TS_REQ_free(ctx->request);
    ctx->request = NULL;
    TS_RESP_free(ctx->response);
    ctx->response = NULL;
    TS_TST_INFO_free(ctx->tst_info);
    ctx->tst_info = NULL;
}
446 447

/* Checks the format and content of the request. */
R
Rich Salz 已提交
448
static int ts_RESP_check_request(TS_RESP_CTX *ctx)
449 450 451 452 453 454
{
    TS_REQ *request = ctx->request;
    TS_MSG_IMPRINT *msg_imprint;
    X509_ALGOR *md_alg;
    int md_alg_id;
    const ASN1_OCTET_STRING *digest;
455
    const EVP_MD *md = NULL;
456 457 458 459 460 461 462 463 464
    int i;

    if (TS_REQ_get_version(request) != 1) {
        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                    "Bad request version.");
        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
        return 0;
    }

R
Rich Salz 已提交
465 466
    msg_imprint = request->msg_imprint;
    md_alg = msg_imprint->hash_algo;
467 468
    md_alg_id = OBJ_obj2nid(md_alg->algorithm);
    for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) {
469
        const EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
        if (md_alg_id == EVP_MD_type(current_md))
            md = current_md;
    }
    if (!md) {
        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                    "Message digest algorithm is "
                                    "not supported.");
        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
        return 0;
    }

    if (md_alg->parameter && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) {
        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                    "Superfluous message digest "
                                    "parameter.");
        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
        return 0;
    }
R
Rich Salz 已提交
488
    digest = msg_imprint->hashed_msg;
489 490 491 492 493 494 495 496 497
    if (digest->length != EVP_MD_size(md)) {
        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                    "Bad message digest.");
        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
        return 0;
    }

    return 1;
}
498

499
/* Returns the TSA policy based on the requested and acceptable policies. */
R
Rich Salz 已提交
500
static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx)
501
{
R
Rich Salz 已提交
502
    ASN1_OBJECT *requested = ctx->request->policy_id;
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
    ASN1_OBJECT *policy = NULL;
    int i;

    if (ctx->default_policy == NULL) {
        TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
        return NULL;
    }
    if (!requested || !OBJ_cmp(requested, ctx->default_policy))
        policy = ctx->default_policy;

    /* Check if the policy is acceptable. */
    for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) {
        ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
        if (!OBJ_cmp(requested, current))
            policy = current;
    }
    if (!policy) {
        TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                    "Requested policy is not " "supported.");
        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
    }
    return policy;
}
527 528

/* Creates the TS_TST_INFO object based on the settings of the context. */
R
Rich Salz 已提交
529
static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
530 531 532 533 534 535 536 537 538 539 540
                                            ASN1_OBJECT *policy)
{
    int result = 0;
    TS_TST_INFO *tst_info = NULL;
    ASN1_INTEGER *serial = NULL;
    ASN1_GENERALIZEDTIME *asn1_time = NULL;
    long sec, usec;
    TS_ACCURACY *accuracy = NULL;
    const ASN1_INTEGER *nonce;
    GENERAL_NAME *tsa_name = NULL;

541
    if ((tst_info = TS_TST_INFO_new()) == NULL)
542 543 544 545 546 547 548
        goto end;
    if (!TS_TST_INFO_set_version(tst_info, 1))
        goto end;
    if (!TS_TST_INFO_set_policy_id(tst_info, policy))
        goto end;
    if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
        goto end;
549
    if ((serial = ctx->serial_cb(ctx, ctx->serial_cb_data)) == NULL
550 551
        || !TS_TST_INFO_set_serial(tst_info, serial))
        goto end;
552 553 554 555
    if (!ctx->time_cb(ctx, ctx->time_cb_data, &sec, &usec)
        || (asn1_time =
            TS_RESP_set_genTime_with_precision(NULL, sec, usec,
                                        ctx->clock_precision_digits)) == NULL
556 557 558 559
        || !TS_TST_INFO_set_time(tst_info, asn1_time))
        goto end;

    if ((ctx->seconds || ctx->millis || ctx->micros)
560
        && (accuracy = TS_ACCURACY_new()) == NULL)
561 562 563 564 565 566 567 568 569 570 571 572 573 574
        goto end;
    if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
        goto end;
    if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
        goto end;
    if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
        goto end;
    if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))
        goto end;

    if ((ctx->flags & TS_ORDERING)
        && !TS_TST_INFO_set_ordering(tst_info, 1))
        goto end;

R
Rich Salz 已提交
575
    if ((nonce = ctx->request->nonce) != NULL
576 577 578 579
        && !TS_TST_INFO_set_nonce(tst_info, nonce))
        goto end;

    if (ctx->flags & TS_TSA_NAME) {
580
        if ((tsa_name = GENERAL_NAME_new()) == NULL)
581 582 583
            goto end;
        tsa_name->type = GEN_DIRNAME;
        tsa_name->d.dirn =
584
            X509_NAME_dup(X509_get_subject_name(ctx->signer_cert));
585 586 587 588 589 590 591
        if (!tsa_name->d.dirn)
            goto end;
        if (!TS_TST_INFO_set_tsa(tst_info, tsa_name))
            goto end;
    }

    result = 1;
592
 end:
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
    if (!result) {
        TS_TST_INFO_free(tst_info);
        tst_info = NULL;
        TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
        TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
                                         "Error during TSTInfo "
                                         "generation.");
    }
    GENERAL_NAME_free(tsa_name);
    TS_ACCURACY_free(accuracy);
    ASN1_GENERALIZEDTIME_free(asn1_time);
    ASN1_INTEGER_free(serial);

    return tst_info;
}
608 609

/* Processing the extensions of the request. */
R
Rich Salz 已提交
610
static int ts_RESP_process_extensions(TS_RESP_CTX *ctx)
611
{
R
Rich Salz 已提交
612
    STACK_OF(X509_EXTENSION) *exts = ctx->request->extensions;
613 614 615 616 617 618
    int i;
    int ok = 1;

    for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) {
        X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
        /*
619
         * The last argument was previously (void *)ctx->extension_cb,
620 621 622 623 624 625 626 627 628
         * but ISO C doesn't permit converting a function pointer to void *.
         * For lack of better information, I'm placing a NULL there instead.
         * The callback can pick its own address out from the ctx anyway...
         */
        ok = (*ctx->extension_cb) (ctx, ext, NULL);
    }

    return ok;
}
629 630

/* Functions for signing the TS_TST_INFO structure of the context. */
R
Rich Salz 已提交
631
static int ts_RESP_sign(TS_RESP_CTX *ctx)
632 633 634 635 636
{
    int ret = 0;
    PKCS7 *p7 = NULL;
    PKCS7_SIGNER_INFO *si;
    STACK_OF(X509) *certs;      /* Certificates to include in sc. */
M
Marek Klein 已提交
637
    ESS_SIGNING_CERT_V2 *sc2 = NULL;
638 639 640 641 642 643 644 645 646 647
    ESS_SIGNING_CERT *sc = NULL;
    ASN1_OBJECT *oid;
    BIO *p7bio = NULL;
    int i;

    if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
        TSerr(TS_F_TS_RESP_SIGN, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
        goto err;
    }

648
    if ((p7 = PKCS7_new()) == NULL) {
649 650 651 652 653 654 655 656
        TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (!PKCS7_set_type(p7, NID_pkcs7_signed))
        goto err;
    if (!ASN1_INTEGER_set(p7->d.sign->version, 3))
        goto err;

R
Rich Salz 已提交
657
    if (ctx->request->cert_req) {
658 659 660 661 662 663 664 665 666
        PKCS7_add_certificate(p7, ctx->signer_cert);
        if (ctx->certs) {
            for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
                X509 *cert = sk_X509_value(ctx->certs, i);
                PKCS7_add_certificate(p7, cert);
            }
        }
    }

667
    if ((si = PKCS7_add_signature(p7, ctx->signer_cert,
668
                                  ctx->signer_key, ctx->signer_md)) == NULL) {
669 670 671 672 673 674 675 676 677 678 679 680
        TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
        goto err;
    }

    oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
    if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
                                    V_ASN1_OBJECT, oid)) {
        TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
        goto err;
    }

    certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
681 682
    if (ctx->ess_cert_id_digest == NULL
        || ctx->ess_cert_id_digest == EVP_sha1()) {
M
Marek Klein 已提交
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
        if ((sc = ess_SIGNING_CERT_new_init(ctx->signer_cert, certs)) == NULL)
            goto err;

        if (!ess_add_signing_cert(si, sc)) {
            TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
            goto err;
        }
    } else {
        sc2 = ess_signing_cert_v2_new_init(ctx->ess_cert_id_digest,
                                           ctx->signer_cert, certs);
        if (sc2 == NULL)
            goto err;

        if (!ess_add_signing_cert_v2(si, sc2)) {
            TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR);
            goto err;
        }
700 701
    }

R
Rich Salz 已提交
702
    if (!ts_TST_INFO_content_new(p7))
703
        goto err;
704
    if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
        TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) {
        TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
        goto err;
    }
    if (!PKCS7_dataFinal(p7, p7bio)) {
        TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
        goto err;
    }
    TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
    p7 = NULL;                  /* Ownership is lost. */
    ctx->tst_info = NULL;       /* Ownership is lost. */

    ret = 1;
721
 err:
722 723 724 725 726
    if (!ret)
        TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
                                         "Error during signature "
                                         "generation.");
    BIO_free_all(p7bio);
M
Marek Klein 已提交
727
    ESS_SIGNING_CERT_V2_free(sc2);
728 729 730 731 732
    ESS_SIGNING_CERT_free(sc);
    PKCS7_free(p7);
    return ret;
}

R
Rich Salz 已提交
733
static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert,
734 735 736 737 738 739
                                                   STACK_OF(X509) *certs)
{
    ESS_CERT_ID *cid;
    ESS_SIGNING_CERT *sc = NULL;
    int i;

740
    if ((sc = ESS_SIGNING_CERT_new()) == NULL)
741
        goto err;
742 743
    if (sc->cert_ids == NULL
        && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL)
744 745
        goto err;

R
Rich Salz 已提交
746
    if ((cid = ess_CERT_ID_new_init(signcert, 0)) == NULL
747 748 749 750
        || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
        goto err;
    for (i = 0; i < sk_X509_num(certs); ++i) {
        X509 *cert = sk_X509_value(certs, i);
R
Rich Salz 已提交
751
        if ((cid = ess_CERT_ID_new_init(cert, 1)) == NULL
752 753 754 755 756 757 758 759 760 761
            || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
            goto err;
    }

    return sc;
 err:
    ESS_SIGNING_CERT_free(sc);
    TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
    return NULL;
}
762

R
Rich Salz 已提交
763
static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed)
764 765 766
{
    ESS_CERT_ID *cid = NULL;
    GENERAL_NAME *name = NULL;
767
    unsigned char cert_sha1[SHA_DIGEST_LENGTH];
768

769
    /* Call for side-effect of computing hash and caching extensions */
770
    X509_check_purpose(cert, -1, 0);
771
    if ((cid = ESS_CERT_ID_new()) == NULL)
772
        goto err;
773 774
    X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
    if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
775 776 777 778
        goto err;

    /* Setting the issuer/serial if requested. */
    if (issuer_needed) {
779 780
        if (cid->issuer_serial == NULL
            && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL)
781
            goto err;
782
        if ((name = GENERAL_NAME_new()) == NULL)
783 784
            goto err;
        name->type = GEN_DIRNAME;
785
        if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL)
786 787 788 789 790 791
            goto err;
        if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
            goto err;
        name = NULL;            /* Ownership is lost. */
        ASN1_INTEGER_free(cid->issuer_serial->serial);
        if (!(cid->issuer_serial->serial =
792
              ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
793 794 795 796 797 798 799 800 801 802
            goto err;
    }

    return cid;
 err:
    GENERAL_NAME_free(name);
    ESS_CERT_ID_free(cid);
    TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
    return NULL;
}
803

R
Rich Salz 已提交
804
static int ts_TST_INFO_content_new(PKCS7 *p7)
805 806 807 808 809
{
    PKCS7 *ret = NULL;
    ASN1_OCTET_STRING *octet_string = NULL;

    /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
810
    if ((ret = PKCS7_new()) == NULL)
811
        goto err;
812
    if ((ret->d.other = ASN1_TYPE_new()) == NULL)
813 814
        goto err;
    ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
815
    if ((octet_string = ASN1_OCTET_STRING_new()) == NULL)
816 817 818 819 820 821 822 823 824
        goto err;
    ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
    octet_string = NULL;

    /* Add encapsulated content to signed PKCS7 structure. */
    if (!PKCS7_set_content(p7, ret))
        goto err;

    return 1;
825
 err:
826 827 828 829
    ASN1_OCTET_STRING_free(octet_string);
    PKCS7_free(ret);
    return 0;
}
830

M
Marek Klein 已提交
831
static int ess_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
832 833 834 835 836 837
{
    ASN1_STRING *seq = NULL;
    unsigned char *p, *pp = NULL;
    int len;

    len = i2d_ESS_SIGNING_CERT(sc, NULL);
838
    if ((pp = OPENSSL_malloc(len)) == NULL) {
839 840 841 842 843
        TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    p = pp;
    i2d_ESS_SIGNING_CERT(sc, &p);
844
    if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
845 846 847 848 849 850 851 852
        TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    OPENSSL_free(pp);
    pp = NULL;
    return PKCS7_add_signed_attribute(si,
                                      NID_id_smime_aa_signingCertificate,
                                      V_ASN1_SEQUENCE, seq);
853
 err:
854 855 856 857 858 859
    ASN1_STRING_free(seq);
    OPENSSL_free(pp);

    return 0;
}

M
Marek Klein 已提交
860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986
static ESS_SIGNING_CERT_V2 *ess_signing_cert_v2_new_init(const EVP_MD *hash_alg,
                                                         X509 *signcert,
                                                         STACK_OF(X509) *certs)
{
    ESS_CERT_ID_V2 *cid = NULL;
    ESS_SIGNING_CERT_V2 *sc = NULL;
    int i;

    if ((sc = ESS_SIGNING_CERT_V2_new()) == NULL)
        goto err;
    if ((cid = ess_cert_id_v2_new_init(hash_alg, signcert, 0)) == NULL)
        goto err;
    if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid))
        goto err;
    cid = NULL;

    for (i = 0; i < sk_X509_num(certs); ++i) {
        X509 *cert = sk_X509_value(certs, i);

        if ((cid = ess_cert_id_v2_new_init(hash_alg, cert, 1)) == NULL)
            goto err;
        if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid))
            goto err;
        cid = NULL;
    }

    return sc;
 err:
    ESS_SIGNING_CERT_V2_free(sc);
    ESS_CERT_ID_V2_free(cid);
    TSerr(TS_F_ESS_SIGNING_CERT_V2_NEW_INIT, ERR_R_MALLOC_FAILURE);
    return NULL;
}

static ESS_CERT_ID_V2 *ess_cert_id_v2_new_init(const EVP_MD *hash_alg,
                                               X509 *cert, int issuer_needed)
{
    ESS_CERT_ID_V2 *cid = NULL;
    GENERAL_NAME *name = NULL;
    unsigned char hash[EVP_MAX_MD_SIZE];
    unsigned int hash_len = sizeof(hash);
    X509_ALGOR *alg = NULL;

    memset(hash, 0, sizeof(hash));

    if ((cid = ESS_CERT_ID_V2_new()) == NULL)
        goto err;

    if (hash_alg != EVP_sha256()) {
        alg = X509_ALGOR_new();
        if (alg == NULL)
            goto err;
        X509_ALGOR_set_md(alg, hash_alg);
        if (alg->algorithm == NULL)
            goto err;
        cid->hash_alg = alg;
        alg = NULL;
    } else {
        cid->hash_alg = NULL;
    }

    if (!X509_digest(cert, hash_alg, hash, &hash_len))
        goto err;

    if (!ASN1_OCTET_STRING_set(cid->hash, hash, hash_len))
        goto err;

    if (issuer_needed) {
        if ((cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL)
            goto err;
        if ((name = GENERAL_NAME_new()) == NULL)
            goto err;
        name->type = GEN_DIRNAME;
        if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL)
            goto err;
        if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
            goto err;
        name = NULL;            /* Ownership is lost. */
        ASN1_INTEGER_free(cid->issuer_serial->serial);
        cid->issuer_serial->serial =
                ASN1_INTEGER_dup(X509_get_serialNumber(cert));
        if (cid->issuer_serial->serial == NULL)
            goto err;
    }

    return cid;
 err:
    X509_ALGOR_free(alg);
    GENERAL_NAME_free(name);
    ESS_CERT_ID_V2_free(cid);
    TSerr(TS_F_ESS_CERT_ID_V2_NEW_INIT, ERR_R_MALLOC_FAILURE);
    return NULL;
}

static int ess_add_signing_cert_v2(PKCS7_SIGNER_INFO *si,
                                   ESS_SIGNING_CERT_V2 *sc)
{
    ASN1_STRING *seq = NULL;
    unsigned char *p, *pp = NULL;
    int len = i2d_ESS_SIGNING_CERT_V2(sc, NULL);

    if ((pp = OPENSSL_malloc(len)) == NULL) {
        TSerr(TS_F_ESS_ADD_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    p = pp;
    i2d_ESS_SIGNING_CERT_V2(sc, &p);
    if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
        TSerr(TS_F_ESS_ADD_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    OPENSSL_free(pp);
    pp = NULL;
    return PKCS7_add_signed_attribute(si,
                                      NID_id_smime_aa_signingCertificateV2,
                                      V_ASN1_SEQUENCE, seq);
 err:
    ASN1_STRING_free(seq);
    OPENSSL_free(pp);
    return 0;
}

static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
        ASN1_GENERALIZEDTIME *asn1_time, long sec, long usec,
        unsigned precision)
987 988 989 990 991 992 993 994 995 996
{
    time_t time_sec = (time_t)sec;
    struct tm *tm = NULL;
    char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
    char *p = genTime_str;
    char *p_end = genTime_str + sizeof(genTime_str);

    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
        goto err;

997
    if ((tm = gmtime(&time_sec)) == NULL)
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030
        goto err;

    /*
     * Put "genTime_str" in GeneralizedTime format.  We work around the
     * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST
     * NOT include fractional seconds") and OpenSSL related functions to
     * meet the rfc3161 requirement: "GeneralizedTime syntax can include
     * fraction-of-second details".
     */
    p += BIO_snprintf(p, p_end - p,
                      "%04d%02d%02d%02d%02d%02d",
                      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
                      tm->tm_hour, tm->tm_min, tm->tm_sec);
    if (precision > 0) {
        BIO_snprintf(p, 2 + precision, ".%06ld", usec);
        p += strlen(p);

        /*
         * To make things a bit harder, X.690 | ISO/IEC 8825-1 provides the
         * following restrictions for a DER-encoding, which OpenSSL
         * (specifically ASN1_GENERALIZEDTIME_check() function) doesn't
         * support: "The encoding MUST terminate with a "Z" (which means
         * "Zulu" time). The decimal point element, if present, MUST be the
         * point option ".". The fractional-seconds elements, if present,
         * MUST omit all trailing 0's; if the elements correspond to 0, they
         * MUST be wholly omitted, and the decimal point element also MUST be
         * omitted."
         */
        /*
         * Remove trailing zeros. The dot guarantees the exit condition of
         * this loop even if all the digits are zero.
         */
        while (*--p == '0')
1031
             continue;
1032 1033 1034 1035 1036 1037
        if (*p != '.')
            ++p;
    }
    *p++ = 'Z';
    *p++ = '\0';

1038 1039
    if (asn1_time == NULL
        && (asn1_time = ASN1_GENERALIZEDTIME_new()) == NULL)
1040 1041 1042 1043 1044 1045
        goto err;
    if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) {
        ASN1_GENERALIZEDTIME_free(asn1_time);
        goto err;
    }
    return asn1_time;
1046

1047
 err:
1048 1049 1050
    TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
    return NULL;
}
M
Marek Klein 已提交
1051 1052 1053 1054 1055 1056

int TS_RESP_CTX_set_ess_cert_id_digest(TS_RESP_CTX *ctx, const EVP_MD *md)
{
    ctx->ess_cert_id_digest = md;
    return 1;
}