/*
* Copyright 2006-2022 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 "internal/e_os.h"
#include <openssl/objects.h>
#include <openssl/ts.h>
#include <openssl/pkcs7.h>
#include <openssl/crypto.h>
#include "internal/cryptlib.h"
#include "internal/sizes.h"
#include "internal/time.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);
static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
static void ts_RESP_CTX_init(TS_RESP_CTX *ctx);
static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
static int ts_RESP_check_request(TS_RESP_CTX *ctx);
static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx);
static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
ASN1_OBJECT *policy);
static int ts_RESP_process_extensions(TS_RESP_CTX *ctx);
static int ts_RESP_sign(TS_RESP_CTX *ctx);
static int ts_TST_INFO_content_new(PKCS7 *p7);
static ASN1_GENERALIZEDTIME
*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long,
unsigned);
/* 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 == NULL)
goto err;
if (!ASN1_INTEGER_set(serial, 1))
goto err;
return serial;
err:
ERR_raise(ERR_LIB_TS, ERR_R_ASN1_LIB);
TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
"Error during serial number generation.");
ASN1_INTEGER_free(serial);
return NULL;
}
static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
long *sec, long *usec)
{
OSSL_TIME t;
struct timeval tv;
t = ossl_time_now();
if (ossl_time_is_zero(t)) {
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);
return 0;
}
tv = ossl_time_to_timeval(t);
*sec = (long int)tv.tv_sec;
*usec = (long int)tv.tv_usec;
return 1;
}
static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
void *data)
{
TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
"Unsupported extension.");
TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
return 0;
}
/* TS_RESP_CTX management functions. */
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)
return NULL;
if (propq != NULL) {
ctx->propq = OPENSSL_strdup(propq);
if (ctx->propq == NULL) {
OPENSSL_free(ctx);
return NULL;
}
}
ctx->libctx = libctx;
ctx->serial_cb = def_serial_cb;
ctx->time_cb = def_time_cb;
ctx->extension_cb = def_extension_cb;
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);
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. */
ASN1_INTEGER_free(ctx->seconds);
ASN1_INTEGER_free(ctx->millis);
ASN1_INTEGER_free(ctx->micros);
OPENSSL_free(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) {
ERR_raise(ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
return 0;
}
X509_free(ctx->signer_cert);
ctx->signer_cert = signer;
X509_up_ref(ctx->signer_cert);
return 1;
}
int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
{
EVP_PKEY_free(ctx->signer_key);
ctx->signer_key =