X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fts%2Fts_rsp_sign.c;h=7791fc73c896ddac2c734bf535a79d70a1171656;hp=f0fc503aff02bf6c5b79336812d379742b681567;hb=e85d19c68e7fb3302410bd72d434793e5c0c23a0;hpb=05f0fb9f6acc34c82a082d7668572828925694e7 diff --git a/crypto/ts/ts_rsp_sign.c b/crypto/ts/ts_rsp_sign.c index f0fc503aff..7791fc73c8 100644 --- a/crypto/ts/ts_rsp_sign.c +++ b/crypto/ts/ts_rsp_sign.c @@ -1,73 +1,21 @@ -/* 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 "e_os.h" #include "internal/cryptlib.h" -#if defined(OPENSSL_SYS_UNIX) -# include -#endif - #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); @@ -82,26 +30,23 @@ static TS_TST_INFO *ts_RESP_create_tst_info(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 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))) == NULL) { + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE); return NULL; } - memset(ctx, 0, sizeof(*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; @@ -217,12 +157,18 @@ 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)) == NULL) @@ -248,11 +194,10 @@ 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 == NULL && (ctx->policies = sk_ASN1_OBJECT_new_null()) == NULL) goto err; @@ -270,12 +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 == 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; @@ -378,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; @@ -389,7 +331,7 @@ 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); + TS_STATUS_INFO *si = ctx->response->status_info; if (si->failure_info == NULL && (si->failure_info = ASN1_BIT_STRING_new()) == NULL) goto err; @@ -429,46 +371,30 @@ TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) ts_RESP_CTX_init(ctx); - /* Creating the response object. */ 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)) == 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)) goto end; - - /* Checking acceptable policies. */ 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)) == NULL) goto end; - - /* Processing extensions. */ if (!ts_RESP_process_extensions(ctx)) goto end; - - /* Generating the signature. */ 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); @@ -515,10 +441,9 @@ static int ts_RESP_check_request(TS_RESP_CTX *ctx) 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."); @@ -526,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; } @@ -543,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 " @@ -551,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."); @@ -566,7 +488,7 @@ 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) { - ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request); + ASN1_OBJECT *requested = ctx->request->policy_id; ASN1_OBJECT *policy = NULL; int i; @@ -574,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; @@ -627,11 +545,9 @@ static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx, || !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()) == 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)) @@ -641,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()) == 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)) @@ -685,14 +598,14 @@ 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) { - 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... @@ -710,31 +623,27 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx) 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()) == 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) { @@ -744,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())) == NULL) { + 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)) { @@ -759,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)) == NULL) - 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)) goto err; - - /* Add the DER encoded tst_info to the PKCS7 structure. */ 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. */ @@ -807,88 +713,12 @@ 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()) == NULL) - goto err; - if (sc->cert_ids == NULL - && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL) - goto err; - - /* Adding the signing certificate id. */ - if ((cid = ess_CERT_ID_new_init(signcert, 0)) == NULL - || !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)) == NULL - || !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()) == NULL) - 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 == NULL - && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) - goto err; - /* Creating general name from the certificate issuer. */ - if ((name = GENERAL_NAME_new()) == NULL) - goto err; - name->type = GEN_DIRNAME; - if ((name->d.dirn = X509_NAME_dup(cert->cert_info->issuer)) == NULL) - 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) { PKCS7 *ret = NULL; @@ -916,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)) == NULL) { - 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()) == NULL || !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); @@ -958,7 +759,7 @@ static ASN1_GENERALIZEDTIME if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) goto err; - if ((tm = gmtime(&time_sec)) == NULL) + if ((tm = OPENSSL_gmtime(&time_sec, &tm_result)) == NULL) goto err; /* @@ -973,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); /* @@ -997,18 +793,13 @@ 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 == NULL && (asn1_time = ASN1_GENERALIZEDTIME_new()) == NULL) goto err; @@ -1016,9 +807,15 @@ static ASN1_GENERALIZEDTIME 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; +}