/*
- * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * 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
* https://www.openssl.org/source/license.html
*/
-#include "e_os.h"
-#include "internal/cryptlib.h"
+#include "internal/e_os.h"
#include <openssl/objects.h>
#include <openssl/ts.h>
#include <openssl/pkcs7.h>
#include <openssl/crypto.h>
-#include "ts_local.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);
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;
}
{
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);
{
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);
/* TS_RESP_CTX management functions. */
-TS_RESP_CTX *TS_RESP_CTX_new(void)
+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;
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. */
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);
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, const 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;
}
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;
}
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;
}
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;
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;
}
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) {
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,
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;
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) {
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);
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))
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);
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.");
}
/* 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;
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))
}
}
+ 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 (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)
+ || 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 (!ESS_SIGNING_CERT_add(si, sc)) {
- TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
+ if (!ossl_ess_add1_signing_cert(si, sc)) {
+ ERR_raise(ERR_LIB_TS, 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);
+ sc2 = OSSL_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);
+ 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);
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 "
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;
}