X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fts%2Fts_rsp_sign.c;h=7791fc73c896ddac2c734bf535a79d70a1171656;hp=2d1e4388331d3998cafbadd2b58b6ad3f0174131;hb=e85d19c68e7fb3302410bd72d434793e5c0c23a0;hpb=b4faea50c35d92a67d1369355b49cc3efba78406 diff --git a/crypto/ts/ts_rsp_sign.c b/crypto/ts/ts_rsp_sign.c index 2d1e438833..7791fc73c8 100644 --- a/crypto/ts/ts_rsp_sign.c +++ b/crypto/ts/ts_rsp_sign.c @@ -1,107 +1,52 @@ -/* crypto/ts/ts_resp_sign.c */ /* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). + * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. * + * Licensed under the Apache License 2.0 (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 */ -#include "cryptlib.h" - -#if defined(OPENSSL_SYS_UNIX) -# include -#endif +#include "e_os.h" +#include "internal/cryptlib.h" #include #include #include - -/* Private function declarations. */ +#include +#include "ts_lcl.h" +#include "internal/ess_int.h" 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 *); -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, +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, ASN1_OBJECT *policy); -static int TS_RESP_process_extensions(TS_RESP_CTX *ctx); -static int TS_RESP_sign(TS_RESP_CTX *ctx); +static int ts_RESP_process_extensions(TS_RESP_CTX *ctx); +static int ts_RESP_sign(TS_RESP_CTX *ctx); -static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, - STACK_OF(X509) *certs); -static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed); -static int TS_TST_INFO_content_new(PKCS7 *p7); -static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); +static int ts_TST_INFO_content_new(PKCS7 *p7); static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long, unsigned); -/* Default callbacks for response generation. */ - +/* Default callback for response generation. */ static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) { ASN1_INTEGER *serial = ASN1_INTEGER_new(); - if (!serial) + + if (serial == NULL) goto err; if (!ASN1_INTEGER_set(serial, 1)) goto err; return serial; + err: TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE); TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, @@ -111,7 +56,6 @@ static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) #if defined(OPENSSL_SYS_UNIX) -/* Use the gettimeofday function call. */ static int def_time_cb(struct TS_resp_ctx *ctx, void *data, long *sec, long *usec) { @@ -123,7 +67,6 @@ static int def_time_cb(struct TS_resp_ctx *ctx, void *data, TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); return 0; } - /* Return time to caller. */ *sec = tv.tv_sec; *usec = tv.tv_usec; @@ -132,7 +75,6 @@ static int def_time_cb(struct TS_resp_ctx *ctx, void *data, #else -/* Use the time function call that provides only seconds precision. */ static int def_time_cb(struct TS_resp_ctx *ctx, void *data, long *sec, long *usec) { @@ -144,7 +86,6 @@ static int def_time_cb(struct TS_resp_ctx *ctx, void *data, TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); return 0; } - /* Return time to caller, only second precision. */ *sec = (long)t; *usec = 0; @@ -156,7 +97,6 @@ static int def_time_cb(struct TS_resp_ctx *ctx, void *data, static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, void *data) { - /* No extensions are processed here. */ TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Unsupported extension."); TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION); @@ -165,17 +105,17 @@ static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, /* TS_RESP_CTX management functions. */ -TS_RESP_CTX *TS_RESP_CTX_new() +TS_RESP_CTX *TS_RESP_CTX_new(void) { TS_RESP_CTX *ctx; - if (!(ctx = OPENSSL_malloc(sizeof(*ctx)))) { + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE); return NULL; } - memset(ctx, 0, sizeof(TS_RESP_CTX)); - /* Setting default callbacks. */ + ctx->signer_md = EVP_sha256(); + ctx->serial_cb = def_serial_cb; ctx->time_cb = def_time_cb; ctx->extension_cb = def_extension_cb; @@ -209,7 +149,7 @@ int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) } X509_free(ctx->signer_cert); ctx->signer_cert = signer; - CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509); + X509_up_ref(ctx->signer_cert); return 1; } @@ -217,15 +157,21 @@ int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key) { EVP_PKEY_free(ctx->signer_key); ctx->signer_key = key; - CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY); + EVP_PKEY_up_ref(ctx->signer_key); return 1; } -int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy) +int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, const EVP_MD *md) +{ + ctx->signer_md = md; + return 1; +} + +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy) { ASN1_OBJECT_free(ctx->default_policy); - if (!(ctx->default_policy = OBJ_dup(def_policy))) + if ((ctx->default_policy = OBJ_dup(def_policy)) == NULL) goto err; return 1; err: @@ -240,7 +186,7 @@ int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) ctx->certs = NULL; if (!certs) return 1; - if (!(ctx->certs = X509_chain_up_ref(certs))) { + if ((ctx->certs = X509_chain_up_ref(certs)) == NULL) { TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE); return 0; } @@ -248,14 +194,14 @@ int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) return 1; } -int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy) +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy) { ASN1_OBJECT *copy = NULL; - /* Create new policy stack if necessary. */ - if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) + if (ctx->policies == NULL + && (ctx->policies = sk_ASN1_OBJECT_new_null()) == NULL) goto err; - if (!(copy = OBJ_dup(policy))) + if ((copy = OBJ_dup(policy)) == NULL) goto err; if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) goto err; @@ -269,11 +215,10 @@ int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy) int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md) { - /* Create new md stack if necessary. */ - if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) + if (ctx->mds == NULL + && (ctx->mds = sk_EVP_MD_new_null()) == NULL) goto err; - /* Add the shared md, no copy needed. */ - if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) + if (!sk_EVP_MD_push(ctx->mds, md)) goto err; return 1; @@ -295,14 +240,17 @@ int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, { TS_RESP_CTX_accuracy_free(ctx); - if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) - || !ASN1_INTEGER_set(ctx->seconds, secs))) + if (secs + && ((ctx->seconds = ASN1_INTEGER_new()) == NULL + || !ASN1_INTEGER_set(ctx->seconds, secs))) goto err; - if (millis && (!(ctx->millis = ASN1_INTEGER_new()) - || !ASN1_INTEGER_set(ctx->millis, millis))) + if (millis + && ((ctx->millis = ASN1_INTEGER_new()) == NULL + || !ASN1_INTEGER_set(ctx->millis, millis))) goto err; - if (micros && (!(ctx->micros = ASN1_INTEGER_new()) - || !ASN1_INTEGER_set(ctx->micros, micros))) + if (micros + && ((ctx->micros = ASN1_INTEGER_new()) == NULL + || !ASN1_INTEGER_set(ctx->micros, micros))) goto err; return 1; @@ -343,15 +291,16 @@ int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, ASN1_UTF8STRING *utf8_text = NULL; int ret = 0; - if (!(si = TS_STATUS_INFO_new())) + if ((si = TS_STATUS_INFO_new()) == NULL) goto err; if (!ASN1_INTEGER_set(si->status, status)) goto err; if (text) { - if (!(utf8_text = ASN1_UTF8STRING_new()) + if ((utf8_text = ASN1_UTF8STRING_new()) == NULL || !ASN1_STRING_set(utf8_text, text, strlen(text))) goto err; - if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null())) + if (si->text == NULL + && (si->text = sk_ASN1_UTF8STRING_new_null()) == NULL) goto err; if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) goto err; @@ -372,10 +321,9 @@ int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, int status, const char *text) { int ret = 1; - TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); + TS_STATUS_INFO *si = ctx->response->status_info; if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) { - /* Status has not been set, set it now. */ ret = TS_RESP_CTX_set_status_info(ctx, status, text); } return ret; @@ -383,8 +331,9 @@ int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure) { - TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); - if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new())) + TS_STATUS_INFO *si = ctx->response->status_info; + if (si->failure_info == NULL + && (si->failure_info = ASN1_BIT_STRING_new()) == NULL) goto err; if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1)) goto err; @@ -420,48 +369,32 @@ TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) TS_RESP *response; int result = 0; - TS_RESP_CTX_init(ctx); + ts_RESP_CTX_init(ctx); - /* Creating the response object. */ - if (!(ctx->response = TS_RESP_new())) { + if ((ctx->response = TS_RESP_new()) == NULL) { TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE); goto end; } - - /* Parsing DER request. */ - if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) { + if ((ctx->request = d2i_TS_REQ_bio(req_bio, NULL)) == NULL) { TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Bad request format or " "system error."); + "Bad request format or system error."); TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); goto end; } - - /* Setting default status info. */ if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL)) goto end; - - /* Checking the request format. */ - if (!TS_RESP_check_request(ctx)) + if (!ts_RESP_check_request(ctx)) goto end; - - /* Checking acceptable policies. */ - if (!(policy = TS_RESP_get_policy(ctx))) + if ((policy = ts_RESP_get_policy(ctx)) == NULL) goto end; - - /* Creating the TS_TST_INFO object. */ - if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy))) + if ((ctx->tst_info = ts_RESP_create_tst_info(ctx, policy)) == NULL) goto end; - - /* Processing extensions. */ - if (!TS_RESP_process_extensions(ctx)) + if (!ts_RESP_process_extensions(ctx)) goto end; - - /* Generating the signature. */ - if (!TS_RESP_sign(ctx)) + if (!ts_RESP_sign(ctx)) goto end; - - /* Everything was successful. */ result = 1; + end: if (!result) { TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR); @@ -477,12 +410,12 @@ TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) } response = ctx->response; ctx->response = NULL; /* Ownership will be returned to caller. */ - TS_RESP_CTX_cleanup(ctx); + ts_RESP_CTX_cleanup(ctx); return response; } /* Initializes the variable part of the context. */ -static void TS_RESP_CTX_init(TS_RESP_CTX *ctx) +static void ts_RESP_CTX_init(TS_RESP_CTX *ctx) { ctx->request = NULL; ctx->response = NULL; @@ -490,7 +423,7 @@ static void TS_RESP_CTX_init(TS_RESP_CTX *ctx) } /* Cleans up the variable part of the context. */ -static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx) +static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx) { TS_REQ_free(ctx->request); ctx->request = NULL; @@ -501,17 +434,16 @@ static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx) } /* Checks the format and content of the request. */ -static int TS_RESP_check_request(TS_RESP_CTX *ctx) +static int ts_RESP_check_request(TS_RESP_CTX *ctx) { TS_REQ *request = ctx->request; TS_MSG_IMPRINT *msg_imprint; X509_ALGOR *md_alg; int md_alg_id; const ASN1_OCTET_STRING *digest; - EVP_MD *md = NULL; + const EVP_MD *md = NULL; int i; - /* Checking request version. */ if (TS_REQ_get_version(request) != 1) { TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Bad request version."); @@ -519,12 +451,11 @@ static int TS_RESP_check_request(TS_RESP_CTX *ctx) return 0; } - /* Checking message digest algorithm. */ - msg_imprint = TS_REQ_get_msg_imprint(request); - md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint); + msg_imprint = request->msg_imprint; + md_alg = msg_imprint->hash_algo; md_alg_id = OBJ_obj2nid(md_alg->algorithm); for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) { - EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); + const EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); if (md_alg_id == EVP_MD_type(current_md)) md = current_md; } @@ -536,7 +467,6 @@ static int TS_RESP_check_request(TS_RESP_CTX *ctx) return 0; } - /* No message digest takes parameter. */ 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 " @@ -544,8 +474,7 @@ static int TS_RESP_check_request(TS_RESP_CTX *ctx) TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); return 0; } - /* Checking message digest size. */ - digest = TS_MSG_IMPRINT_get_msg(msg_imprint); + digest = msg_imprint->hashed_msg; if (digest->length != EVP_MD_size(md)) { TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Bad message digest."); @@ -557,9 +486,9 @@ static int TS_RESP_check_request(TS_RESP_CTX *ctx) } /* Returns the TSA policy based on the requested and acceptable policies. */ -static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx) +static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx) { - ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request); + ASN1_OBJECT *requested = ctx->request->policy_id; ASN1_OBJECT *policy = NULL; int i; @@ -567,10 +496,6 @@ static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx) TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER); return NULL; } - /* - * Return the default policy if none is requested or the default is - * requested. - */ if (!requested || !OBJ_cmp(requested, ctx->default_policy)) policy = ctx->default_policy; @@ -590,7 +515,7 @@ static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx) } /* Creates the TS_TST_INFO object based on the settings of the context. */ -static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, +static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx, ASN1_OBJECT *policy) { int result = 0; @@ -602,7 +527,7 @@ static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, const ASN1_INTEGER *nonce; GENERAL_NAME *tsa_name = NULL; - if (!(tst_info = TS_TST_INFO_new())) + if ((tst_info = TS_TST_INFO_new()) == NULL) goto end; if (!TS_TST_INFO_set_version(tst_info, 1)) goto end; @@ -610,21 +535,19 @@ static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, goto end; if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint)) goto end; - if (!(serial = (*ctx->serial_cb) (ctx, ctx->serial_cb_data)) + if ((serial = ctx->serial_cb(ctx, ctx->serial_cb_data)) == NULL || !TS_TST_INFO_set_serial(tst_info, serial)) goto end; - 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)) + 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 || !TS_TST_INFO_set_time(tst_info, asn1_time)) goto end; - /* Setting accuracy if needed. */ if ((ctx->seconds || ctx->millis || ctx->micros) - && !(accuracy = TS_ACCURACY_new())) + && (accuracy = TS_ACCURACY_new()) == NULL) goto end; - if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds)) goto end; if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis)) @@ -634,23 +557,20 @@ static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) goto end; - /* Setting ordering. */ if ((ctx->flags & TS_ORDERING) && !TS_TST_INFO_set_ordering(tst_info, 1)) goto end; - /* Setting nonce if needed. */ - if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL + if ((nonce = ctx->request->nonce) != NULL && !TS_TST_INFO_set_nonce(tst_info, nonce)) goto end; - /* Setting TSA name to subject of signer certificate. */ if (ctx->flags & TS_TSA_NAME) { - if (!(tsa_name = GENERAL_NAME_new())) + if ((tsa_name = GENERAL_NAME_new()) == NULL) goto end; tsa_name->type = GEN_DIRNAME; tsa_name->d.dirn = - X509_NAME_dup(ctx->signer_cert->cert_info->subject); + X509_NAME_dup(X509_get_subject_name(ctx->signer_cert)); if (!tsa_name->d.dirn) goto end; if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) @@ -676,16 +596,16 @@ static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, } /* Processing the extensions of the request. */ -static int TS_RESP_process_extensions(TS_RESP_CTX *ctx) +static int ts_RESP_process_extensions(TS_RESP_CTX *ctx) { - STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request); + STACK_OF(X509_EXTENSION) *exts = ctx->request->extensions; 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); /* - * XXXXX The last argument was previously (void *)ctx->extension_cb, + * The last argument was previously (void *)ctx->extension_cb, * 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... @@ -697,37 +617,33 @@ static int TS_RESP_process_extensions(TS_RESP_CTX *ctx) } /* Functions for signing the TS_TST_INFO structure of the context. */ -static int TS_RESP_sign(TS_RESP_CTX *ctx) +static int ts_RESP_sign(TS_RESP_CTX *ctx) { int ret = 0; PKCS7 *p7 = NULL; PKCS7_SIGNER_INFO *si; STACK_OF(X509) *certs; /* Certificates to include in sc. */ + ESS_SIGNING_CERT_V2 *sc2 = NULL; ESS_SIGNING_CERT *sc = NULL; ASN1_OBJECT *oid; BIO *p7bio = NULL; int i; - /* Check if signcert and pkey match. */ 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; } - /* Create a new PKCS7 signed object. */ - if (!(p7 = PKCS7_new())) { + if ((p7 = PKCS7_new()) == NULL) { TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); goto err; } if (!PKCS7_set_type(p7, NID_pkcs7_signed)) goto err; - - /* Force SignedData version to be 3 instead of the default 1. */ if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) goto err; - /* Add signer certificate and optional certificate chain. */ - if (TS_REQ_get_cert_req(ctx->request)) { + if (ctx->request->cert_req) { PKCS7_add_certificate(p7, ctx->signer_cert); if (ctx->certs) { for (i = 0; i < sk_X509_num(ctx->certs); ++i) { @@ -737,14 +653,12 @@ static int TS_RESP_sign(TS_RESP_CTX *ctx) } } - /* Add a new signer info. */ - if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, - ctx->signer_key, EVP_sha1()))) { + if ((si = PKCS7_add_signature(p7, ctx->signer_cert, + ctx->signer_key, ctx->signer_md)) == NULL) { TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR); goto err; } - /* Add content type signed attribute to the signer info. */ oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, oid)) { @@ -752,43 +666,42 @@ static int TS_RESP_sign(TS_RESP_CTX *ctx) goto err; } - /* - * Create the ESS SigningCertificate attribute which contains the signer - * certificate id and optionally the certificate chain. - */ certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL; - if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs))) - goto err; + if (ctx->ess_cert_id_digest == NULL + || ctx->ess_cert_id_digest == EVP_sha1()) { + if ((sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs, 0)) == NULL) + goto err; - /* Add SigningCertificate signed attribute to the signer info. */ - if (!ESS_add_signing_cert(si, sc)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR); - goto err; + if (!ESS_SIGNING_CERT_add(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, 0); + if (sc2 == NULL) + goto err; + + if (!ESS_SIGNING_CERT_V2_add(si, sc2)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR); + goto err; + } } - /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */ - if (!TS_TST_INFO_content_new(p7)) + if (!ts_TST_INFO_content_new(p7)) goto err; - - /* Add the DER encoded tst_info to the PKCS7 structure. */ - if (!(p7bio = PKCS7_dataInit(p7, NULL))) { + if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) { TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); goto err; } - - /* Convert tst_info to DER. */ if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) { TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); goto err; } - - /* Create the signature and add it to the signer info. */ if (!PKCS7_dataFinal(p7, p7bio)) { TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); goto err; } - - /* Set new PKCS7 and TST_INFO objects. */ TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info); p7 = NULL; /* Ownership is lost. */ ctx->tst_info = NULL; /* Ownership is lost. */ @@ -800,99 +713,24 @@ static int TS_RESP_sign(TS_RESP_CTX *ctx) "Error during signature " "generation."); BIO_free_all(p7bio); + ESS_SIGNING_CERT_V2_free(sc2); ESS_SIGNING_CERT_free(sc); PKCS7_free(p7); return ret; } -static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, - STACK_OF(X509) *certs) -{ - ESS_CERT_ID *cid; - ESS_SIGNING_CERT *sc = NULL; - int i; - - /* Creating the ESS_CERT_ID stack. */ - if (!(sc = ESS_SIGNING_CERT_new())) - goto err; - if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null())) - goto err; - - /* Adding the signing certificate id. */ - if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) - || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) - goto err; - /* Adding the certificate chain ids. */ - for (i = 0; i < sk_X509_num(certs); ++i) { - X509 *cert = sk_X509_value(certs, i); - if (!(cid = ESS_CERT_ID_new_init(cert, 1)) - || !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; -} - -static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) -{ - ESS_CERT_ID *cid = NULL; - GENERAL_NAME *name = NULL; - - /* Recompute SHA1 hash of certificate if necessary (side effect). */ - X509_check_purpose(cert, -1, 0); - - if (!(cid = ESS_CERT_ID_new())) - goto err; - if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash, - sizeof(cert->sha1_hash))) - goto err; - - /* Setting the issuer/serial if requested. */ - if (issuer_needed) { - /* Creating issuer/serial structure. */ - if (!cid->issuer_serial - && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new())) - goto err; - /* Creating general name from the certificate issuer. */ - if (!(name = GENERAL_NAME_new())) - goto err; - name->type = GEN_DIRNAME; - if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) - goto err; - if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) - goto err; - name = NULL; /* Ownership is lost. */ - /* Setting the serial number. */ - ASN1_INTEGER_free(cid->issuer_serial->serial); - if (!(cid->issuer_serial->serial = - ASN1_INTEGER_dup(cert->cert_info->serialNumber))) - 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; -} - -static int TS_TST_INFO_content_new(PKCS7 *p7) +static int ts_TST_INFO_content_new(PKCS7 *p7) { PKCS7 *ret = NULL; ASN1_OCTET_STRING *octet_string = NULL; /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */ - if (!(ret = PKCS7_new())) + if ((ret = PKCS7_new()) == NULL) goto err; - if (!(ret->d.other = ASN1_TYPE_new())) + if ((ret->d.other = ASN1_TYPE_new()) == NULL) goto err; ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); - if (!(octet_string = ASN1_OCTET_STRING_new())) + if ((octet_string = ASN1_OCTET_STRING_new()) == NULL) goto err; ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string); octet_string = NULL; @@ -908,41 +746,12 @@ static int TS_TST_INFO_content_new(PKCS7 *p7) return 0; } -static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc) -{ - ASN1_STRING *seq = NULL; - unsigned char *p, *pp = NULL; - int len; - - len = i2d_ESS_SIGNING_CERT(sc, NULL); - if (!(pp = OPENSSL_malloc(len))) { - TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); - goto err; - } - p = pp; - i2d_ESS_SIGNING_CERT(sc, &p); - if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { - 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); - 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) +static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision( + ASN1_GENERALIZEDTIME *asn1_time, long sec, long usec, + unsigned precision) { time_t time_sec = (time_t)sec; - struct tm *tm = NULL; + struct tm *tm = NULL, tm_result; char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS]; char *p = genTime_str; char *p_end = genTime_str + sizeof(genTime_str); @@ -950,7 +759,7 @@ static ASN1_GENERALIZEDTIME if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) goto err; - if (!(tm = gmtime(&time_sec))) + if ((tm = OPENSSL_gmtime(&time_sec, &tm_result)) == NULL) goto err; /* @@ -965,12 +774,7 @@ static ASN1_GENERALIZEDTIME tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); if (precision > 0) { - /* Add fraction of seconds (leave space for dot and null). */ BIO_snprintf(p, 2 + precision, ".%06ld", usec); - /* - * We cannot use the snprintf return value, because it might have - * been truncated. - */ p += strlen(p); /* @@ -989,27 +793,29 @@ static ASN1_GENERALIZEDTIME * this loop even if all the digits are zero. */ while (*--p == '0') - /* - * empty - */ ; - /* p points to either the dot or the last non-zero digit. */ + continue; if (*p != '.') ++p; } - /* Add the trailing Z and the terminating null. */ *p++ = 'Z'; *p++ = '\0'; - /* Now call OpenSSL to check and set our genTime value */ - if (!asn1_time && !(asn1_time = ASN1_GENERALIZEDTIME_new())) + if (asn1_time == NULL + && (asn1_time = ASN1_GENERALIZEDTIME_new()) == NULL) goto err; if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) { ASN1_GENERALIZEDTIME_free(asn1_time); goto err; } - return asn1_time; + err: TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME); return NULL; } + +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; +}