1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include "e_os.h"
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_ci#include <openssl/objects.h>
13e1051a39Sopenharmony_ci#include <openssl/ts.h>
14e1051a39Sopenharmony_ci#include <openssl/pkcs7.h>
15e1051a39Sopenharmony_ci#include <openssl/crypto.h>
16e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
17e1051a39Sopenharmony_ci#include "internal/sizes.h"
18e1051a39Sopenharmony_ci#include "crypto/ess.h"
19e1051a39Sopenharmony_ci#include "ts_local.h"
20e1051a39Sopenharmony_ci
21e1051a39Sopenharmony_ciDEFINE_STACK_OF_CONST(EVP_MD)
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_cistatic ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
24e1051a39Sopenharmony_cistatic int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
25e1051a39Sopenharmony_cistatic int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
26e1051a39Sopenharmony_ci
27e1051a39Sopenharmony_cistatic void ts_RESP_CTX_init(TS_RESP_CTX *ctx);
28e1051a39Sopenharmony_cistatic void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
29e1051a39Sopenharmony_cistatic int ts_RESP_check_request(TS_RESP_CTX *ctx);
30e1051a39Sopenharmony_cistatic ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx);
31e1051a39Sopenharmony_cistatic TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
32e1051a39Sopenharmony_ci                                            ASN1_OBJECT *policy);
33e1051a39Sopenharmony_cistatic int ts_RESP_process_extensions(TS_RESP_CTX *ctx);
34e1051a39Sopenharmony_cistatic int ts_RESP_sign(TS_RESP_CTX *ctx);
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_cistatic int ts_TST_INFO_content_new(PKCS7 *p7);
37e1051a39Sopenharmony_ci
38e1051a39Sopenharmony_cistatic ASN1_GENERALIZEDTIME
39e1051a39Sopenharmony_ci*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long,
40e1051a39Sopenharmony_ci                                    unsigned);
41e1051a39Sopenharmony_ci
42e1051a39Sopenharmony_ci/* Default callback for response generation. */
43e1051a39Sopenharmony_cistatic ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
44e1051a39Sopenharmony_ci{
45e1051a39Sopenharmony_ci    ASN1_INTEGER *serial = ASN1_INTEGER_new();
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_ci    if (serial == NULL)
48e1051a39Sopenharmony_ci        goto err;
49e1051a39Sopenharmony_ci    if (!ASN1_INTEGER_set(serial, 1))
50e1051a39Sopenharmony_ci        goto err;
51e1051a39Sopenharmony_ci    return serial;
52e1051a39Sopenharmony_ci
53e1051a39Sopenharmony_ci err:
54e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
55e1051a39Sopenharmony_ci    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
56e1051a39Sopenharmony_ci                                "Error during serial number generation.");
57e1051a39Sopenharmony_ci    ASN1_INTEGER_free(serial);
58e1051a39Sopenharmony_ci    return NULL;
59e1051a39Sopenharmony_ci}
60e1051a39Sopenharmony_ci
61e1051a39Sopenharmony_ci#if defined(OPENSSL_SYS_UNIX)
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_cistatic int def_time_cb(struct TS_resp_ctx *ctx, void *data,
64e1051a39Sopenharmony_ci                       long *sec, long *usec)
65e1051a39Sopenharmony_ci{
66e1051a39Sopenharmony_ci    struct timeval tv;
67e1051a39Sopenharmony_ci    if (gettimeofday(&tv, NULL) != 0) {
68e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR);
69e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
70e1051a39Sopenharmony_ci                                    "Time is not available.");
71e1051a39Sopenharmony_ci        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
72e1051a39Sopenharmony_ci        return 0;
73e1051a39Sopenharmony_ci    }
74e1051a39Sopenharmony_ci    *sec = tv.tv_sec;
75e1051a39Sopenharmony_ci    *usec = tv.tv_usec;
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_ci    return 1;
78e1051a39Sopenharmony_ci}
79e1051a39Sopenharmony_ci
80e1051a39Sopenharmony_ci#else
81e1051a39Sopenharmony_ci
82e1051a39Sopenharmony_cistatic int def_time_cb(struct TS_resp_ctx *ctx, void *data,
83e1051a39Sopenharmony_ci                       long *sec, long *usec)
84e1051a39Sopenharmony_ci{
85e1051a39Sopenharmony_ci    time_t t;
86e1051a39Sopenharmony_ci    if (time(&t) == (time_t)-1) {
87e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR);
88e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
89e1051a39Sopenharmony_ci                                    "Time is not available.");
90e1051a39Sopenharmony_ci        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
91e1051a39Sopenharmony_ci        return 0;
92e1051a39Sopenharmony_ci    }
93e1051a39Sopenharmony_ci    *sec = (long)t;
94e1051a39Sopenharmony_ci    *usec = 0;
95e1051a39Sopenharmony_ci
96e1051a39Sopenharmony_ci    return 1;
97e1051a39Sopenharmony_ci}
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_ci#endif
100e1051a39Sopenharmony_ci
101e1051a39Sopenharmony_cistatic int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
102e1051a39Sopenharmony_ci                            void *data)
103e1051a39Sopenharmony_ci{
104e1051a39Sopenharmony_ci    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
105e1051a39Sopenharmony_ci                                "Unsupported extension.");
106e1051a39Sopenharmony_ci    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
107e1051a39Sopenharmony_ci    return 0;
108e1051a39Sopenharmony_ci}
109e1051a39Sopenharmony_ci
110e1051a39Sopenharmony_ci/* TS_RESP_CTX management functions. */
111e1051a39Sopenharmony_ci
112e1051a39Sopenharmony_ciTS_RESP_CTX *TS_RESP_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq)
113e1051a39Sopenharmony_ci{
114e1051a39Sopenharmony_ci    TS_RESP_CTX *ctx;
115e1051a39Sopenharmony_ci
116e1051a39Sopenharmony_ci    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
117e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
118e1051a39Sopenharmony_ci        return NULL;
119e1051a39Sopenharmony_ci    }
120e1051a39Sopenharmony_ci
121e1051a39Sopenharmony_ci    if (propq != NULL) {
122e1051a39Sopenharmony_ci        ctx->propq = OPENSSL_strdup(propq);
123e1051a39Sopenharmony_ci        if (ctx->propq == NULL) {
124e1051a39Sopenharmony_ci            OPENSSL_free(ctx);
125e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
126e1051a39Sopenharmony_ci            return NULL;
127e1051a39Sopenharmony_ci        }
128e1051a39Sopenharmony_ci    }
129e1051a39Sopenharmony_ci    ctx->libctx = libctx;
130e1051a39Sopenharmony_ci    ctx->serial_cb = def_serial_cb;
131e1051a39Sopenharmony_ci    ctx->time_cb = def_time_cb;
132e1051a39Sopenharmony_ci    ctx->extension_cb = def_extension_cb;
133e1051a39Sopenharmony_ci
134e1051a39Sopenharmony_ci    return ctx;
135e1051a39Sopenharmony_ci}
136e1051a39Sopenharmony_ci
137e1051a39Sopenharmony_ciTS_RESP_CTX *TS_RESP_CTX_new(void)
138e1051a39Sopenharmony_ci{
139e1051a39Sopenharmony_ci    return TS_RESP_CTX_new_ex(NULL, NULL);
140e1051a39Sopenharmony_ci}
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_civoid TS_RESP_CTX_free(TS_RESP_CTX *ctx)
143e1051a39Sopenharmony_ci{
144e1051a39Sopenharmony_ci    if (!ctx)
145e1051a39Sopenharmony_ci        return;
146e1051a39Sopenharmony_ci
147e1051a39Sopenharmony_ci    OPENSSL_free(ctx->propq);
148e1051a39Sopenharmony_ci    X509_free(ctx->signer_cert);
149e1051a39Sopenharmony_ci    EVP_PKEY_free(ctx->signer_key);
150e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->certs, X509_free);
151e1051a39Sopenharmony_ci    sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
152e1051a39Sopenharmony_ci    ASN1_OBJECT_free(ctx->default_policy);
153e1051a39Sopenharmony_ci    sk_EVP_MD_free(ctx->mds);   /* No EVP_MD_free method exists. */
154e1051a39Sopenharmony_ci    ASN1_INTEGER_free(ctx->seconds);
155e1051a39Sopenharmony_ci    ASN1_INTEGER_free(ctx->millis);
156e1051a39Sopenharmony_ci    ASN1_INTEGER_free(ctx->micros);
157e1051a39Sopenharmony_ci    OPENSSL_free(ctx);
158e1051a39Sopenharmony_ci}
159e1051a39Sopenharmony_ci
160e1051a39Sopenharmony_ciint TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
161e1051a39Sopenharmony_ci{
162e1051a39Sopenharmony_ci    if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) {
163e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
164e1051a39Sopenharmony_ci        return 0;
165e1051a39Sopenharmony_ci    }
166e1051a39Sopenharmony_ci    X509_free(ctx->signer_cert);
167e1051a39Sopenharmony_ci    ctx->signer_cert = signer;
168e1051a39Sopenharmony_ci    X509_up_ref(ctx->signer_cert);
169e1051a39Sopenharmony_ci    return 1;
170e1051a39Sopenharmony_ci}
171e1051a39Sopenharmony_ci
172e1051a39Sopenharmony_ciint TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
173e1051a39Sopenharmony_ci{
174e1051a39Sopenharmony_ci    EVP_PKEY_free(ctx->signer_key);
175e1051a39Sopenharmony_ci    ctx->signer_key = key;
176e1051a39Sopenharmony_ci    EVP_PKEY_up_ref(ctx->signer_key);
177e1051a39Sopenharmony_ci
178e1051a39Sopenharmony_ci    return 1;
179e1051a39Sopenharmony_ci}
180e1051a39Sopenharmony_ci
181e1051a39Sopenharmony_ciint TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, const EVP_MD *md)
182e1051a39Sopenharmony_ci{
183e1051a39Sopenharmony_ci    ctx->signer_md = md;
184e1051a39Sopenharmony_ci    return 1;
185e1051a39Sopenharmony_ci}
186e1051a39Sopenharmony_ci
187e1051a39Sopenharmony_ciint TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy)
188e1051a39Sopenharmony_ci{
189e1051a39Sopenharmony_ci    ASN1_OBJECT_free(ctx->default_policy);
190e1051a39Sopenharmony_ci    if ((ctx->default_policy = OBJ_dup(def_policy)) == NULL)
191e1051a39Sopenharmony_ci        goto err;
192e1051a39Sopenharmony_ci    return 1;
193e1051a39Sopenharmony_ci err:
194e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
195e1051a39Sopenharmony_ci    return 0;
196e1051a39Sopenharmony_ci}
197e1051a39Sopenharmony_ci
198e1051a39Sopenharmony_ciint TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
199e1051a39Sopenharmony_ci{
200e1051a39Sopenharmony_ci    sk_X509_pop_free(ctx->certs, X509_free);
201e1051a39Sopenharmony_ci    ctx->certs = NULL;
202e1051a39Sopenharmony_ci
203e1051a39Sopenharmony_ci    return certs == NULL || (ctx->certs = X509_chain_up_ref(certs)) != NULL;
204e1051a39Sopenharmony_ci}
205e1051a39Sopenharmony_ci
206e1051a39Sopenharmony_ciint TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy)
207e1051a39Sopenharmony_ci{
208e1051a39Sopenharmony_ci    ASN1_OBJECT *copy = NULL;
209e1051a39Sopenharmony_ci
210e1051a39Sopenharmony_ci    if (ctx->policies == NULL
211e1051a39Sopenharmony_ci        && (ctx->policies = sk_ASN1_OBJECT_new_null()) == NULL)
212e1051a39Sopenharmony_ci        goto err;
213e1051a39Sopenharmony_ci    if ((copy = OBJ_dup(policy)) == NULL)
214e1051a39Sopenharmony_ci        goto err;
215e1051a39Sopenharmony_ci    if (!sk_ASN1_OBJECT_push(ctx->policies, copy))
216e1051a39Sopenharmony_ci        goto err;
217e1051a39Sopenharmony_ci
218e1051a39Sopenharmony_ci    return 1;
219e1051a39Sopenharmony_ci err:
220e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
221e1051a39Sopenharmony_ci    ASN1_OBJECT_free(copy);
222e1051a39Sopenharmony_ci    return 0;
223e1051a39Sopenharmony_ci}
224e1051a39Sopenharmony_ci
225e1051a39Sopenharmony_ciint TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
226e1051a39Sopenharmony_ci{
227e1051a39Sopenharmony_ci    if (ctx->mds == NULL
228e1051a39Sopenharmony_ci        && (ctx->mds = sk_EVP_MD_new_null()) == NULL)
229e1051a39Sopenharmony_ci        goto err;
230e1051a39Sopenharmony_ci    if (!sk_EVP_MD_push(ctx->mds, md))
231e1051a39Sopenharmony_ci        goto err;
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_ci    return 1;
234e1051a39Sopenharmony_ci err:
235e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
236e1051a39Sopenharmony_ci    return 0;
237e1051a39Sopenharmony_ci}
238e1051a39Sopenharmony_ci
239e1051a39Sopenharmony_ci#define TS_RESP_CTX_accuracy_free(ctx)          \
240e1051a39Sopenharmony_ci        ASN1_INTEGER_free(ctx->seconds);        \
241e1051a39Sopenharmony_ci        ctx->seconds = NULL;                    \
242e1051a39Sopenharmony_ci        ASN1_INTEGER_free(ctx->millis);         \
243e1051a39Sopenharmony_ci        ctx->millis = NULL;                     \
244e1051a39Sopenharmony_ci        ASN1_INTEGER_free(ctx->micros);         \
245e1051a39Sopenharmony_ci        ctx->micros = NULL;
246e1051a39Sopenharmony_ci
247e1051a39Sopenharmony_ciint TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
248e1051a39Sopenharmony_ci                             int secs, int millis, int micros)
249e1051a39Sopenharmony_ci{
250e1051a39Sopenharmony_ci
251e1051a39Sopenharmony_ci    TS_RESP_CTX_accuracy_free(ctx);
252e1051a39Sopenharmony_ci    if (secs
253e1051a39Sopenharmony_ci        && ((ctx->seconds = ASN1_INTEGER_new()) == NULL
254e1051a39Sopenharmony_ci            || !ASN1_INTEGER_set(ctx->seconds, secs)))
255e1051a39Sopenharmony_ci        goto err;
256e1051a39Sopenharmony_ci    if (millis
257e1051a39Sopenharmony_ci        && ((ctx->millis = ASN1_INTEGER_new()) == NULL
258e1051a39Sopenharmony_ci            || !ASN1_INTEGER_set(ctx->millis, millis)))
259e1051a39Sopenharmony_ci        goto err;
260e1051a39Sopenharmony_ci    if (micros
261e1051a39Sopenharmony_ci        && ((ctx->micros = ASN1_INTEGER_new()) == NULL
262e1051a39Sopenharmony_ci            || !ASN1_INTEGER_set(ctx->micros, micros)))
263e1051a39Sopenharmony_ci        goto err;
264e1051a39Sopenharmony_ci
265e1051a39Sopenharmony_ci    return 1;
266e1051a39Sopenharmony_ci err:
267e1051a39Sopenharmony_ci    TS_RESP_CTX_accuracy_free(ctx);
268e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
269e1051a39Sopenharmony_ci    return 0;
270e1051a39Sopenharmony_ci}
271e1051a39Sopenharmony_ci
272e1051a39Sopenharmony_civoid TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
273e1051a39Sopenharmony_ci{
274e1051a39Sopenharmony_ci    ctx->flags |= flags;
275e1051a39Sopenharmony_ci}
276e1051a39Sopenharmony_ci
277e1051a39Sopenharmony_civoid TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
278e1051a39Sopenharmony_ci{
279e1051a39Sopenharmony_ci    ctx->serial_cb = cb;
280e1051a39Sopenharmony_ci    ctx->serial_cb_data = data;
281e1051a39Sopenharmony_ci}
282e1051a39Sopenharmony_ci
283e1051a39Sopenharmony_civoid TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
284e1051a39Sopenharmony_ci{
285e1051a39Sopenharmony_ci    ctx->time_cb = cb;
286e1051a39Sopenharmony_ci    ctx->time_cb_data = data;
287e1051a39Sopenharmony_ci}
288e1051a39Sopenharmony_ci
289e1051a39Sopenharmony_civoid TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
290e1051a39Sopenharmony_ci                                  TS_extension_cb cb, void *data)
291e1051a39Sopenharmony_ci{
292e1051a39Sopenharmony_ci    ctx->extension_cb = cb;
293e1051a39Sopenharmony_ci    ctx->extension_cb_data = data;
294e1051a39Sopenharmony_ci}
295e1051a39Sopenharmony_ci
296e1051a39Sopenharmony_ciint TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
297e1051a39Sopenharmony_ci                                int status, const char *text)
298e1051a39Sopenharmony_ci{
299e1051a39Sopenharmony_ci    TS_STATUS_INFO *si = NULL;
300e1051a39Sopenharmony_ci    ASN1_UTF8STRING *utf8_text = NULL;
301e1051a39Sopenharmony_ci    int ret = 0;
302e1051a39Sopenharmony_ci
303e1051a39Sopenharmony_ci    if ((si = TS_STATUS_INFO_new()) == NULL)
304e1051a39Sopenharmony_ci        goto err;
305e1051a39Sopenharmony_ci    if (!ASN1_INTEGER_set(si->status, status))
306e1051a39Sopenharmony_ci        goto err;
307e1051a39Sopenharmony_ci    if (text) {
308e1051a39Sopenharmony_ci        if ((utf8_text = ASN1_UTF8STRING_new()) == NULL
309e1051a39Sopenharmony_ci            || !ASN1_STRING_set(utf8_text, text, strlen(text)))
310e1051a39Sopenharmony_ci            goto err;
311e1051a39Sopenharmony_ci        if (si->text == NULL
312e1051a39Sopenharmony_ci            && (si->text = sk_ASN1_UTF8STRING_new_null()) == NULL)
313e1051a39Sopenharmony_ci            goto err;
314e1051a39Sopenharmony_ci        if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text))
315e1051a39Sopenharmony_ci            goto err;
316e1051a39Sopenharmony_ci        utf8_text = NULL;       /* Ownership is lost. */
317e1051a39Sopenharmony_ci    }
318e1051a39Sopenharmony_ci    if (!TS_RESP_set_status_info(ctx->response, si))
319e1051a39Sopenharmony_ci        goto err;
320e1051a39Sopenharmony_ci    ret = 1;
321e1051a39Sopenharmony_ci err:
322e1051a39Sopenharmony_ci    if (!ret)
323e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
324e1051a39Sopenharmony_ci    TS_STATUS_INFO_free(si);
325e1051a39Sopenharmony_ci    ASN1_UTF8STRING_free(utf8_text);
326e1051a39Sopenharmony_ci    return ret;
327e1051a39Sopenharmony_ci}
328e1051a39Sopenharmony_ci
329e1051a39Sopenharmony_ciint TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
330e1051a39Sopenharmony_ci                                     int status, const char *text)
331e1051a39Sopenharmony_ci{
332e1051a39Sopenharmony_ci    int ret = 1;
333e1051a39Sopenharmony_ci    TS_STATUS_INFO *si = ctx->response->status_info;
334e1051a39Sopenharmony_ci
335e1051a39Sopenharmony_ci    if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) {
336e1051a39Sopenharmony_ci        ret = TS_RESP_CTX_set_status_info(ctx, status, text);
337e1051a39Sopenharmony_ci    }
338e1051a39Sopenharmony_ci    return ret;
339e1051a39Sopenharmony_ci}
340e1051a39Sopenharmony_ci
341e1051a39Sopenharmony_ciint TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
342e1051a39Sopenharmony_ci{
343e1051a39Sopenharmony_ci    TS_STATUS_INFO *si = ctx->response->status_info;
344e1051a39Sopenharmony_ci    if (si->failure_info == NULL
345e1051a39Sopenharmony_ci        && (si->failure_info = ASN1_BIT_STRING_new()) == NULL)
346e1051a39Sopenharmony_ci        goto err;
347e1051a39Sopenharmony_ci    if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
348e1051a39Sopenharmony_ci        goto err;
349e1051a39Sopenharmony_ci    return 1;
350e1051a39Sopenharmony_ci err:
351e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
352e1051a39Sopenharmony_ci    return 0;
353e1051a39Sopenharmony_ci}
354e1051a39Sopenharmony_ci
355e1051a39Sopenharmony_ciTS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
356e1051a39Sopenharmony_ci{
357e1051a39Sopenharmony_ci    return ctx->request;
358e1051a39Sopenharmony_ci}
359e1051a39Sopenharmony_ci
360e1051a39Sopenharmony_ciTS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
361e1051a39Sopenharmony_ci{
362e1051a39Sopenharmony_ci    return ctx->tst_info;
363e1051a39Sopenharmony_ci}
364e1051a39Sopenharmony_ci
365e1051a39Sopenharmony_ciint TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
366e1051a39Sopenharmony_ci                                           unsigned precision)
367e1051a39Sopenharmony_ci{
368e1051a39Sopenharmony_ci    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
369e1051a39Sopenharmony_ci        return 0;
370e1051a39Sopenharmony_ci    ctx->clock_precision_digits = precision;
371e1051a39Sopenharmony_ci    return 1;
372e1051a39Sopenharmony_ci}
373e1051a39Sopenharmony_ci
374e1051a39Sopenharmony_ci/* Main entry method of the response generation. */
375e1051a39Sopenharmony_ciTS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
376e1051a39Sopenharmony_ci{
377e1051a39Sopenharmony_ci    ASN1_OBJECT *policy;
378e1051a39Sopenharmony_ci    TS_RESP *response;
379e1051a39Sopenharmony_ci    int result = 0;
380e1051a39Sopenharmony_ci
381e1051a39Sopenharmony_ci    ts_RESP_CTX_init(ctx);
382e1051a39Sopenharmony_ci
383e1051a39Sopenharmony_ci    if ((ctx->response = TS_RESP_new()) == NULL) {
384e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
385e1051a39Sopenharmony_ci        goto end;
386e1051a39Sopenharmony_ci    }
387e1051a39Sopenharmony_ci    if ((ctx->request = d2i_TS_REQ_bio(req_bio, NULL)) == NULL) {
388e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
389e1051a39Sopenharmony_ci                                    "Bad request format or system error.");
390e1051a39Sopenharmony_ci        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
391e1051a39Sopenharmony_ci        goto end;
392e1051a39Sopenharmony_ci    }
393e1051a39Sopenharmony_ci    if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
394e1051a39Sopenharmony_ci        goto end;
395e1051a39Sopenharmony_ci    if (!ts_RESP_check_request(ctx))
396e1051a39Sopenharmony_ci        goto end;
397e1051a39Sopenharmony_ci    if ((policy = ts_RESP_get_policy(ctx)) == NULL)
398e1051a39Sopenharmony_ci        goto end;
399e1051a39Sopenharmony_ci    if ((ctx->tst_info = ts_RESP_create_tst_info(ctx, policy)) == NULL)
400e1051a39Sopenharmony_ci        goto end;
401e1051a39Sopenharmony_ci    if (!ts_RESP_process_extensions(ctx))
402e1051a39Sopenharmony_ci        goto end;
403e1051a39Sopenharmony_ci    if (!ts_RESP_sign(ctx))
404e1051a39Sopenharmony_ci        goto end;
405e1051a39Sopenharmony_ci    result = 1;
406e1051a39Sopenharmony_ci
407e1051a39Sopenharmony_ci end:
408e1051a39Sopenharmony_ci    if (!result) {
409e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_RESPONSE_SETUP_ERROR);
410e1051a39Sopenharmony_ci        if (ctx->response != NULL) {
411e1051a39Sopenharmony_ci            if (TS_RESP_CTX_set_status_info_cond(ctx,
412e1051a39Sopenharmony_ci                                                 TS_STATUS_REJECTION,
413e1051a39Sopenharmony_ci                                                 "Error during response "
414e1051a39Sopenharmony_ci                                                 "generation.") == 0) {
415e1051a39Sopenharmony_ci                TS_RESP_free(ctx->response);
416e1051a39Sopenharmony_ci                ctx->response = NULL;
417e1051a39Sopenharmony_ci            }
418e1051a39Sopenharmony_ci        }
419e1051a39Sopenharmony_ci    }
420e1051a39Sopenharmony_ci    response = ctx->response;
421e1051a39Sopenharmony_ci    ctx->response = NULL;       /* Ownership will be returned to caller. */
422e1051a39Sopenharmony_ci    ts_RESP_CTX_cleanup(ctx);
423e1051a39Sopenharmony_ci    return response;
424e1051a39Sopenharmony_ci}
425e1051a39Sopenharmony_ci
426e1051a39Sopenharmony_ci/* Initializes the variable part of the context. */
427e1051a39Sopenharmony_cistatic void ts_RESP_CTX_init(TS_RESP_CTX *ctx)
428e1051a39Sopenharmony_ci{
429e1051a39Sopenharmony_ci    ctx->request = NULL;
430e1051a39Sopenharmony_ci    ctx->response = NULL;
431e1051a39Sopenharmony_ci    ctx->tst_info = NULL;
432e1051a39Sopenharmony_ci}
433e1051a39Sopenharmony_ci
434e1051a39Sopenharmony_ci/* Cleans up the variable part of the context. */
435e1051a39Sopenharmony_cistatic void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
436e1051a39Sopenharmony_ci{
437e1051a39Sopenharmony_ci    TS_REQ_free(ctx->request);
438e1051a39Sopenharmony_ci    ctx->request = NULL;
439e1051a39Sopenharmony_ci    TS_RESP_free(ctx->response);
440e1051a39Sopenharmony_ci    ctx->response = NULL;
441e1051a39Sopenharmony_ci    TS_TST_INFO_free(ctx->tst_info);
442e1051a39Sopenharmony_ci    ctx->tst_info = NULL;
443e1051a39Sopenharmony_ci}
444e1051a39Sopenharmony_ci
445e1051a39Sopenharmony_ci/* Checks the format and content of the request. */
446e1051a39Sopenharmony_cistatic int ts_RESP_check_request(TS_RESP_CTX *ctx)
447e1051a39Sopenharmony_ci{
448e1051a39Sopenharmony_ci    TS_REQ *request = ctx->request;
449e1051a39Sopenharmony_ci    TS_MSG_IMPRINT *msg_imprint;
450e1051a39Sopenharmony_ci    X509_ALGOR *md_alg;
451e1051a39Sopenharmony_ci    char md_alg_name[OSSL_MAX_NAME_SIZE];
452e1051a39Sopenharmony_ci    const ASN1_OCTET_STRING *digest;
453e1051a39Sopenharmony_ci    const EVP_MD *md = NULL;
454e1051a39Sopenharmony_ci    int i;
455e1051a39Sopenharmony_ci
456e1051a39Sopenharmony_ci    if (TS_REQ_get_version(request) != 1) {
457e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
458e1051a39Sopenharmony_ci                                    "Bad request version.");
459e1051a39Sopenharmony_ci        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
460e1051a39Sopenharmony_ci        return 0;
461e1051a39Sopenharmony_ci    }
462e1051a39Sopenharmony_ci
463e1051a39Sopenharmony_ci    msg_imprint = request->msg_imprint;
464e1051a39Sopenharmony_ci    md_alg = msg_imprint->hash_algo;
465e1051a39Sopenharmony_ci    OBJ_obj2txt(md_alg_name, sizeof(md_alg_name), md_alg->algorithm, 0);
466e1051a39Sopenharmony_ci    for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) {
467e1051a39Sopenharmony_ci        const EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
468e1051a39Sopenharmony_ci        if (EVP_MD_is_a(current_md, md_alg_name))
469e1051a39Sopenharmony_ci            md = current_md;
470e1051a39Sopenharmony_ci    }
471e1051a39Sopenharmony_ci    if (!md) {
472e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
473e1051a39Sopenharmony_ci                                    "Message digest algorithm is "
474e1051a39Sopenharmony_ci                                    "not supported.");
475e1051a39Sopenharmony_ci        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
476e1051a39Sopenharmony_ci        return 0;
477e1051a39Sopenharmony_ci    }
478e1051a39Sopenharmony_ci
479e1051a39Sopenharmony_ci    if (md_alg->parameter && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) {
480e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
481e1051a39Sopenharmony_ci                                    "Superfluous message digest "
482e1051a39Sopenharmony_ci                                    "parameter.");
483e1051a39Sopenharmony_ci        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
484e1051a39Sopenharmony_ci        return 0;
485e1051a39Sopenharmony_ci    }
486e1051a39Sopenharmony_ci    digest = msg_imprint->hashed_msg;
487e1051a39Sopenharmony_ci    if (digest->length != EVP_MD_get_size(md)) {
488e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
489e1051a39Sopenharmony_ci                                    "Bad message digest.");
490e1051a39Sopenharmony_ci        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
491e1051a39Sopenharmony_ci        return 0;
492e1051a39Sopenharmony_ci    }
493e1051a39Sopenharmony_ci
494e1051a39Sopenharmony_ci    return 1;
495e1051a39Sopenharmony_ci}
496e1051a39Sopenharmony_ci
497e1051a39Sopenharmony_ci/* Returns the TSA policy based on the requested and acceptable policies. */
498e1051a39Sopenharmony_cistatic ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx)
499e1051a39Sopenharmony_ci{
500e1051a39Sopenharmony_ci    ASN1_OBJECT *requested = ctx->request->policy_id;
501e1051a39Sopenharmony_ci    ASN1_OBJECT *policy = NULL;
502e1051a39Sopenharmony_ci    int i;
503e1051a39Sopenharmony_ci
504e1051a39Sopenharmony_ci    if (ctx->default_policy == NULL) {
505e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_INVALID_NULL_POINTER);
506e1051a39Sopenharmony_ci        return NULL;
507e1051a39Sopenharmony_ci    }
508e1051a39Sopenharmony_ci    if (!requested || !OBJ_cmp(requested, ctx->default_policy))
509e1051a39Sopenharmony_ci        policy = ctx->default_policy;
510e1051a39Sopenharmony_ci
511e1051a39Sopenharmony_ci    /* Check if the policy is acceptable. */
512e1051a39Sopenharmony_ci    for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) {
513e1051a39Sopenharmony_ci        ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
514e1051a39Sopenharmony_ci        if (!OBJ_cmp(requested, current))
515e1051a39Sopenharmony_ci            policy = current;
516e1051a39Sopenharmony_ci    }
517e1051a39Sopenharmony_ci    if (policy == NULL) {
518e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_UNACCEPTABLE_POLICY);
519e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
520e1051a39Sopenharmony_ci                                    "Requested policy is not " "supported.");
521e1051a39Sopenharmony_ci        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
522e1051a39Sopenharmony_ci    }
523e1051a39Sopenharmony_ci    return policy;
524e1051a39Sopenharmony_ci}
525e1051a39Sopenharmony_ci
526e1051a39Sopenharmony_ci/* Creates the TS_TST_INFO object based on the settings of the context. */
527e1051a39Sopenharmony_cistatic TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
528e1051a39Sopenharmony_ci                                            ASN1_OBJECT *policy)
529e1051a39Sopenharmony_ci{
530e1051a39Sopenharmony_ci    int result = 0;
531e1051a39Sopenharmony_ci    TS_TST_INFO *tst_info = NULL;
532e1051a39Sopenharmony_ci    ASN1_INTEGER *serial = NULL;
533e1051a39Sopenharmony_ci    ASN1_GENERALIZEDTIME *asn1_time = NULL;
534e1051a39Sopenharmony_ci    long sec, usec;
535e1051a39Sopenharmony_ci    TS_ACCURACY *accuracy = NULL;
536e1051a39Sopenharmony_ci    const ASN1_INTEGER *nonce;
537e1051a39Sopenharmony_ci    GENERAL_NAME *tsa_name = NULL;
538e1051a39Sopenharmony_ci
539e1051a39Sopenharmony_ci    if ((tst_info = TS_TST_INFO_new()) == NULL)
540e1051a39Sopenharmony_ci        goto end;
541e1051a39Sopenharmony_ci    if (!TS_TST_INFO_set_version(tst_info, 1))
542e1051a39Sopenharmony_ci        goto end;
543e1051a39Sopenharmony_ci    if (!TS_TST_INFO_set_policy_id(tst_info, policy))
544e1051a39Sopenharmony_ci        goto end;
545e1051a39Sopenharmony_ci    if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
546e1051a39Sopenharmony_ci        goto end;
547e1051a39Sopenharmony_ci    if ((serial = ctx->serial_cb(ctx, ctx->serial_cb_data)) == NULL
548e1051a39Sopenharmony_ci        || !TS_TST_INFO_set_serial(tst_info, serial))
549e1051a39Sopenharmony_ci        goto end;
550e1051a39Sopenharmony_ci    if (!ctx->time_cb(ctx, ctx->time_cb_data, &sec, &usec)
551e1051a39Sopenharmony_ci        || (asn1_time =
552e1051a39Sopenharmony_ci            TS_RESP_set_genTime_with_precision(NULL, sec, usec,
553e1051a39Sopenharmony_ci                                        ctx->clock_precision_digits)) == NULL
554e1051a39Sopenharmony_ci        || !TS_TST_INFO_set_time(tst_info, asn1_time))
555e1051a39Sopenharmony_ci        goto end;
556e1051a39Sopenharmony_ci
557e1051a39Sopenharmony_ci    if ((ctx->seconds || ctx->millis || ctx->micros)
558e1051a39Sopenharmony_ci        && (accuracy = TS_ACCURACY_new()) == NULL)
559e1051a39Sopenharmony_ci        goto end;
560e1051a39Sopenharmony_ci    if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
561e1051a39Sopenharmony_ci        goto end;
562e1051a39Sopenharmony_ci    if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
563e1051a39Sopenharmony_ci        goto end;
564e1051a39Sopenharmony_ci    if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
565e1051a39Sopenharmony_ci        goto end;
566e1051a39Sopenharmony_ci    if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))
567e1051a39Sopenharmony_ci        goto end;
568e1051a39Sopenharmony_ci
569e1051a39Sopenharmony_ci    if ((ctx->flags & TS_ORDERING)
570e1051a39Sopenharmony_ci        && !TS_TST_INFO_set_ordering(tst_info, 1))
571e1051a39Sopenharmony_ci        goto end;
572e1051a39Sopenharmony_ci
573e1051a39Sopenharmony_ci    if ((nonce = ctx->request->nonce) != NULL
574e1051a39Sopenharmony_ci        && !TS_TST_INFO_set_nonce(tst_info, nonce))
575e1051a39Sopenharmony_ci        goto end;
576e1051a39Sopenharmony_ci
577e1051a39Sopenharmony_ci    if (ctx->flags & TS_TSA_NAME) {
578e1051a39Sopenharmony_ci        if ((tsa_name = GENERAL_NAME_new()) == NULL)
579e1051a39Sopenharmony_ci            goto end;
580e1051a39Sopenharmony_ci        tsa_name->type = GEN_DIRNAME;
581e1051a39Sopenharmony_ci        tsa_name->d.dirn =
582e1051a39Sopenharmony_ci            X509_NAME_dup(X509_get_subject_name(ctx->signer_cert));
583e1051a39Sopenharmony_ci        if (!tsa_name->d.dirn)
584e1051a39Sopenharmony_ci            goto end;
585e1051a39Sopenharmony_ci        if (!TS_TST_INFO_set_tsa(tst_info, tsa_name))
586e1051a39Sopenharmony_ci            goto end;
587e1051a39Sopenharmony_ci    }
588e1051a39Sopenharmony_ci
589e1051a39Sopenharmony_ci    result = 1;
590e1051a39Sopenharmony_ci end:
591e1051a39Sopenharmony_ci    if (!result) {
592e1051a39Sopenharmony_ci        TS_TST_INFO_free(tst_info);
593e1051a39Sopenharmony_ci        tst_info = NULL;
594e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_TST_INFO_SETUP_ERROR);
595e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
596e1051a39Sopenharmony_ci                                         "Error during TSTInfo "
597e1051a39Sopenharmony_ci                                         "generation.");
598e1051a39Sopenharmony_ci    }
599e1051a39Sopenharmony_ci    GENERAL_NAME_free(tsa_name);
600e1051a39Sopenharmony_ci    TS_ACCURACY_free(accuracy);
601e1051a39Sopenharmony_ci    ASN1_GENERALIZEDTIME_free(asn1_time);
602e1051a39Sopenharmony_ci    ASN1_INTEGER_free(serial);
603e1051a39Sopenharmony_ci
604e1051a39Sopenharmony_ci    return tst_info;
605e1051a39Sopenharmony_ci}
606e1051a39Sopenharmony_ci
607e1051a39Sopenharmony_ci/* Processing the extensions of the request. */
608e1051a39Sopenharmony_cistatic int ts_RESP_process_extensions(TS_RESP_CTX *ctx)
609e1051a39Sopenharmony_ci{
610e1051a39Sopenharmony_ci    STACK_OF(X509_EXTENSION) *exts = ctx->request->extensions;
611e1051a39Sopenharmony_ci    int i;
612e1051a39Sopenharmony_ci    int ok = 1;
613e1051a39Sopenharmony_ci
614e1051a39Sopenharmony_ci    for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) {
615e1051a39Sopenharmony_ci        X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
616e1051a39Sopenharmony_ci        /*
617e1051a39Sopenharmony_ci         * The last argument was previously (void *)ctx->extension_cb,
618e1051a39Sopenharmony_ci         * but ISO C doesn't permit converting a function pointer to void *.
619e1051a39Sopenharmony_ci         * For lack of better information, I'm placing a NULL there instead.
620e1051a39Sopenharmony_ci         * The callback can pick its own address out from the ctx anyway...
621e1051a39Sopenharmony_ci         */
622e1051a39Sopenharmony_ci        ok = (*ctx->extension_cb) (ctx, ext, NULL);
623e1051a39Sopenharmony_ci    }
624e1051a39Sopenharmony_ci
625e1051a39Sopenharmony_ci    return ok;
626e1051a39Sopenharmony_ci}
627e1051a39Sopenharmony_ci
628e1051a39Sopenharmony_ci/* Functions for signing the TS_TST_INFO structure of the context. */
629e1051a39Sopenharmony_cistatic int ossl_ess_add1_signing_cert(PKCS7_SIGNER_INFO *si,
630e1051a39Sopenharmony_ci                                      const ESS_SIGNING_CERT *sc)
631e1051a39Sopenharmony_ci{
632e1051a39Sopenharmony_ci    ASN1_STRING *seq = NULL;
633e1051a39Sopenharmony_ci    int len = i2d_ESS_SIGNING_CERT(sc, NULL);
634e1051a39Sopenharmony_ci    unsigned char *p, *pp = OPENSSL_malloc(len);
635e1051a39Sopenharmony_ci
636e1051a39Sopenharmony_ci    if (pp == NULL)
637e1051a39Sopenharmony_ci        return 0;
638e1051a39Sopenharmony_ci
639e1051a39Sopenharmony_ci    p = pp;
640e1051a39Sopenharmony_ci    i2d_ESS_SIGNING_CERT(sc, &p);
641e1051a39Sopenharmony_ci    if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
642e1051a39Sopenharmony_ci        ASN1_STRING_free(seq);
643e1051a39Sopenharmony_ci        OPENSSL_free(pp);
644e1051a39Sopenharmony_ci        return 0;
645e1051a39Sopenharmony_ci    }
646e1051a39Sopenharmony_ci
647e1051a39Sopenharmony_ci    OPENSSL_free(pp);
648e1051a39Sopenharmony_ci    return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificate,
649e1051a39Sopenharmony_ci                                      V_ASN1_SEQUENCE, seq);
650e1051a39Sopenharmony_ci}
651e1051a39Sopenharmony_ci
652e1051a39Sopenharmony_cistatic int ossl_ess_add1_signing_cert_v2(PKCS7_SIGNER_INFO *si,
653e1051a39Sopenharmony_ci                                         const ESS_SIGNING_CERT_V2 *sc)
654e1051a39Sopenharmony_ci{
655e1051a39Sopenharmony_ci    ASN1_STRING *seq = NULL;
656e1051a39Sopenharmony_ci    int len = i2d_ESS_SIGNING_CERT_V2(sc, NULL);
657e1051a39Sopenharmony_ci    unsigned char *p, *pp = OPENSSL_malloc(len);
658e1051a39Sopenharmony_ci
659e1051a39Sopenharmony_ci    if (pp == NULL)
660e1051a39Sopenharmony_ci        return 0;
661e1051a39Sopenharmony_ci
662e1051a39Sopenharmony_ci    p = pp;
663e1051a39Sopenharmony_ci    i2d_ESS_SIGNING_CERT_V2(sc, &p);
664e1051a39Sopenharmony_ci    if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
665e1051a39Sopenharmony_ci        ASN1_STRING_free(seq);
666e1051a39Sopenharmony_ci        OPENSSL_free(pp);
667e1051a39Sopenharmony_ci        return 0;
668e1051a39Sopenharmony_ci    }
669e1051a39Sopenharmony_ci
670e1051a39Sopenharmony_ci    OPENSSL_free(pp);
671e1051a39Sopenharmony_ci    return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificateV2,
672e1051a39Sopenharmony_ci                                      V_ASN1_SEQUENCE, seq);
673e1051a39Sopenharmony_ci}
674e1051a39Sopenharmony_ci
675e1051a39Sopenharmony_cistatic int ts_RESP_sign(TS_RESP_CTX *ctx)
676e1051a39Sopenharmony_ci{
677e1051a39Sopenharmony_ci    int ret = 0;
678e1051a39Sopenharmony_ci    PKCS7 *p7 = NULL;
679e1051a39Sopenharmony_ci    PKCS7_SIGNER_INFO *si;
680e1051a39Sopenharmony_ci    STACK_OF(X509) *certs;      /* Certificates to include in sc. */
681e1051a39Sopenharmony_ci    ESS_SIGNING_CERT_V2 *sc2 = NULL;
682e1051a39Sopenharmony_ci    ESS_SIGNING_CERT *sc = NULL;
683e1051a39Sopenharmony_ci    ASN1_OBJECT *oid;
684e1051a39Sopenharmony_ci    BIO *p7bio = NULL;
685e1051a39Sopenharmony_ci    int i;
686e1051a39Sopenharmony_ci    EVP_MD *signer_md = NULL;
687e1051a39Sopenharmony_ci
688e1051a39Sopenharmony_ci    if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
689e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
690e1051a39Sopenharmony_ci        goto err;
691e1051a39Sopenharmony_ci    }
692e1051a39Sopenharmony_ci
693e1051a39Sopenharmony_ci    if ((p7 = PKCS7_new_ex(ctx->libctx, ctx->propq)) == NULL) {
694e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
695e1051a39Sopenharmony_ci        goto err;
696e1051a39Sopenharmony_ci    }
697e1051a39Sopenharmony_ci    if (!PKCS7_set_type(p7, NID_pkcs7_signed))
698e1051a39Sopenharmony_ci        goto err;
699e1051a39Sopenharmony_ci    if (!ASN1_INTEGER_set(p7->d.sign->version, 3))
700e1051a39Sopenharmony_ci        goto err;
701e1051a39Sopenharmony_ci
702e1051a39Sopenharmony_ci    if (ctx->request->cert_req) {
703e1051a39Sopenharmony_ci        PKCS7_add_certificate(p7, ctx->signer_cert);
704e1051a39Sopenharmony_ci        if (ctx->certs) {
705e1051a39Sopenharmony_ci            for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
706e1051a39Sopenharmony_ci                X509 *cert = sk_X509_value(ctx->certs, i);
707e1051a39Sopenharmony_ci                PKCS7_add_certificate(p7, cert);
708e1051a39Sopenharmony_ci            }
709e1051a39Sopenharmony_ci        }
710e1051a39Sopenharmony_ci    }
711e1051a39Sopenharmony_ci
712e1051a39Sopenharmony_ci    if (ctx->signer_md == NULL)
713e1051a39Sopenharmony_ci        signer_md = EVP_MD_fetch(ctx->libctx, "SHA256", ctx->propq);
714e1051a39Sopenharmony_ci    else if (EVP_MD_get0_provider(ctx->signer_md) == NULL)
715e1051a39Sopenharmony_ci        signer_md = EVP_MD_fetch(ctx->libctx, EVP_MD_get0_name(ctx->signer_md),
716e1051a39Sopenharmony_ci                                 ctx->propq);
717e1051a39Sopenharmony_ci    else
718e1051a39Sopenharmony_ci        signer_md = (EVP_MD *)ctx->signer_md;
719e1051a39Sopenharmony_ci
720e1051a39Sopenharmony_ci    if ((si = PKCS7_add_signature(p7, ctx->signer_cert,
721e1051a39Sopenharmony_ci                                  ctx->signer_key, signer_md)) == NULL) {
722e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
723e1051a39Sopenharmony_ci        goto err;
724e1051a39Sopenharmony_ci    }
725e1051a39Sopenharmony_ci
726e1051a39Sopenharmony_ci    oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
727e1051a39Sopenharmony_ci    if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
728e1051a39Sopenharmony_ci                                    V_ASN1_OBJECT, oid)) {
729e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
730e1051a39Sopenharmony_ci        goto err;
731e1051a39Sopenharmony_ci    }
732e1051a39Sopenharmony_ci
733e1051a39Sopenharmony_ci    certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
734e1051a39Sopenharmony_ci    if (ctx->ess_cert_id_digest == NULL
735e1051a39Sopenharmony_ci        || EVP_MD_is_a(ctx->ess_cert_id_digest, SN_sha1)) {
736e1051a39Sopenharmony_ci        if ((sc = OSSL_ESS_signing_cert_new_init(ctx->signer_cert,
737e1051a39Sopenharmony_ci                                                 certs, 0)) == NULL)
738e1051a39Sopenharmony_ci            goto err;
739e1051a39Sopenharmony_ci
740e1051a39Sopenharmony_ci        if (!ossl_ess_add1_signing_cert(si, sc)) {
741e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
742e1051a39Sopenharmony_ci            goto err;
743e1051a39Sopenharmony_ci        }
744e1051a39Sopenharmony_ci    } else {
745e1051a39Sopenharmony_ci        sc2 = OSSL_ESS_signing_cert_v2_new_init(ctx->ess_cert_id_digest,
746e1051a39Sopenharmony_ci                                                ctx->signer_cert, certs, 0);
747e1051a39Sopenharmony_ci        if (sc2 == NULL)
748e1051a39Sopenharmony_ci            goto err;
749e1051a39Sopenharmony_ci
750e1051a39Sopenharmony_ci        if (!ossl_ess_add1_signing_cert_v2(si, sc2)) {
751e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR);
752e1051a39Sopenharmony_ci            goto err;
753e1051a39Sopenharmony_ci        }
754e1051a39Sopenharmony_ci    }
755e1051a39Sopenharmony_ci
756e1051a39Sopenharmony_ci    if (!ts_TST_INFO_content_new(p7))
757e1051a39Sopenharmony_ci        goto err;
758e1051a39Sopenharmony_ci    if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
759e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
760e1051a39Sopenharmony_ci        goto err;
761e1051a39Sopenharmony_ci    }
762e1051a39Sopenharmony_ci    if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) {
763e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_TS_DATASIGN);
764e1051a39Sopenharmony_ci        goto err;
765e1051a39Sopenharmony_ci    }
766e1051a39Sopenharmony_ci    if (!PKCS7_dataFinal(p7, p7bio)) {
767e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_TS, TS_R_TS_DATASIGN);
768e1051a39Sopenharmony_ci        goto err;
769e1051a39Sopenharmony_ci    }
770e1051a39Sopenharmony_ci    TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
771e1051a39Sopenharmony_ci    p7 = NULL;                  /* Ownership is lost. */
772e1051a39Sopenharmony_ci    ctx->tst_info = NULL;       /* Ownership is lost. */
773e1051a39Sopenharmony_ci
774e1051a39Sopenharmony_ci    ret = 1;
775e1051a39Sopenharmony_ci err:
776e1051a39Sopenharmony_ci    if (signer_md != ctx->signer_md)
777e1051a39Sopenharmony_ci        EVP_MD_free(signer_md);
778e1051a39Sopenharmony_ci
779e1051a39Sopenharmony_ci    if (!ret)
780e1051a39Sopenharmony_ci        TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
781e1051a39Sopenharmony_ci                                         "Error during signature "
782e1051a39Sopenharmony_ci                                         "generation.");
783e1051a39Sopenharmony_ci    BIO_free_all(p7bio);
784e1051a39Sopenharmony_ci    ESS_SIGNING_CERT_V2_free(sc2);
785e1051a39Sopenharmony_ci    ESS_SIGNING_CERT_free(sc);
786e1051a39Sopenharmony_ci    PKCS7_free(p7);
787e1051a39Sopenharmony_ci    return ret;
788e1051a39Sopenharmony_ci}
789e1051a39Sopenharmony_ci
790e1051a39Sopenharmony_cistatic int ts_TST_INFO_content_new(PKCS7 *p7)
791e1051a39Sopenharmony_ci{
792e1051a39Sopenharmony_ci    PKCS7 *ret = NULL;
793e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *octet_string = NULL;
794e1051a39Sopenharmony_ci
795e1051a39Sopenharmony_ci    /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
796e1051a39Sopenharmony_ci    if ((ret = PKCS7_new()) == NULL)
797e1051a39Sopenharmony_ci        goto err;
798e1051a39Sopenharmony_ci    if ((ret->d.other = ASN1_TYPE_new()) == NULL)
799e1051a39Sopenharmony_ci        goto err;
800e1051a39Sopenharmony_ci    ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
801e1051a39Sopenharmony_ci    if ((octet_string = ASN1_OCTET_STRING_new()) == NULL)
802e1051a39Sopenharmony_ci        goto err;
803e1051a39Sopenharmony_ci    ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
804e1051a39Sopenharmony_ci    octet_string = NULL;
805e1051a39Sopenharmony_ci
806e1051a39Sopenharmony_ci    /* Add encapsulated content to signed PKCS7 structure. */
807e1051a39Sopenharmony_ci    if (!PKCS7_set_content(p7, ret))
808e1051a39Sopenharmony_ci        goto err;
809e1051a39Sopenharmony_ci
810e1051a39Sopenharmony_ci    return 1;
811e1051a39Sopenharmony_ci err:
812e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(octet_string);
813e1051a39Sopenharmony_ci    PKCS7_free(ret);
814e1051a39Sopenharmony_ci    return 0;
815e1051a39Sopenharmony_ci}
816e1051a39Sopenharmony_ci
817e1051a39Sopenharmony_cistatic ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
818e1051a39Sopenharmony_ci        ASN1_GENERALIZEDTIME *asn1_time, long sec, long usec,
819e1051a39Sopenharmony_ci        unsigned precision)
820e1051a39Sopenharmony_ci{
821e1051a39Sopenharmony_ci    time_t time_sec = (time_t)sec;
822e1051a39Sopenharmony_ci    struct tm *tm = NULL, tm_result;
823e1051a39Sopenharmony_ci    char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
824e1051a39Sopenharmony_ci    char *p = genTime_str;
825e1051a39Sopenharmony_ci    char *p_end = genTime_str + sizeof(genTime_str);
826e1051a39Sopenharmony_ci
827e1051a39Sopenharmony_ci    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
828e1051a39Sopenharmony_ci        goto err;
829e1051a39Sopenharmony_ci
830e1051a39Sopenharmony_ci    if ((tm = OPENSSL_gmtime(&time_sec, &tm_result)) == NULL)
831e1051a39Sopenharmony_ci        goto err;
832e1051a39Sopenharmony_ci
833e1051a39Sopenharmony_ci    /*
834e1051a39Sopenharmony_ci     * Put "genTime_str" in GeneralizedTime format.  We work around the
835e1051a39Sopenharmony_ci     * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST
836e1051a39Sopenharmony_ci     * NOT include fractional seconds") and OpenSSL related functions to
837e1051a39Sopenharmony_ci     * meet the rfc3161 requirement: "GeneralizedTime syntax can include
838e1051a39Sopenharmony_ci     * fraction-of-second details".
839e1051a39Sopenharmony_ci     */
840e1051a39Sopenharmony_ci    p += BIO_snprintf(p, p_end - p,
841e1051a39Sopenharmony_ci                      "%04d%02d%02d%02d%02d%02d",
842e1051a39Sopenharmony_ci                      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
843e1051a39Sopenharmony_ci                      tm->tm_hour, tm->tm_min, tm->tm_sec);
844e1051a39Sopenharmony_ci    if (precision > 0) {
845e1051a39Sopenharmony_ci        BIO_snprintf(p, 2 + precision, ".%06ld", usec);
846e1051a39Sopenharmony_ci        p += strlen(p);
847e1051a39Sopenharmony_ci
848e1051a39Sopenharmony_ci        /*
849e1051a39Sopenharmony_ci         * To make things a bit harder, X.690 | ISO/IEC 8825-1 provides the
850e1051a39Sopenharmony_ci         * following restrictions for a DER-encoding, which OpenSSL
851e1051a39Sopenharmony_ci         * (specifically ASN1_GENERALIZEDTIME_check() function) doesn't
852e1051a39Sopenharmony_ci         * support: "The encoding MUST terminate with a "Z" (which means
853e1051a39Sopenharmony_ci         * "Zulu" time). The decimal point element, if present, MUST be the
854e1051a39Sopenharmony_ci         * point option ".". The fractional-seconds elements, if present,
855e1051a39Sopenharmony_ci         * MUST omit all trailing 0's; if the elements correspond to 0, they
856e1051a39Sopenharmony_ci         * MUST be wholly omitted, and the decimal point element also MUST be
857e1051a39Sopenharmony_ci         * omitted."
858e1051a39Sopenharmony_ci         */
859e1051a39Sopenharmony_ci        /*
860e1051a39Sopenharmony_ci         * Remove trailing zeros. The dot guarantees the exit condition of
861e1051a39Sopenharmony_ci         * this loop even if all the digits are zero.
862e1051a39Sopenharmony_ci         */
863e1051a39Sopenharmony_ci        while (*--p == '0')
864e1051a39Sopenharmony_ci             continue;
865e1051a39Sopenharmony_ci        if (*p != '.')
866e1051a39Sopenharmony_ci            ++p;
867e1051a39Sopenharmony_ci    }
868e1051a39Sopenharmony_ci    *p++ = 'Z';
869e1051a39Sopenharmony_ci    *p++ = '\0';
870e1051a39Sopenharmony_ci
871e1051a39Sopenharmony_ci    if (asn1_time == NULL
872e1051a39Sopenharmony_ci        && (asn1_time = ASN1_GENERALIZEDTIME_new()) == NULL)
873e1051a39Sopenharmony_ci        goto err;
874e1051a39Sopenharmony_ci    if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) {
875e1051a39Sopenharmony_ci        ASN1_GENERALIZEDTIME_free(asn1_time);
876e1051a39Sopenharmony_ci        goto err;
877e1051a39Sopenharmony_ci    }
878e1051a39Sopenharmony_ci    return asn1_time;
879e1051a39Sopenharmony_ci
880e1051a39Sopenharmony_ci err:
881e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_TS, TS_R_COULD_NOT_SET_TIME);
882e1051a39Sopenharmony_ci    return NULL;
883e1051a39Sopenharmony_ci}
884e1051a39Sopenharmony_ci
885e1051a39Sopenharmony_ciint TS_RESP_CTX_set_ess_cert_id_digest(TS_RESP_CTX *ctx, const EVP_MD *md)
886e1051a39Sopenharmony_ci{
887e1051a39Sopenharmony_ci    ctx->ess_cert_id_digest = md;
888e1051a39Sopenharmony_ci    return 1;
889e1051a39Sopenharmony_ci}
890