Update copyright year
[openssl.git] / crypto / ts / ts_rsp_sign.c
index 313b37ed0616dd72d69868a0f507d257f3ea1bf8..dce50eb451fa708c58fbc0b67ec559b8e9a2f464 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2021 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
@@ -7,15 +7,16 @@
  * 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)
 
@@ -108,7 +109,7 @@ 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(void)
+TS_RESP_CTX *TS_RESP_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq)
 {
     TS_RESP_CTX *ctx;
 
@@ -117,8 +118,15 @@ TS_RESP_CTX *TS_RESP_CTX_new(void)
         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;
@@ -126,14 +134,20 @@ TS_RESP_CTX *TS_RESP_CTX_new(void)
     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. */
@@ -183,7 +197,7 @@ int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy)
 
 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;
 
     return certs == NULL || (ctx->certs = X509_chain_up_ref(certs)) != NULL;
@@ -434,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;
@@ -448,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) {
@@ -470,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);
@@ -612,6 +626,52 @@ 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;
@@ -623,13 +683,14 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx)
     ASN1_OBJECT *oid;
     BIO *p7bio = NULL;
     int i;
+    EVP_MD *signer_md = NULL;
 
     if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
         ERR_raise(ERR_LIB_TS, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
         goto err;
     }
 
-    if ((p7 = PKCS7_new()) == NULL) {
+    if ((p7 = PKCS7_new_ex(ctx->libctx, ctx->propq)) == NULL) {
         ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE);
         goto err;
     }
@@ -648,8 +709,16 @@ 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) {
+                                  ctx->signer_key, signer_md)) == NULL) {
         ERR_raise(ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
         goto err;
     }
@@ -663,21 +732,22 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx)
 
     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)) {
+        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)) {
+        if (!ossl_ess_add1_signing_cert_v2(si, sc2)) {
             ERR_raise(ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR);
             goto err;
         }
@@ -703,6 +773,9 @@ 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 "