Added support for ESSCertIDv2

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/771)
This commit is contained in:
Marek Klein 2016-03-01 16:32:10 +00:00 committed by Richard Levitte
parent 0e534337b2
commit f0ef20bf38
18 changed files with 396 additions and 34 deletions

View 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)

View 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)

View file

@ -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))

View 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 */

View 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

View 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

View 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)
{

View 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;
}

View 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"},

View 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. */

View 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;
}

View 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;

View 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 *

View file

@ -932,6 +932,10 @@
#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

View 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

View 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 ]

View file

@ -223,8 +223,10 @@
-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
@ -525,6 +527,7 @@
-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_

View 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