/* crypto/cms/cms_sd.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project.
 */
/* ====================================================================
 * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */

#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include "cms_lcl.h"

/* CMS SignedData Utilities */

DECLARE_ASN1_ITEM(CMS_SignedData)

static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
	{
	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed)
		{
		CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
		return NULL;
		}
	return cms->d.signedData;
	}

static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
	{
	if (cms->d.other == NULL)
		{
		cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
		if (!cms->d.signedData)
			{
			CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
			return NULL;
			}
		cms->d.signedData->version = 1;
		cms->d.signedData->encapContentInfo->eContentType =
						OBJ_nid2obj(NID_pkcs7_data);
		cms->d.signedData->encapContentInfo->partial = 1;
		ASN1_OBJECT_free(cms->contentType);
		cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
		return cms->d.signedData;
		}
	return cms_get0_signed(cms);
	}

/* Just initialize SignedData e.g. for certs only structure */

int CMS_SignedData_init(CMS_ContentInfo *cms)
	{
	if (cms_signed_data_init(cms))
		return 1;
	else
		return 0;
	}

/* Check structures and fixup version numbers (if necessary) */

static void cms_sd_set_version(CMS_SignedData *sd)
	{
	int i;
	CMS_CertificateChoices *cch;
	CMS_RevocationInfoChoice *rch;
	CMS_SignerInfo *si;

	for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++)
		{
		cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
		if (cch->type == CMS_CERTCHOICE_OTHER)
			{
			if (sd->version < 5)
				sd->version = 5;
			}
		else if (cch->type == CMS_CERTCHOICE_V2ACERT)
			{
			if (sd->version < 4)
				sd->version = 4;
			}
		else if (cch->type == CMS_CERTCHOICE_V1ACERT)
			{
			if (sd->version < 3)
				sd->version = 3;
			}
		}

	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++)
		{
		rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
		if (rch->type == CMS_REVCHOICE_OTHER)
			{
			if (sd->version < 5)
				sd->version = 5;
			}
		}

	if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
			&& (sd->version < 3))
		sd->version = 3;

	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
		{
		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
		if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
			{
			if (si->version < 3)
				si->version = 3;
			if (sd->version < 3)
				sd->version = 3;
			}
		else
			sd->version = 1;
		}

	if (sd->version < 1)
		sd->version = 1;

	}
	
/* Copy an existing messageDigest value */

static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
	{
	STACK_OF(CMS_SignerInfo) *sinfos;
	CMS_SignerInfo *sitmp;
	int i;
	sinfos = CMS_get0_SignerInfos(cms);
	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
		{
		ASN1_OCTET_STRING *messageDigest;
		sitmp = sk_CMS_SignerInfo_value(sinfos, i);
		if (sitmp == si)
			continue;
		if (CMS_signed_get_attr_count(sitmp) < 0)
			continue;
		if (OBJ_cmp(si->digestAlgorithm->algorithm,
				sitmp->digestAlgorithm->algorithm))
			continue;
		messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
					OBJ_nid2obj(NID_pkcs9_messageDigest),
					-3, V_ASN1_OCTET_STRING);
		if (!messageDigest)
			{
			CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
			return 0;
			}

		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
						V_ASN1_OCTET_STRING,
						messageDigest, -1))
			return 1;
		else
			return 0;
		}
		CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
		return 0;
	}

int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
	{
	switch(type)
		{
		case CMS_SIGNERINFO_ISSUER_SERIAL:
		sid->d.issuerAndSerialNumber =
			M_ASN1_new_of(CMS_IssuerAndSerialNumber);
		if (!sid->d.issuerAndSerialNumber)
			goto merr;
		if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,
					X509_get_issuer_name(cert)))
			goto merr;
		ASN1_STRING_free(sid->d.issuerAndSerialNumber->serialNumber);
		sid->d.issuerAndSerialNumber->serialNumber =
				ASN1_STRING_dup(X509_get_serialNumber(cert));
		if(!sid->d.issuerAndSerialNumber->serialNumber)
			goto merr;
		break;

		case CMS_SIGNERINFO_KEYIDENTIFIER:
		if (!cert->skid)
			{
			CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER,
					CMS_R_CERTIFICATE_HAS_NO_KEYID);
			return 0;
			}
		sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid);
		if (!sid->d.subjectKeyIdentifier)
			goto merr;
		break;

		default:
		CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
		return 0;
		}

	sid->type = type;

	return 1;

	merr:
	CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE);
	return 0;

	}

int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
					ASN1_OCTET_STRING **keyid,
					X509_NAME **issuer, ASN1_INTEGER **sno)
	{
	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
		{
		if (issuer)
			*issuer = sid->d.issuerAndSerialNumber->issuer;
		if (sno)
			*sno = sid->d.issuerAndSerialNumber->serialNumber;
		}
	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
		{
		if (keyid)
			*keyid = sid->d.subjectKeyIdentifier;
		}
	else
		return 0;
	return 1;
	}

int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
	{
	int ret;
	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
		{
		ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer,
					X509_get_issuer_name(cert));
		if (ret)
			return ret;
		return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber,
					X509_get_serialNumber(cert));
		}
	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
		{
		X509_check_purpose(cert, -1, -1);
		if (!cert->skid)
			return -1;
		return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier,
							cert->skid);
		}
	else
		return -1;
	}

CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
			unsigned int flags)
	{
	CMS_SignedData *sd;
	CMS_SignerInfo *si = NULL;
	X509_ALGOR *alg;
	int i, type;
	if(!X509_check_private_key(signer, pk))
		{
		CMSerr(CMS_F_CMS_ADD1_SIGNER,
			CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
                return NULL;
		}
	sd = cms_signed_data_init(cms);
	if (!sd)
		goto err;
	si = M_ASN1_new_of(CMS_SignerInfo);
	if (!si)
		goto merr;
	X509_check_purpose(signer, -1, -1);

	CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
	CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);

	si->pkey = pk;
	si->signer = signer;

	if (flags & CMS_USE_KEYID)
		{
		si->version = 3;
		if (sd->version < 3)
			sd->version = 3;
		type = CMS_SIGNERINFO_KEYIDENTIFIER;
		}
	else
		{
		type = CMS_SIGNERINFO_ISSUER_SERIAL;
		si->version = 1;
		}

	if (!cms_set1_SignerIdentifier(si->sid, signer, type))
		goto err;

	/* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */
	if (md == NULL)
		md = EVP_sha1();

	/* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */

	if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1))
		{
		CMSerr(CMS_F_CMS_ADD1_SIGNER,
				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
		goto err;
		}

	cms_DigestAlgorithm_set(si->digestAlgorithm, md);

	/* See if digest is present in digestAlgorithms */
	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
		{
		ASN1_OBJECT *aoid;
		alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
		X509_ALGOR_get0(&aoid, NULL, NULL, alg);
		if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
			break;
		}

	if (i == sk_X509_ALGOR_num(sd->digestAlgorithms))
		{
		alg = X509_ALGOR_new();
		if (!alg)
			goto merr;
		cms_DigestAlgorithm_set(alg, md);
		if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg))
			{
			X509_ALGOR_free(alg);
			goto merr;
			}
		}

	/* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8,
	 * hard code algorithm parameters.
	 */

	switch (pk->type)
		{

		case EVP_PKEY_RSA:
		X509_ALGOR_set0(si->signatureAlgorithm,
					OBJ_nid2obj(NID_rsaEncryption),
					V_ASN1_NULL, 0);
		break;

		case EVP_PKEY_DSA:
		X509_ALGOR_set0(si->signatureAlgorithm,
					OBJ_nid2obj(NID_dsaWithSHA1),
					V_ASN1_UNDEF, 0);
		break;


		case EVP_PKEY_EC:
		X509_ALGOR_set0(si->signatureAlgorithm,
					OBJ_nid2obj(NID_ecdsa_with_SHA1),
					V_ASN1_UNDEF, 0);
		break;

		default:
		CMSerr(CMS_F_CMS_ADD1_SIGNER,
				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
		goto err;

		}

	if (!(flags & CMS_NOATTR))
		{
		/* Initialialize signed attributes strutucture so other
		 * attributes such as signing time etc are added later
		 * even if we add none here.
		 */
		if (!si->signedAttrs)
			{
			si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
			if (!si->signedAttrs)
				goto merr;
			}

		if (!(flags & CMS_NOSMIMECAP))
			{
			STACK_OF(X509_ALGOR) *smcap = NULL;
			i = CMS_add_standard_smimecap(&smcap);
			if (i)
				i = CMS_add_smimecap(si, smcap);
			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
			if (!i)
				goto merr;
			}
		if (flags & CMS_REUSE_DIGEST)
			{
			if (!cms_copy_messageDigest(cms, si))
				goto err;
			if (!(flags & CMS_PARTIAL) &&
					!CMS_SignerInfo_sign(si))
				goto err;
			}
		}

	if (!(flags & CMS_NOCERTS))
		{
		/* NB ignore -1 return for duplicate cert */
		if (!CMS_add1_cert(cms, signer))
			goto merr;
		}

	if (!sd->signerInfos)
		sd->signerInfos = sk_CMS_SignerInfo_new_null();
	if (!sd->signerInfos ||
		!sk_CMS_SignerInfo_push(sd->signerInfos, si))
		goto merr;

	return si;

	merr:
	CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
	err:
	if (si)
		M_ASN1_free_of(si, CMS_SignerInfo);
	return NULL;

	}

static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
	{
	ASN1_TIME *tt;
	int r = 0;
	if (t)
		tt = t;
	else
		tt = X509_gmtime_adj(NULL, 0);

	if (!tt)
		goto merr;

	if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
						tt->type, tt, -1) <= 0)
		goto merr;

	r = 1;

	merr:

	if (!t)
		ASN1_TIME_free(tt);

	if (!r)
		CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);

	return r;

	}

STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
	{
	CMS_SignedData *sd;
	sd = cms_get0_signed(cms);
	if (!sd)
		return NULL;
	return sd->signerInfos;
	}

STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
	{
	STACK_OF(X509) *signers = NULL;
	STACK_OF(CMS_SignerInfo) *sinfos;
	CMS_SignerInfo *si;
	int i;
	sinfos = CMS_get0_SignerInfos(cms);
	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
		{
		si = sk_CMS_SignerInfo_value(sinfos, i);
		if (si->signer)
			{
			if (!signers)
				{
				signers = sk_X509_new_null();
				if (!signers)
					return NULL;
				}
			if (!sk_X509_push(signers, si->signer))
				{
				sk_X509_free(signers);
				return NULL;
				}
			}
		}
	return signers;
	}

void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
	{
	if (signer)
		{
		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
		if (si->pkey)
			EVP_PKEY_free(si->pkey);
		si->pkey = X509_get_pubkey(signer);
		}
	if (si->signer)
		X509_free(si->signer);
	si->signer = signer;
	}

int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
					ASN1_OCTET_STRING **keyid,
					X509_NAME **issuer, ASN1_INTEGER **sno)
	{
	return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
	}

int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
	{
	return cms_SignerIdentifier_cert_cmp(si->sid, cert);
	}

int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
				unsigned int flags)
	{
	CMS_SignedData *sd;
	CMS_SignerInfo *si;
	CMS_CertificateChoices *cch;
	STACK_OF(CMS_CertificateChoices) *certs;
	X509 *x;
	int i, j;
	int ret = 0;
	sd = cms_get0_signed(cms);
	if (!sd)
		return -1;
	certs = sd->certificates;
	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
		{
		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
		if (si->signer)
			continue;

		for (j = 0; j < sk_X509_num(scerts); j++)
			{
			x = sk_X509_value(scerts, j);
			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
				{
				CMS_SignerInfo_set1_signer_cert(si, x);
				ret++;
				break;
				}
			}

		if (si->signer || (flags & CMS_NOINTERN))
			continue;

		for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++)
			{
			cch = sk_CMS_CertificateChoices_value(certs, j);
			if (cch->type != 0)
				continue;
			x = cch->d.certificate;
			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
				{
				CMS_SignerInfo_set1_signer_cert(si, x);
				ret++;
				break;
				}
			}
		}
	return ret;
	}

void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
					X509_ALGOR **pdig, X509_ALGOR **psig)
	{
	if (pk)
		*pk = si->pkey;
	if (signer)
		*signer = si->signer;
	if (pdig)
		*pdig = si->digestAlgorithm;
	if (psig)
		*psig = si->signatureAlgorithm;
	}

/* In OpenSSL 0.9.8 we have the link between digest types and public
 * key types so we need to fixup the digest type if the public key
 * type is not appropriate.
 */

static void cms_fixup_mctx(EVP_MD_CTX *mctx, EVP_PKEY *pkey)
	{
	if (EVP_MD_CTX_type(mctx) != NID_sha1)
		return;
#ifndef OPENSSL_NO_DSA
	if (pkey->type == EVP_PKEY_DSA)
		mctx->digest = EVP_dss1();	
#endif
#ifndef OPENSSL_NO_ECDSA
	if (pkey->type == EVP_PKEY_EC)
		mctx->digest = EVP_ecdsa();	
#endif
	}

static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
					CMS_SignerInfo *si, BIO *chain)
	{
	EVP_MD_CTX mctx;
	int r = 0;
	EVP_MD_CTX_init(&mctx);


	if (!si->pkey)
		{
		CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
		return 0;
		}

	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
		goto err;

	/* If any signed attributes calculate and add messageDigest attribute */

	if (CMS_signed_get_attr_count(si) >= 0)
		{
		ASN1_OBJECT *ctype =
			cms->d.signedData->encapContentInfo->eContentType; 
		unsigned char md[EVP_MAX_MD_SIZE];
		unsigned int mdlen;
		EVP_DigestFinal_ex(&mctx, md, &mdlen);
		if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
						V_ASN1_OCTET_STRING,
						md, mdlen))
			goto err;
		/* Copy content type across */
		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
					V_ASN1_OBJECT, ctype, -1) <= 0)
			goto err;
		if (!CMS_SignerInfo_sign(si))
			goto err;
		}
	else
		{
		unsigned char *sig;
		unsigned int siglen;
		sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
		if (!sig)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
					ERR_R_MALLOC_FAILURE);
			goto err;
			}
		cms_fixup_mctx(&mctx, si->pkey);
		if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey))
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
					CMS_R_SIGNFINAL_ERROR);
			OPENSSL_free(sig);
			goto err;
			}
		ASN1_STRING_set0(si->signature, sig, siglen);
		}

	r = 1;

	err:
	EVP_MD_CTX_cleanup(&mctx);
	return r;

	}

int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
	{
	STACK_OF(CMS_SignerInfo) *sinfos;
	CMS_SignerInfo *si;
	int i;
	sinfos = CMS_get0_SignerInfos(cms);
	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
		{
		si = sk_CMS_SignerInfo_value(sinfos, i);
		if (!cms_SignerInfo_content_sign(cms, si, chain))
			return 0;
		}
	cms->d.signedData->encapContentInfo->partial = 0;
	return 1;
	}

int CMS_SignerInfo_sign(CMS_SignerInfo *si)
	{
	EVP_MD_CTX mctx;
	unsigned char *abuf = NULL;
	int alen;
	unsigned int siglen;
	const EVP_MD *md = NULL;

	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
	if (md == NULL)
		return 0;

	EVP_MD_CTX_init(&mctx);

	if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0)
		{
		if (!cms_add1_signingTime(si, NULL))
			goto err;
		}

	if (EVP_SignInit_ex(&mctx, md, NULL) <= 0)
		goto err;

#if 0
	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
				EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0)
		{
		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
		goto err;
		}
#endif

	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
				ASN1_ITEM_rptr(CMS_Attributes_Sign));
	if(!abuf)
		goto err;
	if (EVP_SignUpdate(&mctx, abuf, alen) <= 0)
		goto err;
	siglen = EVP_PKEY_size(si->pkey);
	OPENSSL_free(abuf);
	abuf = OPENSSL_malloc(siglen);
	if(!abuf)
		goto err;
	cms_fixup_mctx(&mctx, si->pkey);
	if (EVP_SignFinal(&mctx, abuf, &siglen, si->pkey) <= 0)
		goto err;
#if 0
	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
				EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0)
		{
		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
		goto err;
		}
#endif
	EVP_MD_CTX_cleanup(&mctx);

	ASN1_STRING_set0(si->signature, abuf, siglen);

	return 1;

	err:
	if (abuf)
		OPENSSL_free(abuf);
	EVP_MD_CTX_cleanup(&mctx);
	return 0;

	}

int CMS_SignerInfo_verify(CMS_SignerInfo *si)
	{
	EVP_MD_CTX mctx;
	unsigned char *abuf = NULL;
	int alen, r = -1;
	const EVP_MD *md = NULL;

	if (!si->pkey)
		{
		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
		return -1;
		}

	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
	if (md == NULL)
		return -1;
	EVP_MD_CTX_init(&mctx);
	if (EVP_VerifyInit_ex(&mctx, md, NULL) <= 0)
		goto err;

	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
				ASN1_ITEM_rptr(CMS_Attributes_Verify));
	if(!abuf)
		goto err;
	r = EVP_VerifyUpdate(&mctx, abuf, alen);
	OPENSSL_free(abuf);
	if (r <= 0)
		{
		r = -1;
		goto err;
		}
	cms_fixup_mctx(&mctx, si->pkey);
	r = EVP_VerifyFinal(&mctx,
			si->signature->data, si->signature->length, si->pkey);
	if (r <= 0)
		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
	err:
	EVP_MD_CTX_cleanup(&mctx);
	return r;
	}

/* Create a chain of digest BIOs from a CMS ContentInfo */

BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
	{
	int i;
	CMS_SignedData *sd;
	BIO *chain = NULL;
	sd = cms_get0_signed(cms);
	if (!sd)
		return NULL;
	if (cms->d.signedData->encapContentInfo->partial)
		cms_sd_set_version(sd);
	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
		{
		X509_ALGOR *digestAlgorithm;
		BIO *mdbio;
		digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
		mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
		if (!mdbio)
			goto err;	
		if (chain)
			 BIO_push(chain, mdbio);
		else
			chain = mdbio;
		}
	return chain;
	err:
	if (chain)
		BIO_free_all(chain);
	return NULL;
	}

int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
	{
	ASN1_OCTET_STRING *os = NULL;
	EVP_MD_CTX mctx;
	int r = -1;
	EVP_MD_CTX_init(&mctx);
	/* If we have any signed attributes look for messageDigest value */
	if (CMS_signed_get_attr_count(si) >= 0)
		{
		os = CMS_signed_get0_data_by_OBJ(si,
					OBJ_nid2obj(NID_pkcs9_messageDigest),
					-3, V_ASN1_OCTET_STRING);
		if (!os)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
			goto err;
			}
		}

	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
		goto err;

	/* If messageDigest found compare it */

	if (os)
		{
		unsigned char mval[EVP_MAX_MD_SIZE];
		unsigned int mlen;
		if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
			goto err;
			}
		if (mlen != (unsigned int)os->length)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
			goto err;
			}

		if (memcmp(mval, os->data, mlen))
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_VERIFICATION_FAILURE);
			r = 0;
			}
		else
			r = 1;
		}
	else
		{
		cms_fixup_mctx(&mctx, si->pkey);
		r = EVP_VerifyFinal(&mctx, si->signature->data,
					si->signature->length, si->pkey);
		if (r <= 0)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_VERIFICATION_FAILURE);
			r = 0;
			}
		}

	err:
	EVP_MD_CTX_cleanup(&mctx);
	return r;

	}

int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
	{
	unsigned char *smder = NULL;
	int smderlen, r;
	smderlen = i2d_X509_ALGORS(algs, &smder);
	if (smderlen <= 0)
		return 0;
	r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
					V_ASN1_SEQUENCE, smder, smderlen);
	OPENSSL_free(smder);
	return r;
	}

int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
				int algnid, int keysize)
	{
	X509_ALGOR *alg;
	ASN1_INTEGER *key = NULL;
	if (keysize > 0)
		{
		key = ASN1_INTEGER_new();
		if (!key || !ASN1_INTEGER_set(key, keysize))
			return 0;
		}
	alg = X509_ALGOR_new();
	if (!alg)
		{
		if (key)
			ASN1_INTEGER_free(key);
		return 0;
		}
		
	X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
				key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
	if (!*algs)
		*algs = sk_X509_ALGOR_new_null();
	if (!*algs || !sk_X509_ALGOR_push(*algs, alg))
		{
		X509_ALGOR_free(alg);
		return 0;
		}
	return 1;
	}

/* Check to see if a cipher exists and if so add S/MIME capabilities */

static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
	{
	if (EVP_get_cipherbynid(nid))
		return CMS_add_simple_smimecap(sk, nid, arg);
	return 1;
	}
#if 0
static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
	{
	if (EVP_get_digestbynid(nid))
		return CMS_add_simple_smimecap(sk, nid, arg);
	return 1;
	}
#endif
int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
	{
	if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
		|| !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
		|| !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
		|| !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
		|| !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
		return 0;
	return 1;
	}
