xref: /openbsd-src/lib/libcrypto/cms/cms_ess.c (revision 7a9020cd0142ffa8aefc1557149a140147228b71)
1*7a9020cdStb /* $OpenBSD: cms_ess.c,v 1.26 2024/11/01 18:53:35 tb Exp $ */
2b8b016bfSjsing /*
3f29d8588Sjsing  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4f29d8588Sjsing  * project.
5f29d8588Sjsing  */
6f29d8588Sjsing /* ====================================================================
7f29d8588Sjsing  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
8b8b016bfSjsing  *
9f29d8588Sjsing  * Redistribution and use in source and binary forms, with or without
10f29d8588Sjsing  * modification, are permitted provided that the following conditions
11f29d8588Sjsing  * are met:
12f29d8588Sjsing  *
13f29d8588Sjsing  * 1. Redistributions of source code must retain the above copyright
14f29d8588Sjsing  *    notice, this list of conditions and the following disclaimer.
15f29d8588Sjsing  *
16f29d8588Sjsing  * 2. Redistributions in binary form must reproduce the above copyright
17f29d8588Sjsing  *    notice, this list of conditions and the following disclaimer in
18f29d8588Sjsing  *    the documentation and/or other materials provided with the
19f29d8588Sjsing  *    distribution.
20f29d8588Sjsing  *
21f29d8588Sjsing  * 3. All advertising materials mentioning features or use of this
22f29d8588Sjsing  *    software must display the following acknowledgment:
23f29d8588Sjsing  *    "This product includes software developed by the OpenSSL Project
24f29d8588Sjsing  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25f29d8588Sjsing  *
26f29d8588Sjsing  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27f29d8588Sjsing  *    endorse or promote products derived from this software without
28f29d8588Sjsing  *    prior written permission. For written permission, please contact
29f29d8588Sjsing  *    licensing@OpenSSL.org.
30f29d8588Sjsing  *
31f29d8588Sjsing  * 5. Products derived from this software may not be called "OpenSSL"
32f29d8588Sjsing  *    nor may "OpenSSL" appear in their names without prior written
33f29d8588Sjsing  *    permission of the OpenSSL Project.
34f29d8588Sjsing  *
35f29d8588Sjsing  * 6. Redistributions of any form whatsoever must retain the following
36f29d8588Sjsing  *    acknowledgment:
37f29d8588Sjsing  *    "This product includes software developed by the OpenSSL Project
38f29d8588Sjsing  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39f29d8588Sjsing  *
40f29d8588Sjsing  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41f29d8588Sjsing  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42f29d8588Sjsing  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43f29d8588Sjsing  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44f29d8588Sjsing  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45f29d8588Sjsing  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46f29d8588Sjsing  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47f29d8588Sjsing  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f29d8588Sjsing  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49f29d8588Sjsing  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50f29d8588Sjsing  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51f29d8588Sjsing  * OF THE POSSIBILITY OF SUCH DAMAGE.
52f29d8588Sjsing  * ====================================================================
53b8b016bfSjsing  */
54b8b016bfSjsing 
55*7a9020cdStb #include <stdlib.h>
56bd31daa0Sjsing #include <string.h>
57bd31daa0Sjsing 
58*7a9020cdStb #include <openssl/asn1.h>
59b8b016bfSjsing #include <openssl/cms.h>
60*7a9020cdStb #include <openssl/err.h>
61*7a9020cdStb #include <openssl/evp.h>
62*7a9020cdStb #include <openssl/objects.h>
63*7a9020cdStb #include <openssl/x509.h>
64*7a9020cdStb #include <openssl/x509v3.h>
65b8b016bfSjsing 
66723bccacStb #include "cms_local.h"
670a940e1fSjsing 
680a940e1fSjsing CMS_ReceiptRequest *
690a940e1fSjsing d2i_CMS_ReceiptRequest(CMS_ReceiptRequest **a, const unsigned char **in, long len)
700a940e1fSjsing {
710a940e1fSjsing 	return (CMS_ReceiptRequest *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
720a940e1fSjsing 	    &CMS_ReceiptRequest_it);
730a940e1fSjsing }
74ead8f799Sbeck LCRYPTO_ALIAS(d2i_CMS_ReceiptRequest);
750a940e1fSjsing 
760a940e1fSjsing int
770a940e1fSjsing i2d_CMS_ReceiptRequest(CMS_ReceiptRequest *a, unsigned char **out)
780a940e1fSjsing {
790a940e1fSjsing 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &CMS_ReceiptRequest_it);
800a940e1fSjsing }
81ead8f799Sbeck LCRYPTO_ALIAS(i2d_CMS_ReceiptRequest);
820a940e1fSjsing 
830a940e1fSjsing CMS_ReceiptRequest *
840a940e1fSjsing CMS_ReceiptRequest_new(void)
850a940e1fSjsing {
860a940e1fSjsing 	return (CMS_ReceiptRequest *)ASN1_item_new(&CMS_ReceiptRequest_it);
870a940e1fSjsing }
88ead8f799Sbeck LCRYPTO_ALIAS(CMS_ReceiptRequest_new);
890a940e1fSjsing 
900a940e1fSjsing void
910a940e1fSjsing CMS_ReceiptRequest_free(CMS_ReceiptRequest *a)
920a940e1fSjsing {
930a940e1fSjsing 	ASN1_item_free((ASN1_VALUE *)a, &CMS_ReceiptRequest_it);
940a940e1fSjsing }
95ead8f799Sbeck LCRYPTO_ALIAS(CMS_ReceiptRequest_free);
96b8b016bfSjsing 
97b8b016bfSjsing /* ESS services: for now just Signed Receipt related */
98b8b016bfSjsing 
9972419cc7Sjsing int
10072419cc7Sjsing CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
101b8b016bfSjsing {
102b8b016bfSjsing 	ASN1_STRING *str;
103b8b016bfSjsing 	CMS_ReceiptRequest *rr = NULL;
10472419cc7Sjsing 
105b8b016bfSjsing 	if (prr)
106b8b016bfSjsing 		*prr = NULL;
107b8b016bfSjsing 	str = CMS_signed_get0_data_by_OBJ(si,
10872419cc7Sjsing 	    OBJ_nid2obj(NID_id_smime_aa_receiptRequest), -3, V_ASN1_SEQUENCE);
109b8b016bfSjsing 	if (!str)
110b8b016bfSjsing 		return 0;
111b8b016bfSjsing 
1120a940e1fSjsing 	rr = ASN1_item_unpack(str, &CMS_ReceiptRequest_it);
113b8b016bfSjsing 	if (!rr)
114b8b016bfSjsing 		return -1;
115b8b016bfSjsing 	if (prr)
116b8b016bfSjsing 		*prr = rr;
117b8b016bfSjsing 	else
118b8b016bfSjsing 		CMS_ReceiptRequest_free(rr);
11972419cc7Sjsing 
120b8b016bfSjsing 	return 1;
121b8b016bfSjsing }
1227bfedc82Sjoshua LCRYPTO_ALIAS(CMS_get1_ReceiptRequest);
123b8b016bfSjsing 
12472419cc7Sjsing CMS_ReceiptRequest *
12572419cc7Sjsing CMS_ReceiptRequest_create0(unsigned char *id, int idlen, int allorfirst,
12672419cc7Sjsing     STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo)
127b8b016bfSjsing {
128b8b016bfSjsing 	CMS_ReceiptRequest *rr = NULL;
129b8b016bfSjsing 
130b8b016bfSjsing 	rr = CMS_ReceiptRequest_new();
131b8b016bfSjsing 	if (rr == NULL)
132b8b016bfSjsing 		goto merr;
133b8b016bfSjsing 	if (id)
134b8b016bfSjsing 		ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
135b8b016bfSjsing 	else {
136b8b016bfSjsing 		if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
137b8b016bfSjsing 			goto merr;
1381d2f41d6Sjsing 		arc4random_buf(rr->signedContentIdentifier->data, 32);
139b8b016bfSjsing 	}
140b8b016bfSjsing 
141b8b016bfSjsing 	sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
142b8b016bfSjsing 	rr->receiptsTo = receiptsTo;
143b8b016bfSjsing 
144b8b016bfSjsing 	if (receiptList) {
145b8b016bfSjsing 		rr->receiptsFrom->type = 1;
146b8b016bfSjsing 		rr->receiptsFrom->d.receiptList = receiptList;
147b8b016bfSjsing 	} else {
148b8b016bfSjsing 		rr->receiptsFrom->type = 0;
149b8b016bfSjsing 		rr->receiptsFrom->d.allOrFirstTier = allorfirst;
150b8b016bfSjsing 	}
151b8b016bfSjsing 
152b8b016bfSjsing 	return rr;
153b8b016bfSjsing 
154b8b016bfSjsing  merr:
155be6ec861Sjsing 	CMSerror(ERR_R_MALLOC_FAILURE);
156b8b016bfSjsing 	CMS_ReceiptRequest_free(rr);
157fcde3053Sjsing 
158b8b016bfSjsing 	return NULL;
159b8b016bfSjsing }
1607bfedc82Sjoshua LCRYPTO_ALIAS(CMS_ReceiptRequest_create0);
161b8b016bfSjsing 
16272419cc7Sjsing int
16372419cc7Sjsing CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
164b8b016bfSjsing {
165b8b016bfSjsing 	unsigned char *rrder = NULL;
166b8b016bfSjsing 	int rrderlen, r = 0;
167b8b016bfSjsing 
168b8b016bfSjsing 	rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
169b8b016bfSjsing 	if (rrderlen < 0)
170b8b016bfSjsing 		goto merr;
171b8b016bfSjsing 
172b8b016bfSjsing 	if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
173b8b016bfSjsing 	    V_ASN1_SEQUENCE, rrder, rrderlen))
174b8b016bfSjsing 		goto merr;
175b8b016bfSjsing 
176b8b016bfSjsing 	r = 1;
177b8b016bfSjsing 
178b8b016bfSjsing  merr:
179b8b016bfSjsing 	if (!r)
180be6ec861Sjsing 		CMSerror(ERR_R_MALLOC_FAILURE);
181b8b016bfSjsing 
1824ff91afbSjsing 	free(rrder);
183b8b016bfSjsing 
184b8b016bfSjsing 	return r;
185b8b016bfSjsing }
1867bfedc82Sjoshua LCRYPTO_ALIAS(CMS_add1_ReceiptRequest);
187b8b016bfSjsing 
18872419cc7Sjsing void
18972419cc7Sjsing CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid,
19072419cc7Sjsing     int *pallorfirst, STACK_OF(GENERAL_NAMES) **plist,
191b8b016bfSjsing     STACK_OF(GENERAL_NAMES) **prto)
192b8b016bfSjsing {
193b8b016bfSjsing 	if (pcid)
194b8b016bfSjsing 		*pcid = rr->signedContentIdentifier;
195b8b016bfSjsing 	if (rr->receiptsFrom->type == 0) {
196b8b016bfSjsing 		if (pallorfirst)
197b8b016bfSjsing 			*pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
198b8b016bfSjsing 		if (plist)
199b8b016bfSjsing 			*plist = NULL;
200b8b016bfSjsing 	} else {
201b8b016bfSjsing 		if (pallorfirst)
202b8b016bfSjsing 			*pallorfirst = -1;
203b8b016bfSjsing 		if (plist)
204b8b016bfSjsing 			*plist = rr->receiptsFrom->d.receiptList;
205b8b016bfSjsing 	}
206b8b016bfSjsing 	if (prto)
207b8b016bfSjsing 		*prto = rr->receiptsTo;
208b8b016bfSjsing }
2097bfedc82Sjoshua LCRYPTO_ALIAS(CMS_ReceiptRequest_get0_values);
210b8b016bfSjsing 
211b8b016bfSjsing /* Digest a SignerInfo structure for msgSigDigest attribute processing */
212b8b016bfSjsing 
21372419cc7Sjsing static int
21472419cc7Sjsing cms_msgSigDigest(CMS_SignerInfo *si, unsigned char *dig, unsigned int *diglen)
215b8b016bfSjsing {
216b8b016bfSjsing 	const EVP_MD *md;
21772419cc7Sjsing 
218b8b016bfSjsing 	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
219b8b016bfSjsing 	if (md == NULL)
220b8b016bfSjsing 		return 0;
2210a940e1fSjsing 	if (!ASN1_item_digest(&CMS_Attributes_Verify_it, md,
222b8b016bfSjsing 	    si->signedAttrs, dig, diglen))
223b8b016bfSjsing 		return 0;
22472419cc7Sjsing 
225b8b016bfSjsing 	return 1;
226b8b016bfSjsing }
227b8b016bfSjsing 
228b8b016bfSjsing /* Add a msgSigDigest attribute to a SignerInfo */
229b8b016bfSjsing 
23072419cc7Sjsing int
23172419cc7Sjsing cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
232b8b016bfSjsing {
233b8b016bfSjsing 	unsigned char dig[EVP_MAX_MD_SIZE];
234b8b016bfSjsing 	unsigned int diglen;
23572419cc7Sjsing 
236b8b016bfSjsing 	if (!cms_msgSigDigest(src, dig, &diglen)) {
237be6ec861Sjsing 		CMSerror(CMS_R_MSGSIGDIGEST_ERROR);
238b8b016bfSjsing 		return 0;
239b8b016bfSjsing 	}
240b8b016bfSjsing 	if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
241b8b016bfSjsing 	    V_ASN1_OCTET_STRING, dig, diglen)) {
242be6ec861Sjsing 		CMSerror(ERR_R_MALLOC_FAILURE);
243b8b016bfSjsing 		return 0;
244b8b016bfSjsing 	}
24572419cc7Sjsing 
246b8b016bfSjsing 	return 1;
247b8b016bfSjsing }
248b8b016bfSjsing 
249b8b016bfSjsing /* Verify signed receipt after it has already passed normal CMS verify */
250b8b016bfSjsing 
25172419cc7Sjsing int
25272419cc7Sjsing cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
253b8b016bfSjsing {
254b8b016bfSjsing 	int r = 0, i;
255b8b016bfSjsing 	CMS_ReceiptRequest *rr = NULL;
256b8b016bfSjsing 	CMS_Receipt *rct = NULL;
257b8b016bfSjsing 	STACK_OF(CMS_SignerInfo) *sis, *osis;
258b8b016bfSjsing 	CMS_SignerInfo *si, *osi = NULL;
259b8b016bfSjsing 	ASN1_OCTET_STRING *msig, **pcont;
260b8b016bfSjsing 	ASN1_OBJECT *octype;
261b8b016bfSjsing 	unsigned char dig[EVP_MAX_MD_SIZE];
262b8b016bfSjsing 	unsigned int diglen;
263b8b016bfSjsing 
264b8b016bfSjsing 	/* Get SignerInfos, also checks SignedData content type */
265b8b016bfSjsing 	osis = CMS_get0_SignerInfos(req_cms);
266b8b016bfSjsing 	sis = CMS_get0_SignerInfos(cms);
267b8b016bfSjsing 	if (!osis || !sis)
268b8b016bfSjsing 		goto err;
269b8b016bfSjsing 
270b8b016bfSjsing 	if (sk_CMS_SignerInfo_num(sis) != 1) {
271be6ec861Sjsing 		CMSerror(CMS_R_NEED_ONE_SIGNER);
272b8b016bfSjsing 		goto err;
273b8b016bfSjsing 	}
274b8b016bfSjsing 
275b8b016bfSjsing 	/* Check receipt content type */
276b8b016bfSjsing 	if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) {
277be6ec861Sjsing 		CMSerror(CMS_R_NOT_A_SIGNED_RECEIPT);
278b8b016bfSjsing 		goto err;
279b8b016bfSjsing 	}
280b8b016bfSjsing 
281b8b016bfSjsing 	/* Extract and decode receipt content */
282b8b016bfSjsing 	pcont = CMS_get0_content(cms);
283b8b016bfSjsing 	if (!pcont || !*pcont) {
284be6ec861Sjsing 		CMSerror(CMS_R_NO_CONTENT);
285b8b016bfSjsing 		goto err;
286b8b016bfSjsing 	}
287b8b016bfSjsing 
2880a940e1fSjsing 	rct = ASN1_item_unpack(*pcont, &CMS_Receipt_it);
289b8b016bfSjsing 
290b8b016bfSjsing 	if (!rct) {
291be6ec861Sjsing 		CMSerror(CMS_R_RECEIPT_DECODE_ERROR);
292b8b016bfSjsing 		goto err;
293b8b016bfSjsing 	}
294b8b016bfSjsing 
295b8b016bfSjsing 	/* Locate original request */
296b8b016bfSjsing 
297b8b016bfSjsing 	for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) {
298b8b016bfSjsing 		osi = sk_CMS_SignerInfo_value(osis, i);
299b8b016bfSjsing 		if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue))
300b8b016bfSjsing 			break;
301b8b016bfSjsing 	}
302b8b016bfSjsing 
303b8b016bfSjsing 	if (i == sk_CMS_SignerInfo_num(osis)) {
304be6ec861Sjsing 		CMSerror(CMS_R_NO_MATCHING_SIGNATURE);
305b8b016bfSjsing 		goto err;
306b8b016bfSjsing 	}
307b8b016bfSjsing 
308b8b016bfSjsing 	si = sk_CMS_SignerInfo_value(sis, 0);
309b8b016bfSjsing 
310b8b016bfSjsing 	/* Get msgSigDigest value and compare */
311b8b016bfSjsing 
312b8b016bfSjsing 	msig = CMS_signed_get0_data_by_OBJ(si,
31372419cc7Sjsing 	    OBJ_nid2obj(NID_id_smime_aa_msgSigDigest), -3, V_ASN1_OCTET_STRING);
314b8b016bfSjsing 
315b8b016bfSjsing 	if (!msig) {
316be6ec861Sjsing 		CMSerror(CMS_R_NO_MSGSIGDIGEST);
317b8b016bfSjsing 		goto err;
318b8b016bfSjsing 	}
319b8b016bfSjsing 
320b8b016bfSjsing 	if (!cms_msgSigDigest(osi, dig, &diglen)) {
321be6ec861Sjsing 		CMSerror(CMS_R_MSGSIGDIGEST_ERROR);
322b8b016bfSjsing 		goto err;
323b8b016bfSjsing 	}
324b8b016bfSjsing 
325b8b016bfSjsing 	if (diglen != (unsigned int)msig->length) {
326be6ec861Sjsing 		CMSerror(CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
327b8b016bfSjsing 		goto err;
328b8b016bfSjsing 	}
329b8b016bfSjsing 
330b8b016bfSjsing 	if (memcmp(dig, msig->data, diglen)) {
331be6ec861Sjsing 		CMSerror(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
332b8b016bfSjsing 		goto err;
333b8b016bfSjsing 	}
334b8b016bfSjsing 
335b8b016bfSjsing 	/* Compare content types */
336b8b016bfSjsing 
337b8b016bfSjsing 	octype = CMS_signed_get0_data_by_OBJ(osi,
33872419cc7Sjsing 	    OBJ_nid2obj(NID_pkcs9_contentType), -3, V_ASN1_OBJECT);
339b8b016bfSjsing 	if (!octype) {
340be6ec861Sjsing 		CMSerror(CMS_R_NO_CONTENT_TYPE);
341b8b016bfSjsing 		goto err;
342b8b016bfSjsing 	}
343b8b016bfSjsing 
344b8b016bfSjsing 	/* Compare details in receipt request */
345b8b016bfSjsing 
346b8b016bfSjsing 	if (OBJ_cmp(octype, rct->contentType)) {
347be6ec861Sjsing 		CMSerror(CMS_R_CONTENT_TYPE_MISMATCH);
348b8b016bfSjsing 		goto err;
349b8b016bfSjsing 	}
350b8b016bfSjsing 
351b8b016bfSjsing 	/* Get original receipt request details */
352b8b016bfSjsing 
353b8b016bfSjsing 	if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) {
354be6ec861Sjsing 		CMSerror(CMS_R_NO_RECEIPT_REQUEST);
355b8b016bfSjsing 		goto err;
356b8b016bfSjsing 	}
357b8b016bfSjsing 
358b8b016bfSjsing 	if (ASN1_STRING_cmp(rr->signedContentIdentifier,
359b8b016bfSjsing 	    rct->signedContentIdentifier)) {
360be6ec861Sjsing 		CMSerror(CMS_R_CONTENTIDENTIFIER_MISMATCH);
361b8b016bfSjsing 		goto err;
362b8b016bfSjsing 	}
363b8b016bfSjsing 
364b8b016bfSjsing 	r = 1;
365b8b016bfSjsing 
366b8b016bfSjsing  err:
367b8b016bfSjsing 	CMS_ReceiptRequest_free(rr);
368f2f5f7c4Sjsing 	ASN1_item_free((ASN1_VALUE *)rct, &CMS_Receipt_it);
369b8b016bfSjsing 	return r;
370b8b016bfSjsing }
371b8b016bfSjsing 
372b8b016bfSjsing /*
373b8b016bfSjsing  * Encode a Receipt into an OCTET STRING read for including into content of a
374b8b016bfSjsing  * SignedData ContentInfo.
375b8b016bfSjsing  */
376b8b016bfSjsing 
37772419cc7Sjsing ASN1_OCTET_STRING *
37872419cc7Sjsing cms_encode_Receipt(CMS_SignerInfo *si)
379b8b016bfSjsing {
380b8b016bfSjsing 	CMS_Receipt rct;
381b8b016bfSjsing 	CMS_ReceiptRequest *rr = NULL;
382b8b016bfSjsing 	ASN1_OBJECT *ctype;
383b8b016bfSjsing 	ASN1_OCTET_STRING *os = NULL;
384b8b016bfSjsing 
385b8b016bfSjsing 	/* Get original receipt request */
386b8b016bfSjsing 
387b8b016bfSjsing 	/* Get original receipt request details */
388b8b016bfSjsing 
389b8b016bfSjsing 	if (CMS_get1_ReceiptRequest(si, &rr) <= 0) {
390be6ec861Sjsing 		CMSerror(CMS_R_NO_RECEIPT_REQUEST);
391b8b016bfSjsing 		goto err;
392b8b016bfSjsing 	}
393b8b016bfSjsing 
394b8b016bfSjsing 	/* Get original content type */
395b8b016bfSjsing 
396b8b016bfSjsing 	ctype = CMS_signed_get0_data_by_OBJ(si,
39772419cc7Sjsing 	    OBJ_nid2obj(NID_pkcs9_contentType), -3, V_ASN1_OBJECT);
398b8b016bfSjsing 	if (!ctype) {
399be6ec861Sjsing 		CMSerror(CMS_R_NO_CONTENT_TYPE);
400b8b016bfSjsing 		goto err;
401b8b016bfSjsing 	}
402b8b016bfSjsing 
403b8b016bfSjsing 	rct.version = 1;
404b8b016bfSjsing 	rct.contentType = ctype;
405b8b016bfSjsing 	rct.signedContentIdentifier = rr->signedContentIdentifier;
406b8b016bfSjsing 	rct.originatorSignatureValue = si->signature;
407b8b016bfSjsing 
4080a940e1fSjsing 	os = ASN1_item_pack(&rct, &CMS_Receipt_it, NULL);
409b8b016bfSjsing 
410b8b016bfSjsing  err:
411b8b016bfSjsing 	CMS_ReceiptRequest_free(rr);
412b8b016bfSjsing 	return os;
413b8b016bfSjsing }
414