/* crypto/cms/cms_ess.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/rand.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include "cms_lcl.h"

DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
DECLARE_ASN1_ITEM(CMS_Receipt)

IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ReceiptRequest)

/* ESS services: for now just Signed Receipt related */

int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
	{
	ASN1_STRING *str;
	CMS_ReceiptRequest *rr = NULL;
	if (prr)
		*prr = NULL;
	str = CMS_signed_get0_data_by_OBJ(si,
				OBJ_nid2obj(NID_id_smime_aa_receiptRequest),
					-3, V_ASN1_SEQUENCE);
	if (!str)
		return 0;

	rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
	if (!rr)
		return -1;
	if (prr)
		*prr = rr;
	else
		CMS_ReceiptRequest_free(rr);
	return 1;
	}

CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
				int allorfirst,
				STACK_OF(GENERAL_NAMES) *receiptList,
				STACK_OF(GENERAL_NAMES) *receiptsTo)
	{
	CMS_ReceiptRequest *rr = NULL;

	rr = CMS_ReceiptRequest_new();
	if (!rr)
		goto merr;
	if (id)
		ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
	else
		{
		if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
			goto merr;
		if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32) 
					<= 0)
			goto err;
		}

	sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
	rr->receiptsTo = receiptsTo;

	if (receiptList)
		{
		rr->receiptsFrom->type = 1;
		rr->receiptsFrom->d.receiptList = receiptList;
		}
	else
		{
		rr->receiptsFrom->type = 0;
		rr->receiptsFrom->d.allOrFirstTier = allorfirst;
		}

	return rr;

	merr:
	CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);

	err:
	if (rr)
		CMS_ReceiptRequest_free(rr);

	return NULL;
	
	}

int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
	{
	unsigned char *rrder = NULL;
	int rrderlen, r = 0;

	rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
	if (rrderlen < 0)
		goto merr;

	if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
					V_ASN1_SEQUENCE, rrder, rrderlen))
		goto merr;

	r = 1;

	merr:
	if (!r)
		CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);

	if (rrder)
		OPENSSL_free(rrder);

	return r;
	
	}

void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
					ASN1_STRING **pcid,
					int *pallorfirst,
					STACK_OF(GENERAL_NAMES) **plist,
					STACK_OF(GENERAL_NAMES) **prto)
	{
	if (pcid)
		*pcid = rr->signedContentIdentifier;
	if (rr->receiptsFrom->type == 0)
		{
		if (pallorfirst)
			*pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
		if (plist)
			*plist = NULL;
		}
	else
		{
		if (pallorfirst)
			*pallorfirst = -1;
		if (plist)
			*plist = rr->receiptsFrom->d.receiptList;
		}
	if (prto)
		*prto = rr->receiptsTo;
	}

/* Digest a SignerInfo structure for msgSigDigest attribute processing */

static int cms_msgSigDigest(CMS_SignerInfo *si,
				unsigned char *dig, unsigned int *diglen)
	{
	const EVP_MD *md;
	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
	if (md == NULL)
		return 0;
	if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
						si->signedAttrs, dig, diglen))
		return 0;
	return 1;
	}

/* Add a msgSigDigest attribute to a SignerInfo */

int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
	{
	unsigned char dig[EVP_MAX_MD_SIZE];
	unsigned int diglen;
	if (!cms_msgSigDigest(src, dig, &diglen))
		{
		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
		return 0;
		}
	if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
					V_ASN1_OCTET_STRING, dig, diglen))
		{
		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	return 1;
	}

/* Verify signed receipt after it has already passed normal CMS verify */

int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
	{
	int r = 0, i;
	CMS_ReceiptRequest *rr = NULL;
	CMS_Receipt *rct = NULL;
	STACK_OF(CMS_SignerInfo) *sis, *osis;
	CMS_SignerInfo *si, *osi = NULL;
	ASN1_OCTET_STRING *msig, **pcont;
	ASN1_OBJECT *octype;
	unsigned char dig[EVP_MAX_MD_SIZE];
	unsigned int diglen;

	/* Get SignerInfos, also checks SignedData content type */
	osis = CMS_get0_SignerInfos(req_cms);
	sis = CMS_get0_SignerInfos(cms);
	if (!osis || !sis)
		goto err;

	if (sk_CMS_SignerInfo_num(sis) != 1)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
		goto err;
		}

	/* Check receipt content type */
	if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
		goto err;
		}

	/* Extract and decode receipt content */
	pcont = CMS_get0_content(cms);
	if (!pcont || !*pcont)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
		goto err;
		}

	rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));

	if (!rct)	
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
		goto err;
		}

	/* Locate original request */

	for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++)
		{
		osi = sk_CMS_SignerInfo_value(osis, i);
		if (!ASN1_STRING_cmp(osi->signature,
					rct->originatorSignatureValue))
			break;
		}

	if (i == sk_CMS_SignerInfo_num(osis))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
		goto err;
		}

	si = sk_CMS_SignerInfo_value(sis, 0);

	/* Get msgSigDigest value and compare */

	msig = CMS_signed_get0_data_by_OBJ(si,
				OBJ_nid2obj(NID_id_smime_aa_msgSigDigest),
					-3, V_ASN1_OCTET_STRING);

	if (!msig)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
		goto err;
		}

	if (!cms_msgSigDigest(osi, dig, &diglen))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
		goto err;
		}

	if (diglen != (unsigned int)msig->length)
			{
			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
				CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
			goto err;
			}

	if (memcmp(dig, msig->data, diglen))
			{
			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
				CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
			goto err;
			}

	/* Compare content types */

	octype = CMS_signed_get0_data_by_OBJ(osi,
				OBJ_nid2obj(NID_pkcs9_contentType),
					-3, V_ASN1_OBJECT);
	if (!octype)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
		goto err;
		}

	/* Compare details in receipt request */

	if (OBJ_cmp(octype, rct->contentType))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
		goto err;
		}

	/* Get original receipt request details */

	if (!CMS_get1_ReceiptRequest(osi, &rr))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
		goto err;
		}

	if (ASN1_STRING_cmp(rr->signedContentIdentifier,
					rct->signedContentIdentifier))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
					CMS_R_CONTENTIDENTIFIER_MISMATCH);
		goto err;
		}

	r = 1;

	err:
	if (rr)
		CMS_ReceiptRequest_free(rr);
	if (rct)
		M_ASN1_free_of(rct, CMS_Receipt);

	return r;

	}

/* Encode a Receipt into an OCTET STRING read for including into content of
 * a SignedData ContentInfo.
 */

ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
	{
	CMS_Receipt rct;
	CMS_ReceiptRequest *rr = NULL;
	ASN1_OBJECT *ctype;
	ASN1_OCTET_STRING *os = NULL;

	/* Get original receipt request */

	/* Get original receipt request details */

	if (!CMS_get1_ReceiptRequest(si, &rr))
		{
		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
		goto err;
		}

	/* Get original content type */

	ctype = CMS_signed_get0_data_by_OBJ(si,
				OBJ_nid2obj(NID_pkcs9_contentType),
					-3, V_ASN1_OBJECT);
	if (!ctype)
		{
		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
		goto err;
		}

	rct.version = 1;
	rct.contentType = ctype;
	rct.signedContentIdentifier = rr->signedContentIdentifier;
	rct.originatorSignatureValue = si->signature;

	os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);

	err:
	if (rr)
		CMS_ReceiptRequest_free(rr);

	return os;

	}


