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;
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,
#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);