Added support for ESSCertIDv2
authorMarek Klein <kleinmrk@gmail.com>
Tue, 1 Mar 2016 16:32:10 +0000 (16:32 +0000)
committerRichard Levitte <levitte@openssl.org>
Wed, 3 May 2017 07:04:23 +0000 (09:04 +0200)
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/771)

18 files changed:
apps/openssl-vms.cnf
apps/openssl.cnf
apps/ts.c
crypto/objects/obj_dat.h
crypto/objects/obj_mac.num
crypto/objects/objects.txt
crypto/ts/ts_asn1.c
crypto/ts/ts_conf.c
crypto/ts/ts_err.c
crypto/ts/ts_lcl.h
crypto/ts/ts_rsp_sign.c
crypto/ts/ts_rsp_verify.c
doc/man1/ts.pod
include/openssl/obj_mac.h
include/openssl/ts.h
test/CAtsa.cnf
util/indent.pro
util/libcrypto.num

index 0092a650cb97bfbe687b04e9d5d7f929235ca42d..a3ca3930184d49a10b51c1ada98ade97643bb473 100644 (file)
@@ -344,3 +344,5 @@ tsa_name            = yes   # Must the TSA name be included in the reply?
                                # (optional, default: no)
 ess_cert_id_chain      = no    # Must the ESS cert id chain be included?
                                # (optional, default: no)
+ess_cert_id_alg                = sha1  # algorithm to compute certificate
+                               # identifier (optional, default: sha1)
index b3e7444e5f22ef37be939d1cb51dd5dc1aa66acf..32ee9e9fbbba56f8cb8590766796fd0c88c520af 100644 (file)
@@ -344,3 +344,5 @@ tsa_name            = yes   # Must the TSA name be included in the reply?
                                # (optional, default: no)
 ess_cert_id_chain      = no    # Must the ESS cert id chain be included?
                                # (optional, default: no)
+ess_cert_id_alg                = sha1  # algorithm to compute certificate
+                               # identifier (optional, default: sha1)
index 0db6b509f8dd0b31d15760cf4b5e0dab97912ff5..e816c32a1fe643b2bb75e1af43dce8ff14fc59f6 100644 (file)
--- a/apps/ts.c
+++ b/apps/ts.c
@@ -709,6 +709,8 @@ static TS_RESP *create_response(CONF *conf, const char *section, const char *eng
             goto end;
     }
 
+    if (!TS_CONF_set_ess_cert_id_digest(conf, section, resp_ctx))
+        goto end;
     if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx))
         goto end;
     if (!TS_CONF_set_policies(conf, section, resp_ctx))
index 93843e16c2b3923a658fd34836a6e56dd593e9a8..d1942c0fa4195d6df595d114837766dff025c572 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /* Serialized OID's */
-static const unsigned char so[6900] = {
+static const unsigned char so[6911] = {
     0x2A,0x86,0x48,0x86,0xF7,0x0D,                 /* [    0] OBJ_rsadsi */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,            /* [    6] OBJ_pkcs */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,       /* [   13] OBJ_md2 */
@@ -976,9 +976,10 @@ static const unsigned char so[6900] = {
     0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0D,  /* [ 6872] OBJ_aria_256_cfb128 */
     0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0E,  /* [ 6881] OBJ_aria_256_ofb128 */
     0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0F,  /* [ 6890] OBJ_aria_256_ctr */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1E,  /* [ 6899] OBJ_id_smime_aa_signingCertificateV2 */
 };
 
-#define NUM_NID 1086
+#define NUM_NID 1087
 static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"UNDEF", "undefined", NID_undef},
     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2066,9 +2067,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"ARIA-128-CFB8", "aria-128-cfb8", NID_aria_128_cfb8},
     {"ARIA-192-CFB8", "aria-192-cfb8", NID_aria_192_cfb8},
     {"ARIA-256-CFB8", "aria-256-cfb8", NID_aria_256_cfb8},
+    {"id-smime-aa-signingCertificateV2", "id-smime-aa-signingCertificateV2", NID_id_smime_aa_signingCertificateV2, 11, &so[6899]},
 };
 
-#define NUM_SN 1077
+#define NUM_SN 1078
 static const unsigned int sn_objs[NUM_SN] = {
      364,    /* "AD_DVCS" */
      419,    /* "AES-128-CBC" */
@@ -2712,6 +2714,7 @@ static const unsigned int sn_objs[NUM_SN] = {
      213,    /* "id-smime-aa-securityLabel" */
      239,    /* "id-smime-aa-signatureType" */
      223,    /* "id-smime-aa-signingCertificate" */
+    1086,    /* "id-smime-aa-signingCertificateV2" */
      224,    /* "id-smime-aa-smimeEncryptCerts" */
      225,    /* "id-smime-aa-timeStampToken" */
      192,    /* "id-smime-alg" */
@@ -3149,7 +3152,7 @@ static const unsigned int sn_objs[NUM_SN] = {
      160,    /* "x509Crl" */
 };
 
-#define NUM_LN 1077
+#define NUM_LN 1078
 static const unsigned int ln_objs[NUM_LN] = {
      363,    /* "AD Time Stamping" */
      405,    /* "ANSI X9.62" */
@@ -3786,6 +3789,7 @@ static const unsigned int ln_objs[NUM_LN] = {
      213,    /* "id-smime-aa-securityLabel" */
      239,    /* "id-smime-aa-signatureType" */
      223,    /* "id-smime-aa-signingCertificate" */
+    1086,    /* "id-smime-aa-signingCertificateV2" */
      224,    /* "id-smime-aa-smimeEncryptCerts" */
      225,    /* "id-smime-aa-timeStampToken" */
      192,    /* "id-smime-alg" */
@@ -4230,7 +4234,7 @@ static const unsigned int ln_objs[NUM_LN] = {
      125,    /* "zlib compression" */
 };
 
-#define NUM_OBJ 971
+#define NUM_OBJ 972
 static const unsigned int obj_objs[NUM_OBJ] = {
        0,    /* OBJ_undef                        0 */
      181,    /* OBJ_iso                          1 */
@@ -5173,6 +5177,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
      238,    /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */
      239,    /* OBJ_id_smime_aa_signatureType    1 2 840 113549 1 9 16 2 28 */
      240,    /* OBJ_id_smime_aa_dvcs_dvc         1 2 840 113549 1 9 16 2 29 */
+    1086,    /* OBJ_id_smime_aa_signingCertificateV2 1 2 840 113549 1 9 16 2 30 */
      241,    /* OBJ_id_smime_alg_ESDHwith3DES    1 2 840 113549 1 9 16 3 1 */
      242,    /* OBJ_id_smime_alg_ESDHwithRC2     1 2 840 113549 1 9 16 3 2 */
      243,    /* OBJ_id_smime_alg_3DESwrap        1 2 840 113549 1 9 16 3 3 */
index 270e7e51a66738977255976b1cb7b3bc063ad59f..ca8dcdb7e7cc63ab0b93e263b87aba16d343f02f 100644 (file)
@@ -1083,3 +1083,4 @@ aria_256_cfb1             1082
 aria_128_cfb8          1083
 aria_192_cfb8          1084
 aria_256_cfb8          1085
+id_smime_aa_signingCertificateV2               1086
index 442b39caa3a2c93b15b11db9ae116afb931121ab..f19c5ce286fa8b5376960a5dd4c9073051df21c1 100644 (file)
@@ -294,6 +294,7 @@ id-smime-aa 26              : id-smime-aa-ets-certCRLTimestamp
 id-smime-aa 27         : id-smime-aa-ets-archiveTimeStamp
 id-smime-aa 28         : id-smime-aa-signatureType
 id-smime-aa 29         : id-smime-aa-dvcs-dvc
+id-smime-aa 30         : id-smime-aa-signingCertificateV2
 
 # S/MIME Algorithm Identifiers
 # obsolete
index e60675ab72088635149ad24161c2719e3e571404..8707207082c9a14477038fd9aa12f326b01a37ae 100644 (file)
@@ -225,6 +225,23 @@ ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
 IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT)
 IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)
 
+ASN1_SEQUENCE(ESS_CERT_ID_V2) = {
+        ASN1_OPT(ESS_CERT_ID_V2, hash_alg, X509_ALGOR),
+        ASN1_SIMPLE(ESS_CERT_ID_V2, hash, ASN1_OCTET_STRING),
+        ASN1_OPT(ESS_CERT_ID_V2, issuer_serial, ESS_ISSUER_SERIAL)
+} static_ASN1_SEQUENCE_END(ESS_CERT_ID_V2)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID_V2)
+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID_V2)
+
+ASN1_SEQUENCE(ESS_SIGNING_CERT_V2) = {
+        ASN1_SEQUENCE_OF(ESS_SIGNING_CERT_V2, cert_ids, ESS_CERT_ID_V2),
+        ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT_V2, policy_info, POLICYINFO)
+} static_ASN1_SEQUENCE_END(ESS_SIGNING_CERT_V2)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT_V2)
+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2)
+
 /* Getting encapsulated TS_TST_INFO object from PKCS7. */
 TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token)
 {
index f5f3934dfd48bf3122c7f46b55570fd05fd5ebf0..625089a59bf90c7fab87f68d99a556c9f5722b92 100644 (file)
@@ -37,6 +37,7 @@
 #define ENV_CLOCK_PRECISION_DIGITS      "clock_precision_digits"
 #define ENV_VALUE_YES                   "yes"
 #define ENV_VALUE_NO                    "no"
+#define ENV_ESS_CERT_ID_ALG             "ess_cert_id_alg"
 
 /* Function definitions for certificate and key loading. */
 
@@ -466,3 +467,27 @@ int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
     return ts_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN,
                             TS_ESS_CERT_ID_CHAIN, ctx);
 }
+
+int TS_CONF_set_ess_cert_id_digest(CONF *conf, const char *section,
+                                   TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    const EVP_MD *cert_md = NULL;
+    const char *md = NCONF_get_string(conf, section, ENV_ESS_CERT_ID_ALG);
+
+    if (md == NULL)
+        md = "sha1";
+
+    cert_md = EVP_get_digestbyname(md);
+    if (cert_md == NULL) {
+        ts_CONF_invalid(section, ENV_ESS_CERT_ID_ALG);
+        goto err;
+    }
+
+    if (!TS_RESP_CTX_set_ess_cert_id_digest(ctx, cert_md))
+        goto err;
+
+    ret = 1;
+err:
+    return ret;
+}
index a6d73a174b25afec9814ffcb36f5a6ce4016055c..5aed0461b996e90c65f9ca90a744ee303a7bfbea 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -22,8 +22,12 @@ static ERR_STRING_DATA TS_str_functs[] = {
     {ERR_FUNC(TS_F_DEF_SERIAL_CB), "def_serial_cb"},
     {ERR_FUNC(TS_F_DEF_TIME_CB), "def_time_cb"},
     {ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT), "ESS_add_signing_cert"},
+    {ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT_V2), "ess_add_signing_cert_v2"},
     {ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT), "ess_CERT_ID_new_init"},
+    {ERR_FUNC(TS_F_ESS_CERT_ID_V2_NEW_INIT), "ess_cert_id_new_init"},
     {ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT), "ess_SIGNING_CERT_new_init"},
+    {ERR_FUNC(TS_F_ESS_SIGNING_CERT_V2_NEW_INIT),
+     "ess_signing_cert_V2_new_init"},
     {ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN), "int_ts_RESP_verify_token"},
     {ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"},
     {ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"},
@@ -92,6 +96,8 @@ static ERR_STRING_DATA TS_str_reasons[] = {
     {ERR_REASON(TS_R_DETACHED_CONTENT), "detached content"},
     {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),
      "ess add signing cert error"},
+    {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR),
+     "ess add signing cert v2 error"},
     {ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),
      "ess signing certificate error"},
     {ERR_REASON(TS_R_INVALID_NULL_POINTER), "invalid null pointer"},
index d0c3cf816e00a241505e64c37f228f65440bcc7c..771784fef7c8d6c4ccea48c25929dbb0b1114cc4 100644 (file)
@@ -131,11 +131,39 @@ struct ESS_signing_cert {
     STACK_OF(POLICYINFO) *policy_info;
 };
 
+/*-
+ * ESSCertIDv2 ::=  SEQUENCE {
+ *        hashAlgorithm           AlgorithmIdentifier
+ *                DEFAULT {algorithm id-sha256},
+ *        certHash                Hash,
+ *        issuerSerial            IssuerSerial OPTIONAL
+ * }
+ */
+
+struct ESS_cert_id_v2_st {
+    X509_ALGOR *hash_alg;       /* Default: SHA-256 */
+    ASN1_OCTET_STRING *hash;
+    ESS_ISSUER_SERIAL *issuer_serial;
+};
+
+/*-
+ * SigningCertificateV2 ::= SEQUENCE {
+ *        certs                   SEQUENCE OF ESSCertIDv2,
+ *        policies                SEQUENCE OF PolicyInformation OPTIONAL
+ * }
+ */
+
+struct ESS_signing_cert_v2_st {
+    STACK_OF(ESS_CERT_ID_V2) *cert_ids;
+    STACK_OF(POLICYINFO) *policy_info;
+};
+
 
 struct TS_resp_ctx {
     X509 *signer_cert;
     EVP_PKEY *signer_key;
     const EVP_MD *signer_md;
+    const EVP_MD *ess_cert_id_digest;
     STACK_OF(X509) *certs;      /* Certs to include in signed data. */
     STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
     ASN1_OBJECT *default_policy; /* It may appear in policies, too. */
index aea7b922a34dc8be76fecd3a75c05b9c0018cd3d..76011ada59ab1ad4b8bf623decf8fceee0c23c22 100644 (file)
@@ -35,7 +35,16 @@ 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 int ess_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
+
+static ESS_SIGNING_CERT_V2 *ess_signing_cert_v2_new_init(const EVP_MD *hash_alg,
+                                                         X509 *signcert,
+                                                         STACK_OF(X509)
+                                                         *certs);
+static ESS_CERT_ID_V2 *ess_cert_id_v2_new_init(const EVP_MD *hash_alg,
+                                               X509 *cert, int issuer_needed);
+static int ess_add_signing_cert_v2(PKCS7_SIGNER_INFO *si,
+                                   ESS_SIGNING_CERT_V2 *sc);
 
 static ASN1_GENERALIZEDTIME
 *TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long,
@@ -628,6 +637,7 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx)
     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;
@@ -671,11 +681,24 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx)
     }
 
     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 == EVP_sha1()) {
+        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;
+        }
+    } else {
+        sc2 = ess_signing_cert_v2_new_init(ctx->ess_cert_id_digest,
+                                           ctx->signer_cert, certs);
+        if (sc2 == NULL)
+            goto err;
+
+        if (!ess_add_signing_cert_v2(si, sc2)) {
+            TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR);
+            goto err;
+        }
     }
 
     if (!ts_TST_INFO_content_new(p7))
@@ -703,6 +726,7 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx)
                                          "Error during signature "
                                          "generation.");
     BIO_free_all(p7bio);
+    ESS_SIGNING_CERT_V2_free(sc2);
     ESS_SIGNING_CERT_free(sc);
     PKCS7_free(p7);
     return ret;
@@ -806,7 +830,7 @@ 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)
+static int ess_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
 {
     ASN1_STRING *seq = NULL;
     unsigned char *p, *pp = NULL;
@@ -835,9 +859,133 @@ static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
     return 0;
 }
 
-static ASN1_GENERALIZEDTIME
-*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,
-                                    long sec, long usec, unsigned precision)
+static ESS_SIGNING_CERT_V2 *ess_signing_cert_v2_new_init(const EVP_MD *hash_alg,
+                                                         X509 *signcert,
+                                                         STACK_OF(X509) *certs)
+{
+    ESS_CERT_ID_V2 *cid = NULL;
+    ESS_SIGNING_CERT_V2 *sc = NULL;
+    int i;
+
+    if ((sc = ESS_SIGNING_CERT_V2_new()) == NULL)
+        goto err;
+    if ((cid = ess_cert_id_v2_new_init(hash_alg, signcert, 0)) == NULL)
+        goto err;
+    if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid))
+        goto err;
+    cid = NULL;
+
+    for (i = 0; i < sk_X509_num(certs); ++i) {
+        X509 *cert = sk_X509_value(certs, i);
+
+        if ((cid = ess_cert_id_v2_new_init(hash_alg, cert, 1)) == NULL)
+            goto err;
+        if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid))
+            goto err;
+        cid = NULL;
+    }
+
+    return sc;
+ err:
+    ESS_SIGNING_CERT_V2_free(sc);
+    ESS_CERT_ID_V2_free(cid);
+    TSerr(TS_F_ESS_SIGNING_CERT_V2_NEW_INIT, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+static ESS_CERT_ID_V2 *ess_cert_id_v2_new_init(const EVP_MD *hash_alg,
+                                               X509 *cert, int issuer_needed)
+{
+    ESS_CERT_ID_V2 *cid = NULL;
+    GENERAL_NAME *name = NULL;
+    unsigned char hash[EVP_MAX_MD_SIZE];
+    unsigned int hash_len = sizeof(hash);
+    X509_ALGOR *alg = NULL;
+
+    memset(hash, 0, sizeof(hash));
+
+    if ((cid = ESS_CERT_ID_V2_new()) == NULL)
+        goto err;
+
+    if (hash_alg != EVP_sha256()) {
+        alg = X509_ALGOR_new();
+        if (alg == NULL)
+            goto err;
+        X509_ALGOR_set_md(alg, hash_alg);
+        if (alg->algorithm == NULL)
+            goto err;
+        cid->hash_alg = alg;
+        alg = NULL;
+    } else {
+        cid->hash_alg = NULL;
+    }
+
+    if (!X509_digest(cert, hash_alg, hash, &hash_len))
+        goto err;
+
+    if (!ASN1_OCTET_STRING_set(cid->hash, hash, hash_len))
+        goto err;
+
+    if (issuer_needed) {
+        if ((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);
+        cid->issuer_serial->serial =
+                ASN1_INTEGER_dup(X509_get_serialNumber(cert));
+        if (cid->issuer_serial->serial == NULL)
+            goto err;
+    }
+
+    return cid;
+ err:
+    X509_ALGOR_free(alg);
+    GENERAL_NAME_free(name);
+    ESS_CERT_ID_V2_free(cid);
+    TSerr(TS_F_ESS_CERT_ID_V2_NEW_INIT, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+static int ess_add_signing_cert_v2(PKCS7_SIGNER_INFO *si,
+                                   ESS_SIGNING_CERT_V2 *sc)
+{
+    ASN1_STRING *seq = NULL;
+    unsigned char *p, *pp = NULL;
+    int len = i2d_ESS_SIGNING_CERT_V2(sc, NULL);
+
+    if ((pp = OPENSSL_malloc(len)) == NULL) {
+        TSerr(TS_F_ESS_ADD_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    p = pp;
+    i2d_ESS_SIGNING_CERT_V2(sc, &p);
+    if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
+        TSerr(TS_F_ESS_ADD_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    OPENSSL_free(pp);
+    pp = NULL;
+    return PKCS7_add_signed_attribute(si,
+                                      NID_id_smime_aa_signingCertificateV2,
+                                      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)
 {
     time_t time_sec = (time_t)sec;
     struct tm *tm = NULL;
@@ -902,3 +1050,9 @@ static ASN1_GENERALIZEDTIME
     TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, 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;
+}
index 66f5be6f69d75f159e7f4c67bca98f8f68f82b05..9deda81b07fb8267ffe26b445e25b500e0455b74 100644 (file)
@@ -37,6 +37,8 @@ static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
 static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
 static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names,
                         GENERAL_NAME *name);
+static int ts_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert);
+static ESS_SIGNING_CERT_V2 *ess_get_signing_cert_v2(PKCS7_SIGNER_INFO *si);
 
 /*
  * This must be large enough to hold all values in ts_status_text (with
@@ -201,34 +203,57 @@ static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
 {
     ESS_SIGNING_CERT *ss = ess_get_signing_cert(si);
     STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
+    ESS_SIGNING_CERT_V2 *ssv2 = ess_get_signing_cert_v2(si);
+    STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2 = NULL;
     X509 *cert;
     int i = 0;
     int ret = 0;
 
-    if (!ss)
-        goto err;
-    cert_ids = ss->cert_ids;
-    cert = sk_X509_value(chain, 0);
-    if (ts_find_cert(cert_ids, cert) != 0)
-        goto err;
+    if (ss != NULL) {
+        cert_ids = ss->cert_ids;
+        cert = sk_X509_value(chain, 0);
+        if (ts_find_cert(cert_ids, cert) != 0)
+            goto err;
 
-    /*
-     * Check the other certificates of the chain if there are more than one
-     * certificate ids in cert_ids.
-     */
-    if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
-        for (i = 1; i < sk_X509_num(chain); ++i) {
-            cert = sk_X509_value(chain, i);
-            if (ts_find_cert(cert_ids, cert) < 0)
-                goto err;
+        /*
+         * Check the other certificates of the chain if there are more than one
+         * certificate ids in cert_ids.
+         */
+        if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
+            for (i = 1; i < sk_X509_num(chain); ++i) {
+                cert = sk_X509_value(chain, i);
+                if (ts_find_cert(cert_ids, cert) < 0)
+                    goto err;
+            }
         }
+    } else if (ssv2 != NULL) {
+        cert_ids_v2 = ssv2->cert_ids;
+        cert = sk_X509_value(chain, 0);
+        if (ts_find_cert_v2(cert_ids_v2, cert) != 0)
+            goto err;
+
+        /*
+         * Check the other certificates of the chain if there are more than one
+         * certificate ids in cert_ids.
+         */
+        if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) {
+            for (i = 1; i < sk_X509_num(chain); ++i) {
+                cert = sk_X509_value(chain, i);
+                if (ts_find_cert_v2(cert_ids_v2, cert) < 0)
+                    goto err;
+            }
+        }
+    } else {
+        goto err;
     }
+
     ret = 1;
  err:
     if (!ret)
         TSerr(TS_F_TS_CHECK_SIGNING_CERTS,
               TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
     ESS_SIGNING_CERT_free(ss);
+    ESS_SIGNING_CERT_V2_free(ssv2);
     return ret;
 }
 
@@ -243,6 +268,18 @@ static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si)
     return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
 }
 
+static ESS_SIGNING_CERT_V2 *ess_get_signing_cert_v2(PKCS7_SIGNER_INFO *si)
+{
+    ASN1_TYPE *attr;
+    const unsigned char *p;
+
+    attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificateV2);
+    if (attr == NULL)
+        return NULL;
+    p = attr->value.sequence->data;
+    return d2i_ESS_SIGNING_CERT_V2(NULL, &p, attr->value.sequence->length);
+}
+
 /* Returns < 0 if certificate is not found, certificate index otherwise. */
 static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
 {
@@ -272,6 +309,38 @@ static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
     return -1;
 }
 
+/* Returns < 0 if certificate is not found, certificate index otherwise. */
+static int ts_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert)
+{
+    int i;
+    unsigned char cert_digest[EVP_MAX_MD_SIZE];
+    unsigned int len;
+
+    /* Look for cert in the cert_ids vector. */
+    for (i = 0; i < sk_ESS_CERT_ID_V2_num(cert_ids); ++i) {
+        ESS_CERT_ID_V2 *cid = sk_ESS_CERT_ID_V2_value(cert_ids, i);
+        const EVP_MD *md;
+
+        if (cid->hash_alg != NULL)
+            md = EVP_get_digestbyobj(cid->hash_alg->algorithm);
+        else
+            md = EVP_sha256();
+
+        X509_digest(cert, md, cert_digest, &len);
+        if (cid->hash->length != (int)len)
+            return -1;
+
+        if (memcmp(cid->hash->data, cert_digest, cid->hash->length) == 0) {
+            ESS_ISSUER_SERIAL *is = cid->issuer_serial;
+
+            if (is == NULL || !ts_issuer_serial_cmp(is, cert))
+                return i;
+        }
+    }
+
+    return -1;
+}
+
 static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert)
 {
     GENERAL_NAME *issuer;
index 2ec98370752c4a0e7a45b983c2a18deb4ddb3c1d..d469b231960036c4cb05d12ffcaab05715a71fc0 100644 (file)
@@ -503,6 +503,11 @@ be included in the SigningCertificate signed attribute. If this
 variable is set to no, only the signing certificate identifier is
 included. Default is no. (Optional)
 
+=item B<ess_cert_id_alg>
+
+This option specifies the hash function to be used to calculate the TSA's
+public key certificate identifier. Default is sha1. (Optional)
+
 =back
 
 =head1 EXAMPLES
@@ -605,9 +610,6 @@ You could also look at the 'test' directory for more examples.
 
 =for comment foreign manuals: procmail(1), perl(1)
 
-If you find any bugs or you have suggestions please write to
-Zoltan Glozik <zglozik@opentsa.org>. Known issues:
-
 =over 2
 
 =item *
index d9c45dee015dc6ee485532016be17de7600768d0..3762e514cb61606f7695f272bbadd696b12d2b9f 100644 (file)
 #define NID_id_smime_aa_dvcs_dvc                240
 #define OBJ_id_smime_aa_dvcs_dvc                OBJ_id_smime_aa,29L
 
+#define SN_id_smime_aa_signingCertificateV2             "id-smime-aa-signingCertificateV2"
+#define NID_id_smime_aa_signingCertificateV2            1086
+#define OBJ_id_smime_aa_signingCertificateV2            OBJ_id_smime_aa,30L
+
 #define SN_id_smime_alg_ESDHwith3DES            "id-smime-alg-ESDHwith3DES"
 #define NID_id_smime_alg_ESDHwith3DES           241
 #define OBJ_id_smime_alg_ESDHwith3DES           OBJ_id_smime_alg,1L
index a5659825fbeae52a91216d7db683f5191a399f68..ce8341038d17a95d80a3bd7ec6f94954777ef7fb 100644 (file)
@@ -61,6 +61,11 @@ typedef struct ESS_signing_cert ESS_SIGNING_CERT;
 
 DEFINE_STACK_OF(ESS_CERT_ID)
 
+typedef struct ESS_cert_id_v2_st ESS_CERT_ID_V2;
+typedef struct ESS_signing_cert_v2_st ESS_SIGNING_CERT_V2;
+
+DEFINE_STACK_OF(ESS_CERT_ID_V2)
+
 typedef struct TS_resp_st TS_RESP;
 
 TS_REQ *TS_REQ_new(void);
@@ -156,6 +161,21 @@ ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
                                        const unsigned char **pp, long length);
 ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);
 
+ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new(void);
+void ESS_CERT_ID_V2_free(ESS_CERT_ID_V2 *a);
+int i2d_ESS_CERT_ID_V2(const ESS_CERT_ID_V2 *a, unsigned char **pp);
+ESS_CERT_ID_V2 *d2i_ESS_CERT_ID_V2(ESS_CERT_ID_V2 **a,
+                                   const unsigned char **pp, long length);
+ESS_CERT_ID_V2 *ESS_CERT_ID_V2_dup(ESS_CERT_ID_V2 *a);
+
+ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_new(void);
+void ESS_SIGNING_CERT_V2_free(ESS_SIGNING_CERT_V2 *a);
+int i2d_ESS_SIGNING_CERT_V2(const ESS_SIGNING_CERT_V2 *a, unsigned char **pp);
+ESS_SIGNING_CERT_V2 *d2i_ESS_SIGNING_CERT_V2(ESS_SIGNING_CERT_V2 **a,
+                                             const unsigned char **pp,
+                                             long length);
+ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_dup(ESS_SIGNING_CERT_V2 *a);
+
 int TS_REQ_set_version(TS_REQ *a, long version);
 long TS_REQ_get_version(const TS_REQ *a);
 
@@ -316,6 +336,7 @@ int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
 
 int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx,
                                   const EVP_MD *signer_digest);
+int TS_RESP_CTX_set_ess_cert_id_digest(TS_RESP_CTX *ctx, const EVP_MD *md);
 
 /* This parameter must be set. */
 int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy);
@@ -528,6 +549,8 @@ int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
 int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
 int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
                                   TS_RESP_CTX *ctx);
+int TS_CONF_set_ess_cert_id_digest(CONF *conf, const char *section,
+                                      TS_RESP_CTX *ctx);
 
 /* -------------------------------------------------- */
 /* BEGIN ERROR CODES */
@@ -544,8 +567,11 @@ int ERR_load_TS_strings(void);
 # define TS_F_DEF_SERIAL_CB                               110
 # define TS_F_DEF_TIME_CB                                 111
 # define TS_F_ESS_ADD_SIGNING_CERT                        112
+# define TS_F_ESS_ADD_SIGNING_CERT_V2                     147
 # define TS_F_ESS_CERT_ID_NEW_INIT                        113
+# define TS_F_ESS_CERT_ID_V2_NEW_INIT                     156
 # define TS_F_ESS_SIGNING_CERT_NEW_INIT                   114
+# define TS_F_ESS_SIGNING_CERT_V2_NEW_INIT                157
 # define TS_F_INT_TS_RESP_VERIFY_TOKEN                    149
 # define TS_F_PKCS7_TO_TS_TST_INFO                        148
 # define TS_F_TS_ACCURACY_SET_MICROS                      115
@@ -606,6 +632,7 @@ int ERR_load_TS_strings(void);
 # define TS_R_COULD_NOT_SET_TIME                          115
 # define TS_R_DETACHED_CONTENT                            134
 # define TS_R_ESS_ADD_SIGNING_CERT_ERROR                  116
+# define TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR               139
 # define TS_R_ESS_SIGNING_CERTIFICATE_ERROR               101
 # define TS_R_INVALID_NULL_POINTER                        102
 # define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE          117
index ab2f84aa0feb0ca5432ab44402de6e892aab0f18..d1642879be3baee737bc019b2f8e91ad4641ea02 100644 (file)
@@ -144,6 +144,8 @@ tsa_name            = yes   # Must the TSA name be included in the reply?
                                # (optional, default: no)
 ess_cert_id_chain      = yes   # Must the ESS cert id chain be included?
                                # (optional, default: no)
+ess_cert_id_alg                = sha256        # algorithm to compute certificate
+                                       # identifier (optional, default: sha1)
 
 [ tsa_config2 ]
 
index 81590e141ec50598b5b874dfe162c1cc838acb12..c147f97854a277dce5c65b9d7b7affe8aad869f4 100644 (file)
 -T ERR_STATE
 -T ERR_STRING_DATA
 -T ESS_CERT_ID
+-T ESS_CERT_ID_V2
 -T ESS_ISSUER_SERIAL
 -T ESS_SIGNING_CERT
+-T ESS_SIGNING_CERT_V2
 -T EVP_AES_HMAC_SHA1
 -T EVP_AES_HMAC_SHA256
 -T EVP_CIPHER
 -T STACK_OF_ENGINE_
 -T STACK_OF_ENGINE_CLEANUP_ITEM_
 -T STACK_OF_ESS_CERT_ID_
+-T STACK_OF_ESS_CERT_ID_V2_
 -T STACK_OF_EVP_PBE_CTL_
 -T STACK_OF_EVP_PKEY_ASN1_METHOD_
 -T STACK_OF_EVP_PKEY_METHOD_
index b136a73500c08198e2565d5e2f5cc5d8c7cc2dfd..2e820426e92b52093311ba9d8d7b478c0c7ae9ec 100644 (file)
@@ -4276,3 +4276,15 @@ X509_CRL_print_ex                       4218     1_1_1   EXIST::FUNCTION:
 X509_SIG_INFO_get                       4219   1_1_1   EXIST::FUNCTION:
 X509_get_signature_info                 4220   1_1_1   EXIST::FUNCTION:
 X509_SIG_INFO_set                       4221   1_1_1   EXIST::FUNCTION:
+ESS_CERT_ID_V2_free                     4222   1_1_1   EXIST::FUNCTION:TS
+ESS_SIGNING_CERT_V2_new                 4223   1_1_1   EXIST::FUNCTION:TS
+d2i_ESS_SIGNING_CERT_V2                 4224   1_1_1   EXIST::FUNCTION:TS
+i2d_ESS_CERT_ID_V2                      4225   1_1_1   EXIST::FUNCTION:TS
+ESS_CERT_ID_V2_dup                      4226   1_1_1   EXIST::FUNCTION:TS
+TS_RESP_CTX_set_ess_cert_id_digest      4227   1_1_1   EXIST::FUNCTION:TS
+d2i_ESS_CERT_ID_V2                      4228   1_1_1   EXIST::FUNCTION:TS
+i2d_ESS_SIGNING_CERT_V2                 4229   1_1_1   EXIST::FUNCTION:TS
+TS_CONF_set_ess_cert_id_digest          4230   1_1_1   EXIST::FUNCTION:TS
+ESS_SIGNING_CERT_V2_free                4231   1_1_1   EXIST::FUNCTION:TS
+ESS_SIGNING_CERT_V2_dup                 4232   1_1_1   EXIST::FUNCTION:TS
+ESS_CERT_ID_V2_new                      4233   1_1_1   EXIST::FUNCTION:TS