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:
parent
0e534337b2
commit
f0ef20bf38
18 changed files with 396 additions and 34 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ]
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue