summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2011-09-19 00:34:36 +0000
committerSam Hartman <hartmans@mit.edu>2011-09-19 00:34:36 +0000
commitf79ba7eca6846552fcd00d42f4b8f67e05af2e40 (patch)
treed13eb32d6a4c69c265e76c7cb31fb8232507b24a /src
parenta650a4adf5b4c16b1ecc6d90ab18d9d6ea960c1c (diff)
downloadkrb5-f79ba7eca6846552fcd00d42f4b8f67e05af2e40.tar.gz
krb5-f79ba7eca6846552fcd00d42f4b8f67e05af2e40.tar.xz
krb5-f79ba7eca6846552fcd00d42f4b8f67e05af2e40.zip
pkinit: client: Use SignedData for anonymous
Per RFc 6112 use SignedData not ContentInfo for anonymous when the KDC offers support for PKINIT_KX padata. ticket: 6962 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25186 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/plugins/preauth/pkinit/pkinit.h3
-rw-r--r--src/plugins/preauth/pkinit/pkinit_clnt.c37
-rw-r--r--src/plugins/preauth/pkinit/pkinit_crypto_openssl.c401
3 files changed, 234 insertions, 207 deletions
diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h
index 6ba399de18..8928e9d80c 100644
--- a/src/plugins/preauth/pkinit/pkinit.h
+++ b/src/plugins/preauth/pkinit/pkinit.h
@@ -219,12 +219,13 @@ typedef struct _pkinit_context *pkinit_context;
* Client's per-request context
*/
struct _pkinit_req_context {
- int magic;
+ unsigned int magic;
pkinit_req_crypto_context cryptoctx;
pkinit_req_opts *opts;
pkinit_identity_crypto_context idctx;
pkinit_identity_opts *idopts;
krb5_preauthtype pa_type;
+ int rfc6112_kdc;
};
typedef struct _pkinit_req_context *pkinit_req_context;
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index cf95bd57b2..85b0167378 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -57,6 +57,23 @@
*/
int longhorn = 0; /* Talking to a Longhorn server? */
+/**
+ * Return true if we should use ContentInfo rather than SignedData. This
+ * happens if we are talking to what might be an old (pre-6112) MIT KDC and
+ * we're using anonymous.
+ */
+static int
+use_content_info(krb5_context context, pkinit_req_context req,
+ krb5_principal client)
+{
+ if (req->rfc6112_kdc)
+ return 0;
+ if (krb5_principal_compare_any_realm(context, client,
+ krb5_anonymous_principal()))
+ return 1;
+ return 0;
+ }
+
static krb5_error_code
pkinit_as_req_create(krb5_context context, pkinit_context plgctx,
pkinit_req_context reqctx, krb5_timestamp ctsec,
@@ -347,9 +364,7 @@ pkinit_as_req_create(krb5_context context,
retval = ENOMEM;
goto cleanup;
}
- /* For the new protocol, we support anonymous. */
- if (krb5_principal_compare_any_realm(context, client,
- krb5_anonymous_principal())) {
+ if (use_content_info(context, reqctx, client))
retval = cms_contentinfo_create(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx,
CMS_SIGN_CLIENT, (unsigned char *)
@@ -357,7 +372,7 @@ pkinit_as_req_create(krb5_context context,
coded_auth_pack->length,
&req->signedAuthPack.data,
&req->signedAuthPack.length);
- } else {
+ else {
retval = cms_signeddata_create(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx,
CMS_SIGN_CLIENT, 1,
@@ -1012,7 +1027,10 @@ pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata,
return EINVAL;
switch ((int) in_padata->pa_type) {
- case KRB5_PADATA_PK_AS_REQ:
+ case KRB5_PADATA_PKINIT_KX:
+ reqctx->rfc6112_kdc = 1;
+ return 0;
+ case KRB5_PADATA_PK_AS_REQ:
pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n");
processing_request = 1;
break;
@@ -1176,14 +1194,23 @@ cleanup:
static int
pkinit_client_get_flags(krb5_context kcontext, krb5_preauthtype patype)
{
+ if (patype == KRB5_PADATA_PKINIT_KX)
+ return PA_INFO|PA_PSEUDO;
return PA_REAL;
}
+/*
+ * We want to be notified about KRB5_PADATA_PKINIT_KX in addition to the actual
+ * pkinit patypes because RFC 6112 requires anonymous KDCs to send it. We use
+ * that to determine whether to use the broken MIT 1.9 behavior of sending
+ * ContentInfo rather than SignedData or the RFC 6112 behavior
+ */
static krb5_preauthtype supported_client_pa_types[] = {
KRB5_PADATA_PK_AS_REP,
KRB5_PADATA_PK_AS_REQ,
KRB5_PADATA_PK_AS_REP_OLD,
KRB5_PADATA_PK_AS_REQ_OLD,
+ KRB5_PADATA_PKINIT_KX,
0
};
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 56fc3fe8f7..4247524ae5 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -858,11 +858,6 @@ cms_signeddata_create(krb5_context context,
X509 *cert = NULL;
ASN1_OBJECT *oid = NULL;
- if (id_cryptoctx->my_certs == NULL) {
- krb5_set_error_message(context, EINVAL, _("cms_signdata_create called "
- "with no certificates"));
- return EINVAL;
- }
/* Start creating PKCS7 data. */
if ((p7 = PKCS7_new()) == NULL)
goto cleanup;
@@ -874,206 +869,208 @@ cms_signeddata_create(krb5_context context,
if (!ASN1_INTEGER_set(p7s->version, 3))
goto cleanup;
- /* create a cert chain that has at least the signer's certificate */
- if ((cert_stack = sk_X509_new_null()) == NULL)
+ /* pick the correct oid for the eContentInfo */
+ oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
+ if (oid == NULL)
goto cleanup;
- cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
- if (!include_certchain) {
- pkiDebug("only including signer's certificate\n");
- sk_X509_push(cert_stack, X509_dup(cert));
- } else {
- /* create a cert chain */
- X509_STORE *certstore = NULL;
- X509_STORE_CTX certctx;
- STACK_OF(X509) *certstack = NULL;
- char buf[DN_BUF_LEN];
- unsigned int i = 0, size = 0;
-
- if ((certstore = X509_STORE_new()) == NULL)
- goto cleanup;
- pkiDebug("building certificate chain\n");
- X509_STORE_set_verify_cb_func(certstore, openssl_callback);
- X509_STORE_CTX_init(&certctx, certstore, cert,
- id_cryptoctx->intermediateCAs);
- X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs);
- if (!X509_verify_cert(&certctx)) {
- pkiDebug("failed to create a certificate chain: %s\n",
- X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx)));
- if (!sk_X509_num(id_cryptoctx->trustedCAs))
- pkiDebug("No trusted CAs found. Check your X509_anchors\n");
+ if (id_cryptoctx->my_certs != NULL) {
+ /* create a cert chain that has at least the signer's certificate */
+ if ((cert_stack = sk_X509_new_null()) == NULL)
goto cleanup;
- }
- certstack = X509_STORE_CTX_get1_chain(&certctx);
- size = sk_X509_num(certstack);
- pkiDebug("size of certificate chain = %d\n", size);
- for(i = 0; i < size - 1; i++) {
- X509 *x = sk_X509_value(certstack, i);
- X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
- pkiDebug("cert #%d: %s\n", i, buf);
- sk_X509_push(cert_stack, X509_dup(x));
- }
- X509_STORE_CTX_cleanup(&certctx);
- X509_STORE_free(certstore);
- sk_X509_pop_free(certstack, X509_free);
- }
- p7s->cert = cert_stack;
-
- /* fill-in PKCS7_SIGNER_INFO */
- if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL)
- goto cleanup;
- if (!ASN1_INTEGER_set(p7si->version, 1))
- goto cleanup;
- if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
- X509_get_issuer_name(cert)))
- goto cleanup;
- /* because ASN1_INTEGER_set is used to set a 'long' we will do
- * things the ugly way. */
- M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
- if (!(p7si->issuer_and_serial->serial =
- M_ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
- goto cleanup;
- /* will not fill-out EVP_PKEY because it's on the smartcard */
+ cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
+ if (!include_certchain) {
+ pkiDebug("only including signer's certificate\n");
+ sk_X509_push(cert_stack, X509_dup(cert));
+ } else {
+ /* create a cert chain */
+ X509_STORE *certstore = NULL;
+ X509_STORE_CTX certctx;
+ STACK_OF(X509) *certstack = NULL;
+ char buf[DN_BUF_LEN];
+ unsigned int i = 0, size = 0;
+
+ if ((certstore = X509_STORE_new()) == NULL)
+ goto cleanup;
+ pkiDebug("building certificate chain\n");
+ X509_STORE_set_verify_cb_func(certstore, openssl_callback);
+ X509_STORE_CTX_init(&certctx, certstore, cert,
+ id_cryptoctx->intermediateCAs);
+ X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs);
+ if (!X509_verify_cert(&certctx)) {
+ pkiDebug("failed to create a certificate chain: %s\n",
+ X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx)));
+ if (!sk_X509_num(id_cryptoctx->trustedCAs))
+ pkiDebug("No trusted CAs found. Check your X509_anchors\n");
+ goto cleanup;
+ }
+ certstack = X509_STORE_CTX_get1_chain(&certctx);
+ size = sk_X509_num(certstack);
+ pkiDebug("size of certificate chain = %d\n", size);
+ for(i = 0; i < size - 1; i++) {
+ X509 *x = sk_X509_value(certstack, i);
+ X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
+ pkiDebug("cert #%d: %s\n", i, buf);
+ sk_X509_push(cert_stack, X509_dup(x));
+ }
+ X509_STORE_CTX_cleanup(&certctx);
+ X509_STORE_free(certstore);
+ sk_X509_pop_free(certstack, X509_free);
+ }
+ p7s->cert = cert_stack;
- /* Set digest algs */
- p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
+ /* fill-in PKCS7_SIGNER_INFO */
+ if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL)
+ goto cleanup;
+ if (!ASN1_INTEGER_set(p7si->version, 1))
+ goto cleanup;
+ if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
+ X509_get_issuer_name(cert)))
+ goto cleanup;
+ /* because ASN1_INTEGER_set is used to set a 'long' we will do
+ * things the ugly way. */
+ M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
+ if (!(p7si->issuer_and_serial->serial =
+ M_ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
+ goto cleanup;
- if (p7si->digest_alg->parameter != NULL)
- ASN1_TYPE_free(p7si->digest_alg->parameter);
- if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
- goto cleanup;
- p7si->digest_alg->parameter->type = V_ASN1_NULL;
+ /* will not fill-out EVP_PKEY because it's on the smartcard */
- /* Set sig algs */
- if (p7si->digest_enc_alg->parameter != NULL)
- ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
- p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
- if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
- goto cleanup;
- p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
+ /* Set digest algs */
+ p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
- /* pick the correct oid for the eContentInfo */
- oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
- if (oid == NULL)
- goto cleanup;
+ if (p7si->digest_alg->parameter != NULL)
+ ASN1_TYPE_free(p7si->digest_alg->parameter);
+ if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
+ goto cleanup;
+ p7si->digest_alg->parameter->type = V_ASN1_NULL;
- if (cms_msg_type == CMS_SIGN_DRAFT9) {
- /* don't include signed attributes for pa-type 15 request */
- abuf = data;
- alen = data_len;
- } else {
- /* add signed attributes */
- /* compute sha1 digest over the EncapsulatedContentInfo */
- EVP_MD_CTX_init(&ctx);
- EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
- EVP_DigestUpdate(&ctx, data, data_len);
- md_tmp = EVP_MD_CTX_md(&ctx);
- EVP_DigestFinal_ex(&ctx, md_data, &md_len);
-
- /* create a message digest attr */
- digest_attr = ASN1_OCTET_STRING_new();
- ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
- PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
- V_ASN1_OCTET_STRING, (char *) digest_attr);
-
- /* create a content-type attr */
- PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
- V_ASN1_OBJECT, oid);
-
- /* create the signature over signed attributes. get DER encoded value */
- /* This is the place where smartcard signature needs to be calculated */
- sk = p7si->auth_attr;
- alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
- ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
- if (abuf == NULL)
- goto cleanup2;
- }
+ /* Set sig algs */
+ if (p7si->digest_enc_alg->parameter != NULL)
+ ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
+ p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
+ if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
+ goto cleanup;
+ p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
+
+ if (cms_msg_type == CMS_SIGN_DRAFT9){
+ /* don't include signed attributes for pa-type 15 request */
+ abuf = data;
+ alen = data_len;
+ } else {
+ /* add signed attributes */
+ /* compute sha1 digest over the EncapsulatedContentInfo */
+ EVP_MD_CTX_init(&ctx);
+ EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctx, data, data_len);
+ md_tmp = EVP_MD_CTX_md(&ctx);
+ EVP_DigestFinal_ex(&ctx, md_data, &md_len);
+
+ /* create a message digest attr */
+ digest_attr = ASN1_OCTET_STRING_new();
+ ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
+ PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
+ V_ASN1_OCTET_STRING, (char *) digest_attr);
+
+ /* create a content-type attr */
+ PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
+ V_ASN1_OBJECT, oid);
+
+ /* create the signature over signed attributes. get DER encoded value */
+ /* This is the place where smartcard signature needs to be calculated */
+ sk = p7si->auth_attr;
+ alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
+ ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
+ if (abuf == NULL)
+ goto cleanup2;
+ } /* signed attributes */
#ifndef WITHOUT_PKCS11
- /* Some tokens can only do RSAEncryption without sha1 hash */
- /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
- * function and the hash value into an ASN.1 value of type DigestInfo
- * DigestInfo::=SEQUENCE {
- * digestAlgorithm AlgorithmIdentifier,
- * digest OCTET STRING }
- */
- if (id_cryptoctx->pkcs11_method == 1 &&
- id_cryptoctx->mech == CKM_RSA_PKCS) {
- pkiDebug("mech = CKM_RSA_PKCS\n");
- EVP_MD_CTX_init(&ctx2);
- /* if this is not draft9 request, include digest signed attribute */
- if (cms_msg_type != CMS_SIGN_DRAFT9)
- EVP_DigestInit_ex(&ctx2, md_tmp, NULL);
- else
- EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL);
- EVP_DigestUpdate(&ctx2, abuf, alen);
- EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2);
-
- alg = X509_ALGOR_new();
- if (alg == NULL)
- goto cleanup2;
- alg->algorithm = OBJ_nid2obj(NID_sha1);
- alg->parameter = NULL;
- alg_len = i2d_X509_ALGOR(alg, NULL);
- alg_buf = malloc(alg_len);
- if (alg_buf == NULL)
- goto cleanup2;
-
- digest = ASN1_OCTET_STRING_new();
- if (digest == NULL)
- goto cleanup2;
- ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
- digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
- digest_buf = malloc(digest_len);
- if (digest_buf == NULL)
- goto cleanup2;
-
- digestInfo_len = ASN1_object_size(1, (int)(alg_len + digest_len),
- V_ASN1_SEQUENCE);
- y = digestInfo_buf = malloc(digestInfo_len);
- if (digestInfo_buf == NULL)
- goto cleanup2;
- ASN1_put_object(&y, 1, (int)(alg_len + digest_len), V_ASN1_SEQUENCE,
- V_ASN1_UNIVERSAL);
- i2d_X509_ALGOR(alg, &y);
- i2d_ASN1_OCTET_STRING(digest, &y);
+ /* Some tokens can only do RSAEncryption without sha1 hash */
+ /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
+ * function and the hash value into an ASN.1 value of type DigestInfo
+ * DigestInfo::=SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING }
+ */
+ if (id_cryptoctx->pkcs11_method == 1 &&
+ id_cryptoctx->mech == CKM_RSA_PKCS) {
+ pkiDebug("mech = CKM_RSA_PKCS\n");
+ EVP_MD_CTX_init(&ctx2);
+ /* if this is not draft9 request, include digest signed attribute */
+ if (cms_msg_type != CMS_SIGN_DRAFT9)
+ EVP_DigestInit_ex(&ctx2, md_tmp, NULL);
+ else
+ EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctx2, abuf, alen);
+ EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2);
+
+ alg = X509_ALGOR_new();
+ if (alg == NULL)
+ goto cleanup2;
+ alg->algorithm = OBJ_nid2obj(NID_sha1);
+ alg->parameter = NULL;
+ alg_len = i2d_X509_ALGOR(alg, NULL);
+ alg_buf = malloc(alg_len);
+ if (alg_buf == NULL)
+ goto cleanup2;
+
+ digest = ASN1_OCTET_STRING_new();
+ if (digest == NULL)
+ goto cleanup2;
+ ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
+ digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
+ digest_buf = malloc(digest_len);
+ if (digest_buf == NULL)
+ goto cleanup2;
+
+ digestInfo_len = ASN1_object_size(1, (int)(alg_len + digest_len),
+ V_ASN1_SEQUENCE);
+ y = digestInfo_buf = malloc(digestInfo_len);
+ if (digestInfo_buf == NULL)
+ goto cleanup2;
+ ASN1_put_object(&y, 1, (int)(alg_len + digest_len), V_ASN1_SEQUENCE,
+ V_ASN1_UNIVERSAL);
+ i2d_X509_ALGOR(alg, &y);
+ i2d_ASN1_OCTET_STRING(digest, &y);
#ifdef DEBUG_SIG
- pkiDebug("signing buffer\n");
- print_buffer(digestInfo_buf, digestInfo_len);
- print_buffer_bin(digestInfo_buf, digestInfo_len, "/tmp/pkcs7_tosign");
+ pkiDebug("signing buffer\n");
+ print_buffer(digestInfo_buf, digestInfo_len);
+ print_buffer_bin(digestInfo_buf, digestInfo_len, "/tmp/pkcs7_tosign");
#endif
- retval = pkinit_sign_data(context, id_cryptoctx, digestInfo_buf,
- digestInfo_len, &sig, &sig_len);
- } else
+ retval = pkinit_sign_data(context, id_cryptoctx, digestInfo_buf,
+ digestInfo_len, &sig, &sig_len);
+ } else
#endif
- {
- pkiDebug("mech = %s\n",
- id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS");
- retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen,
- &sig, &sig_len);
- }
+ {
+ pkiDebug("mech = %s\n",
+ id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS");
+ retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen,
+ &sig, &sig_len);
+ }
#ifdef DEBUG_SIG
- print_buffer(sig, sig_len);
+ print_buffer(sig, sig_len);
#endif
- if (cms_msg_type != CMS_SIGN_DRAFT9)
- free(abuf);
- if (retval)
- goto cleanup2;
+ if (cms_msg_type != CMS_SIGN_DRAFT9 )
+ free(abuf);
+ if (retval)
+ goto cleanup2;
- /* Add signature */
- if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig,
- (int)sig_len)) {
- unsigned long err = ERR_peek_error();
- retval = KRB5KDC_ERR_PREAUTH_FAILED;
- krb5_set_error_message(context, retval, "%s\n",
- ERR_error_string(err, NULL));
- pkiDebug("failed to add a signed digest attribute\n");
- goto cleanup2;
- }
- /* adder signer_info to pkcs7 signed */
- if (!PKCS7_add_signer(p7, p7si))
- goto cleanup2;
+ /* Add signature */
+ if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig,
+ (int)sig_len)) {
+ unsigned long err = ERR_peek_error();
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_set_error_message(context, retval, "%s\n",
+ ERR_error_string(err, NULL));
+ pkiDebug("failed to add a signed digest attribute\n");
+ goto cleanup2;
+ }
+ /* adder signer_info to pkcs7 signed */
+ if (!PKCS7_add_signer(p7, p7si))
+ goto cleanup2;
+ } /* we have a certificate */
/* start on adding data to the pkcs7 signed */
retval = create_contentinfo(context, plg_cryptoctx, oid,
@@ -1123,21 +1120,23 @@ cms_signeddata_create(krb5_context context,
#endif
cleanup2:
- if (cms_msg_type != CMS_SIGN_DRAFT9)
- EVP_MD_CTX_cleanup(&ctx);
+ if (p7si) {
+ if (cms_msg_type != CMS_SIGN_DRAFT9)
+ EVP_MD_CTX_cleanup(&ctx);
#ifndef WITHOUT_PKCS11
- if (id_cryptoctx->pkcs11_method == 1 &&
- id_cryptoctx->mech == CKM_RSA_PKCS) {
- EVP_MD_CTX_cleanup(&ctx2);
- free(digest_buf);
- free(digestInfo_buf);
- free(alg_buf);
- if (digest != NULL)
- ASN1_OCTET_STRING_free(digest);
- }
+ if (id_cryptoctx->pkcs11_method == 1 &&
+ id_cryptoctx->mech == CKM_RSA_PKCS) {
+ EVP_MD_CTX_cleanup(&ctx2);
+ free(digest_buf);
+ free(digestInfo_buf);
+ free(alg_buf);
+ if (digest != NULL)
+ ASN1_OCTET_STRING_free(digest);
+ }
#endif
- if (alg != NULL)
- X509_ALGOR_free(alg);
+ if (alg != NULL)
+ X509_ALGOR_free(alg);
+ }
cleanup:
if (p7 != NULL)
PKCS7_free(p7);