diff options
author | Marek Klein <kleinmrk@gmail.com> | 2016-03-01 16:32:10 +0000 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2017-05-03 09:04:23 +0200 |
commit | f0ef20bf386b5c37ba5a4ce5c1de9a819bbeffb2 (patch) | |
tree | 3fc8f414a3c10883a8a09fbe621a563d7c29f0a8 /crypto/ts/ts_rsp_sign.c | |
parent | 0e534337b24ee7b56480d85f01b9dda923fa42fc (diff) |
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)
Diffstat (limited to 'crypto/ts/ts_rsp_sign.c')
-rw-r--r-- | crypto/ts/ts_rsp_sign.c | 174 |
1 files changed, 164 insertions, 10 deletions
diff --git a/crypto/ts/ts_rsp_sign.c b/crypto/ts/ts_rsp_sign.c index aea7b922a3..76011ada59 100644 --- a/crypto/ts/ts_rsp_sign.c +++ b/crypto/ts/ts_rsp_sign.c @@ -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; +} |