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) # (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included? ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no) # (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) # (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included? ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no) # (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; 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)) if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_policies(conf, section, resp_ctx)) if (!TS_CONF_set_policies(conf, section, resp_ctx))

View File

@ -10,7 +10,7 @@
*/ */
/* Serialized OID's */ /* 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, /* [ 0] OBJ_rsadsi */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ 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,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,0x0E, /* [ 6881] OBJ_aria_256_ofb128 */
0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0F, /* [ 6890] OBJ_aria_256_ctr */ 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] = { static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"UNDEF", "undefined", NID_undef}, {"UNDEF", "undefined", NID_undef},
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, {"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-128-CFB8", "aria-128-cfb8", NID_aria_128_cfb8},
{"ARIA-192-CFB8", "aria-192-cfb8", NID_aria_192_cfb8}, {"ARIA-192-CFB8", "aria-192-cfb8", NID_aria_192_cfb8},
{"ARIA-256-CFB8", "aria-256-cfb8", NID_aria_256_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] = { static const unsigned int sn_objs[NUM_SN] = {
364, /* "AD_DVCS" */ 364, /* "AD_DVCS" */
419, /* "AES-128-CBC" */ 419, /* "AES-128-CBC" */
@ -2712,6 +2714,7 @@ static const unsigned int sn_objs[NUM_SN] = {
213, /* "id-smime-aa-securityLabel" */ 213, /* "id-smime-aa-securityLabel" */
239, /* "id-smime-aa-signatureType" */ 239, /* "id-smime-aa-signatureType" */
223, /* "id-smime-aa-signingCertificate" */ 223, /* "id-smime-aa-signingCertificate" */
1086, /* "id-smime-aa-signingCertificateV2" */
224, /* "id-smime-aa-smimeEncryptCerts" */ 224, /* "id-smime-aa-smimeEncryptCerts" */
225, /* "id-smime-aa-timeStampToken" */ 225, /* "id-smime-aa-timeStampToken" */
192, /* "id-smime-alg" */ 192, /* "id-smime-alg" */
@ -3149,7 +3152,7 @@ static const unsigned int sn_objs[NUM_SN] = {
160, /* "x509Crl" */ 160, /* "x509Crl" */
}; };
#define NUM_LN 1077 #define NUM_LN 1078
static const unsigned int ln_objs[NUM_LN] = { static const unsigned int ln_objs[NUM_LN] = {
363, /* "AD Time Stamping" */ 363, /* "AD Time Stamping" */
405, /* "ANSI X9.62" */ 405, /* "ANSI X9.62" */
@ -3786,6 +3789,7 @@ static const unsigned int ln_objs[NUM_LN] = {
213, /* "id-smime-aa-securityLabel" */ 213, /* "id-smime-aa-securityLabel" */
239, /* "id-smime-aa-signatureType" */ 239, /* "id-smime-aa-signatureType" */
223, /* "id-smime-aa-signingCertificate" */ 223, /* "id-smime-aa-signingCertificate" */
1086, /* "id-smime-aa-signingCertificateV2" */
224, /* "id-smime-aa-smimeEncryptCerts" */ 224, /* "id-smime-aa-smimeEncryptCerts" */
225, /* "id-smime-aa-timeStampToken" */ 225, /* "id-smime-aa-timeStampToken" */
192, /* "id-smime-alg" */ 192, /* "id-smime-alg" */
@ -4230,7 +4234,7 @@ static const unsigned int ln_objs[NUM_LN] = {
125, /* "zlib compression" */ 125, /* "zlib compression" */
}; };
#define NUM_OBJ 971 #define NUM_OBJ 972
static const unsigned int obj_objs[NUM_OBJ] = { static const unsigned int obj_objs[NUM_OBJ] = {
0, /* OBJ_undef 0 */ 0, /* OBJ_undef 0 */
181, /* OBJ_iso 1 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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_128_cfb8 1083
aria_192_cfb8 1084 aria_192_cfb8 1084
aria_256_cfb8 1085 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 27 : id-smime-aa-ets-archiveTimeStamp
id-smime-aa 28 : id-smime-aa-signatureType id-smime-aa 28 : id-smime-aa-signatureType
id-smime-aa 29 : id-smime-aa-dvcs-dvc id-smime-aa 29 : id-smime-aa-dvcs-dvc
id-smime-aa 30 : id-smime-aa-signingCertificateV2
# S/MIME Algorithm Identifiers # S/MIME Algorithm Identifiers
# obsolete # obsolete

View File

@ -225,6 +225,23 @@ ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT) IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT)
IMPLEMENT_ASN1_DUP_FUNCTION(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. */ /* Getting encapsulated TS_TST_INFO object from PKCS7. */
TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) 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_CLOCK_PRECISION_DIGITS "clock_precision_digits"
#define ENV_VALUE_YES "yes" #define ENV_VALUE_YES "yes"
#define ENV_VALUE_NO "no" #define ENV_VALUE_NO "no"
#define ENV_ESS_CERT_ID_ALG "ess_cert_id_alg"
/* Function definitions for certificate and key loading. */ /* 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, return ts_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN,
TS_ESS_CERT_ID_CHAIN, ctx); 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 * 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 * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * 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_SERIAL_CB), "def_serial_cb"},
{ERR_FUNC(TS_F_DEF_TIME_CB), "def_time_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), "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_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_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_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_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"},
{ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"}, {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_DETACHED_CONTENT), "detached content"},
{ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR), {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),
"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), {ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),
"ess signing certificate error"}, "ess signing certificate error"},
{ERR_REASON(TS_R_INVALID_NULL_POINTER), "invalid null pointer"}, {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; 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 { struct TS_resp_ctx {
X509 *signer_cert; X509 *signer_cert;
EVP_PKEY *signer_key; EVP_PKEY *signer_key;
const EVP_MD *signer_md; const EVP_MD *signer_md;
const EVP_MD *ess_cert_id_digest;
STACK_OF(X509) *certs; /* Certs to include in signed data. */ STACK_OF(X509) *certs; /* Certs to include in signed data. */
STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */ STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
ASN1_OBJECT *default_policy; /* It may appear in policies, too. */ 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); STACK_OF(X509) *certs);
static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed); 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 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 static ASN1_GENERALIZEDTIME
*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long, *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 *p7 = NULL;
PKCS7_SIGNER_INFO *si; PKCS7_SIGNER_INFO *si;
STACK_OF(X509) *certs; /* Certificates to include in sc. */ STACK_OF(X509) *certs; /* Certificates to include in sc. */
ESS_SIGNING_CERT_V2 *sc2 = NULL;
ESS_SIGNING_CERT *sc = NULL; ESS_SIGNING_CERT *sc = NULL;
ASN1_OBJECT *oid; ASN1_OBJECT *oid;
BIO *p7bio = NULL; BIO *p7bio = NULL;
@ -671,12 +681,25 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx)
} }
certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL; certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
if (ctx->ess_cert_id_digest == EVP_sha1()) {
if ((sc = ess_SIGNING_CERT_new_init(ctx->signer_cert, certs)) == NULL) if ((sc = ess_SIGNING_CERT_new_init(ctx->signer_cert, certs)) == NULL)
goto err; goto err;
if (!ESS_add_signing_cert(si, sc)) {
if (!ess_add_signing_cert(si, sc)) {
TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR); TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
goto err; 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)) if (!ts_TST_INFO_content_new(p7))
goto err; goto err;
@ -703,6 +726,7 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx)
"Error during signature " "Error during signature "
"generation."); "generation.");
BIO_free_all(p7bio); BIO_free_all(p7bio);
ESS_SIGNING_CERT_V2_free(sc2);
ESS_SIGNING_CERT_free(sc); ESS_SIGNING_CERT_free(sc);
PKCS7_free(p7); PKCS7_free(p7);
return ret; return ret;
@ -806,7 +830,7 @@ static int ts_TST_INFO_content_new(PKCS7 *p7)
return 0; 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; ASN1_STRING *seq = NULL;
unsigned char *p, *pp = 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; return 0;
} }
static ASN1_GENERALIZEDTIME static ESS_SIGNING_CERT_V2 *ess_signing_cert_v2_new_init(const EVP_MD *hash_alg,
*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, X509 *signcert,
long sec, long usec, unsigned precision) 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; time_t time_sec = (time_t)sec;
struct tm *tm = NULL; 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); TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
return NULL; 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_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names, static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names,
GENERAL_NAME *name); 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 * This must be large enough to hold all values in ts_status_text (with
@ -201,12 +203,13 @@ static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
{ {
ESS_SIGNING_CERT *ss = ess_get_signing_cert(si); ESS_SIGNING_CERT *ss = ess_get_signing_cert(si);
STACK_OF(ESS_CERT_ID) *cert_ids = NULL; 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; X509 *cert;
int i = 0; int i = 0;
int ret = 0; int ret = 0;
if (!ss) if (ss != NULL) {
goto err;
cert_ids = ss->cert_ids; cert_ids = ss->cert_ids;
cert = sk_X509_value(chain, 0); cert = sk_X509_value(chain, 0);
if (ts_find_cert(cert_ids, cert) != 0) if (ts_find_cert(cert_ids, cert) != 0)
@ -223,12 +226,34 @@ static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
goto err; 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; ret = 1;
err: err:
if (!ret) if (!ret)
TSerr(TS_F_TS_CHECK_SIGNING_CERTS, TSerr(TS_F_TS_CHECK_SIGNING_CERTS,
TS_R_ESS_SIGNING_CERTIFICATE_ERROR); TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
ESS_SIGNING_CERT_free(ss); ESS_SIGNING_CERT_free(ss);
ESS_SIGNING_CERT_V2_free(ssv2);
return ret; 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); 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. */ /* Returns < 0 if certificate is not found, certificate index otherwise. */
static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) 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; 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) static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert)
{ {
GENERAL_NAME *issuer; 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 variable is set to no, only the signing certificate identifier is
included. Default is no. (Optional) 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 =back
=head1 EXAMPLES =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) =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 =over 2
=item * =item *

View File

@ -932,6 +932,10 @@
#define NID_id_smime_aa_dvcs_dvc 240 #define NID_id_smime_aa_dvcs_dvc 240
#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L #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 SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES"
#define NID_id_smime_alg_ESDHwith3DES 241 #define NID_id_smime_alg_ESDHwith3DES 241
#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L #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) 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; typedef struct TS_resp_st TS_RESP;
TS_REQ *TS_REQ_new(void); 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); const unsigned char **pp, long length);
ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); 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); int TS_REQ_set_version(TS_REQ *a, long version);
long TS_REQ_get_version(const TS_REQ *a); 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, int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx,
const EVP_MD *signer_digest); 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. */ /* This parameter must be set. */
int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy); 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_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
TS_RESP_CTX *ctx); TS_RESP_CTX *ctx);
int TS_CONF_set_ess_cert_id_digest(CONF *conf, const char *section,
TS_RESP_CTX *ctx);
/* -------------------------------------------------- */ /* -------------------------------------------------- */
/* BEGIN ERROR CODES */ /* BEGIN ERROR CODES */
@ -544,8 +567,11 @@ int ERR_load_TS_strings(void);
# define TS_F_DEF_SERIAL_CB 110 # define TS_F_DEF_SERIAL_CB 110
# define TS_F_DEF_TIME_CB 111 # define TS_F_DEF_TIME_CB 111
# define TS_F_ESS_ADD_SIGNING_CERT 112 # 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_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_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_INT_TS_RESP_VERIFY_TOKEN 149
# define TS_F_PKCS7_TO_TS_TST_INFO 148 # define TS_F_PKCS7_TO_TS_TST_INFO 148
# define TS_F_TS_ACCURACY_SET_MICROS 115 # 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_COULD_NOT_SET_TIME 115
# define TS_R_DETACHED_CONTENT 134 # define TS_R_DETACHED_CONTENT 134
# define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 # 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_ESS_SIGNING_CERTIFICATE_ERROR 101
# define TS_R_INVALID_NULL_POINTER 102 # define TS_R_INVALID_NULL_POINTER 102
# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 # 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) # (optional, default: no)
ess_cert_id_chain = yes # Must the ESS cert id chain be included? ess_cert_id_chain = yes # Must the ESS cert id chain be included?
# (optional, default: no) # (optional, default: no)
ess_cert_id_alg = sha256 # algorithm to compute certificate
# identifier (optional, default: sha1)
[ tsa_config2 ] [ tsa_config2 ]

View File

@ -223,8 +223,10 @@
-T ERR_STATE -T ERR_STATE
-T ERR_STRING_DATA -T ERR_STRING_DATA
-T ESS_CERT_ID -T ESS_CERT_ID
-T ESS_CERT_ID_V2
-T ESS_ISSUER_SERIAL -T ESS_ISSUER_SERIAL
-T ESS_SIGNING_CERT -T ESS_SIGNING_CERT
-T ESS_SIGNING_CERT_V2
-T EVP_AES_HMAC_SHA1 -T EVP_AES_HMAC_SHA1
-T EVP_AES_HMAC_SHA256 -T EVP_AES_HMAC_SHA256
-T EVP_CIPHER -T EVP_CIPHER
@ -525,6 +527,7 @@
-T STACK_OF_ENGINE_ -T STACK_OF_ENGINE_
-T STACK_OF_ENGINE_CLEANUP_ITEM_ -T STACK_OF_ENGINE_CLEANUP_ITEM_
-T STACK_OF_ESS_CERT_ID_ -T STACK_OF_ESS_CERT_ID_
-T STACK_OF_ESS_CERT_ID_V2_
-T STACK_OF_EVP_PBE_CTL_ -T STACK_OF_EVP_PBE_CTL_
-T STACK_OF_EVP_PKEY_ASN1_METHOD_ -T STACK_OF_EVP_PKEY_ASN1_METHOD_
-T STACK_OF_EVP_PKEY_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_SIG_INFO_get 4219 1_1_1 EXIST::FUNCTION:
X509_get_signature_info 4220 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: 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