Update copyright year
[openssl.git] / crypto / ts / ts_rsp_sign.c
index 8619cb5c90454e8cc81cf68cdd26d7a6b2c1987a..dce50eb451fa708c58fbc0b67ec559b8e9a2f464 100644 (file)
@@ -1,22 +1,24 @@
 /*
- * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
  *
- * Licensed under the OpenSSL license (the "License").  You may not use
+ * 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 "internal/cryptlib.h"
-
-#if defined(OPENSSL_SYS_UNIX)
-# include <sys/time.h>
-#endif
+#include "internal/e_os.h"
 
 #include <openssl/objects.h>
 #include <openssl/ts.h>
 #include <openssl/pkcs7.h>
-#include "ts_lcl.h"
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include "internal/sizes.h"
+#include "crypto/ess.h"
+#include "ts_local.h"
+
+DEFINE_STACK_OF_CONST(EVP_MD)
 
 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);
@@ -31,11 +33,7 @@ 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,
@@ -53,9 +51,10 @@ static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
     return serial;
 
  err:
-    TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
+    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
     TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
                                 "Error during serial number generation.");
+    ASN1_INTEGER_free(serial);
     return NULL;
 }
 
@@ -66,7 +65,7 @@ static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
 {
     struct timeval tv;
     if (gettimeofday(&tv, NULL) != 0) {
-        TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
+        ERR_raise(ERR_LIB_TS, 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);
@@ -85,7 +84,7 @@ static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
 {
     time_t t;
     if (time(&t) == (time_t)-1) {
-        TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
+        ERR_raise(ERR_LIB_TS, 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);
@@ -110,17 +109,24 @@ 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_ex(OSSL_LIB_CTX *libctx, const char *propq)
 {
     TS_RESP_CTX *ctx;
 
     if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
-        TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
 
-    ctx->signer_md = EVP_sha256();
-
+    if (propq != NULL) {
+        ctx->propq = OPENSSL_strdup(propq);
+        if (ctx->propq == NULL) {
+            OPENSSL_free(ctx);
+            ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+    }
+    ctx->libctx = libctx;
     ctx->serial_cb = def_serial_cb;
     ctx->time_cb = def_time_cb;
     ctx->extension_cb = def_extension_cb;
@@ -128,14 +134,20 @@ TS_RESP_CTX *TS_RESP_CTX_new()
     return ctx;
 }
 
+TS_RESP_CTX *TS_RESP_CTX_new(void)
+{
+    return TS_RESP_CTX_new_ex(NULL, NULL);
+}
+
 void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
 {
     if (!ctx)
         return;
 
+    OPENSSL_free(ctx->propq);
     X509_free(ctx->signer_cert);
     EVP_PKEY_free(ctx->signer_key);
-    sk_X509_pop_free(ctx->certs, X509_free);
+    OSSL_STACK_OF_X509_free(ctx->certs);
     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. */
@@ -148,8 +160,7 @@ void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
 int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
 {
     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);
+        ERR_raise(ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
         return 0;
     }
     X509_free(ctx->signer_cert);
@@ -173,33 +184,26 @@ int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, const EVP_MD *md)
     return 1;
 }
 
-int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)
+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)
         goto err;
     return 1;
  err:
-    TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
+    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
     return 0;
 }
 
 int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
 {
-
-    sk_X509_pop_free(ctx->certs, X509_free);
+    OSSL_STACK_OF_X509_free(ctx->certs);
     ctx->certs = NULL;
-    if (!certs)
-        return 1;
-    if ((ctx->certs = X509_chain_up_ref(certs)) == NULL) {
-        TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
 
-    return 1;
+    return certs == NULL || (ctx->certs = X509_chain_up_ref(certs)) != NULL;
 }
 
-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;
 
@@ -213,7 +217,7 @@ int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
 
     return 1;
  err:
-    TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
+    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
     ASN1_OBJECT_free(copy);
     return 0;
 }
@@ -228,7 +232,7 @@ int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
 
     return 1;
  err:
-    TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
+    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
     return 0;
 }
 
@@ -261,7 +265,7 @@ int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
     return 1;
  err:
     TS_RESP_CTX_accuracy_free(ctx);
-    TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
+    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
     return 0;
 }
 
@@ -316,7 +320,7 @@ int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
     ret = 1;
  err:
     if (!ret)
-        TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
     TS_STATUS_INFO_free(si);
     ASN1_UTF8STRING_free(utf8_text);
     return ret;
@@ -344,7 +348,7 @@ int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
         goto err;
     return 1;
  err:
-    TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
+    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
     return 0;
 }
 
@@ -377,7 +381,7 @@ TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
     ts_RESP_CTX_init(ctx);
 
     if ((ctx->response = TS_RESP_new()) == NULL) {
-        TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
         goto end;
     }
     if ((ctx->request = d2i_TS_REQ_bio(req_bio, NULL)) == NULL) {
@@ -402,7 +406,7 @@ TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
 
  end:
     if (!result) {
-        TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
+        ERR_raise(ERR_LIB_TS, TS_R_RESPONSE_SETUP_ERROR);
         if (ctx->response != NULL) {
             if (TS_RESP_CTX_set_status_info_cond(ctx,
                                                  TS_STATUS_REJECTION,
@@ -444,7 +448,7 @@ 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;
+    char md_alg_name[OSSL_MAX_NAME_SIZE];
     const ASN1_OCTET_STRING *digest;
     const EVP_MD *md = NULL;
     int i;
@@ -458,10 +462,10 @@ static int ts_RESP_check_request(TS_RESP_CTX *ctx)
 
     msg_imprint = request->msg_imprint;
     md_alg = msg_imprint->hash_algo;
-    md_alg_id = OBJ_obj2nid(md_alg->algorithm);
+    OBJ_obj2txt(md_alg_name, sizeof(md_alg_name), md_alg->algorithm, 0);
     for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) {
         const EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
-        if (md_alg_id == EVP_MD_type(current_md))
+        if (EVP_MD_is_a(current_md, md_alg_name))
             md = current_md;
     }
     if (!md) {
@@ -480,7 +484,7 @@ static int ts_RESP_check_request(TS_RESP_CTX *ctx)
         return 0;
     }
     digest = msg_imprint->hashed_msg;
-    if (digest->length != EVP_MD_size(md)) {
+    if (digest->length != EVP_MD_get_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);
@@ -498,7 +502,7 @@ static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx)
     int i;
 
     if (ctx->default_policy == NULL) {
-        TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
+        ERR_raise(ERR_LIB_TS, TS_R_INVALID_NULL_POINTER);
         return NULL;
     }
     if (!requested || !OBJ_cmp(requested, ctx->default_policy))
@@ -510,8 +514,8 @@ static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx)
         if (!OBJ_cmp(requested, current))
             policy = current;
     }
-    if (!policy) {
-        TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
+    if (policy == NULL) {
+        ERR_raise(ERR_LIB_TS, 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);
@@ -587,7 +591,7 @@ static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
     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);
+        ERR_raise(ERR_LIB_TS, TS_R_TST_INFO_SETUP_ERROR);
         TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
                                          "Error during TSTInfo "
                                          "generation.");
@@ -622,24 +626,72 @@ static int ts_RESP_process_extensions(TS_RESP_CTX *ctx)
 }
 
 /* Functions for signing the TS_TST_INFO structure of the context. */
+static int ossl_ess_add1_signing_cert(PKCS7_SIGNER_INFO *si,
+                                      const ESS_SIGNING_CERT *sc)
+{
+    ASN1_STRING *seq = NULL;
+    int len = i2d_ESS_SIGNING_CERT(sc, NULL);
+    unsigned char *p, *pp = OPENSSL_malloc(len);
+
+    if (pp == NULL)
+        return 0;
+
+    p = pp;
+    i2d_ESS_SIGNING_CERT(sc, &p);
+    if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
+        ASN1_STRING_free(seq);
+        OPENSSL_free(pp);
+        return 0;
+    }
+
+    OPENSSL_free(pp);
+    return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificate,
+                                      V_ASN1_SEQUENCE, seq);
+}
+
+static int ossl_ess_add1_signing_cert_v2(PKCS7_SIGNER_INFO *si,
+                                         const ESS_SIGNING_CERT_V2 *sc)
+{
+    ASN1_STRING *seq = NULL;
+    int len = i2d_ESS_SIGNING_CERT_V2(sc, NULL);
+    unsigned char *p, *pp = OPENSSL_malloc(len);
+
+    if (pp == NULL)
+        return 0;
+
+    p = pp;
+    i2d_ESS_SIGNING_CERT_V2(sc, &p);
+    if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
+        ASN1_STRING_free(seq);
+        OPENSSL_free(pp);
+        return 0;
+    }
+
+    OPENSSL_free(pp);
+    return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificateV2,
+                                      V_ASN1_SEQUENCE, seq);
+}
+
 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;
+    EVP_MD *signer_md = NULL;
 
     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);
+        ERR_raise(ERR_LIB_TS, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
         goto err;
     }
 
-    if ((p7 = PKCS7_new()) == NULL) {
-        TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
+    if ((p7 = PKCS7_new_ex(ctx->libctx, ctx->propq)) == NULL) {
+        ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     if (!PKCS7_set_type(p7, NID_pkcs7_signed))
@@ -657,39 +709,62 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx)
         }
     }
 
+    if (ctx->signer_md == NULL)
+        signer_md = EVP_MD_fetch(ctx->libctx, "SHA256", ctx->propq);
+    else if (EVP_MD_get0_provider(ctx->signer_md) == NULL)
+        signer_md = EVP_MD_fetch(ctx->libctx, EVP_MD_get0_name(ctx->signer_md),
+                                 ctx->propq);
+    else
+        signer_md = (EVP_MD *)ctx->signer_md;
+
     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);
+                                  ctx->signer_key, signer_md)) == NULL) {
+        ERR_raise(ERR_LIB_TS, 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);
+        ERR_raise(ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
         goto err;
     }
 
     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 (!ESS_add_signing_cert(si, sc)) {
-        TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
-        goto err;
+    if (ctx->ess_cert_id_digest == NULL
+        || EVP_MD_is_a(ctx->ess_cert_id_digest, SN_sha1)) {
+        if ((sc = OSSL_ESS_signing_cert_new_init(ctx->signer_cert,
+                                                 certs, 0)) == NULL)
+            goto err;
+
+        if (!ossl_ess_add1_signing_cert(si, sc)) {
+            ERR_raise(ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
+            goto err;
+        }
+    } else {
+        sc2 = OSSL_ESS_signing_cert_v2_new_init(ctx->ess_cert_id_digest,
+                                                ctx->signer_cert, certs, 0);
+        if (sc2 == NULL)
+            goto err;
+
+        if (!ossl_ess_add1_signing_cert_v2(si, sc2)) {
+            ERR_raise(ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR);
+            goto err;
+        }
     }
 
     if (!ts_TST_INFO_content_new(p7))
         goto err;
     if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
-        TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_TS, 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);
+        ERR_raise(ERR_LIB_TS, TS_R_TS_DATASIGN);
         goto err;
     }
     if (!PKCS7_dataFinal(p7, p7bio)) {
-        TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
+        ERR_raise(ERR_LIB_TS, TS_R_TS_DATASIGN);
         goto err;
     }
     TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
@@ -698,87 +773,20 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx)
 
     ret = 1;
  err:
+    if (signer_md != ctx->signer_md)
+        EVP_MD_free(signer_md);
+
     if (!ret)
         TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
                                          "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;
-
-    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;
-
-    if ((cid = ess_CERT_ID_new_init(signcert, 0)) == NULL
-        || !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);
-        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;
-    unsigned char cert_sha1[SHA_DIGEST_LENGTH];
-
-    /* Call for side-effect of computing hash and caching extensions */
-    X509_check_purpose(cert, -1, 0);
-    if ((cid = ESS_CERT_ID_new()) == NULL)
-        goto err;
-    X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
-    if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
-        goto err;
-
-    /* Setting the issuer/serial if requested. */
-    if (issuer_needed) {
-        if (cid->issuer_serial == NULL
-            && (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);
-        if (!(cid->issuer_serial->serial =
-              ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
-            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;
@@ -806,41 +814,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);
@@ -848,7 +827,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;
 
     /*
@@ -899,6 +878,12 @@ static ASN1_GENERALIZEDTIME
     return asn1_time;
 
  err:
-    TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
+    ERR_raise(ERR_LIB_TS, 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;
+}