1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
11e1051a39Sopenharmony_ci#include <openssl/asn1t.h>
12e1051a39Sopenharmony_ci#include <openssl/pem.h>
13e1051a39Sopenharmony_ci#include <openssl/rand.h>
14e1051a39Sopenharmony_ci#include <openssl/x509v3.h>
15e1051a39Sopenharmony_ci#include <openssl/err.h>
16e1051a39Sopenharmony_ci#include <openssl/cms.h>
17e1051a39Sopenharmony_ci#include <openssl/ess.h>
18e1051a39Sopenharmony_ci#include "crypto/ess.h"
19e1051a39Sopenharmony_ci#include "crypto/x509.h"
20e1051a39Sopenharmony_ci#include "cms_local.h"
21e1051a39Sopenharmony_ci
22e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ci/* ESS services */
25e1051a39Sopenharmony_ci
26e1051a39Sopenharmony_ciint CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
27e1051a39Sopenharmony_ci{
28e1051a39Sopenharmony_ci    ASN1_STRING *str;
29e1051a39Sopenharmony_ci    CMS_ReceiptRequest *rr;
30e1051a39Sopenharmony_ci    ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_receiptRequest);
31e1051a39Sopenharmony_ci
32e1051a39Sopenharmony_ci    if (prr != NULL)
33e1051a39Sopenharmony_ci        *prr = NULL;
34e1051a39Sopenharmony_ci    str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE);
35e1051a39Sopenharmony_ci    if (str == NULL)
36e1051a39Sopenharmony_ci        return 0;
37e1051a39Sopenharmony_ci
38e1051a39Sopenharmony_ci    rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
39e1051a39Sopenharmony_ci    if (rr == NULL)
40e1051a39Sopenharmony_ci        return -1;
41e1051a39Sopenharmony_ci    if (prr != NULL)
42e1051a39Sopenharmony_ci        *prr = rr;
43e1051a39Sopenharmony_ci    else
44e1051a39Sopenharmony_ci        CMS_ReceiptRequest_free(rr);
45e1051a39Sopenharmony_ci    return 1;
46e1051a39Sopenharmony_ci}
47e1051a39Sopenharmony_ci
48e1051a39Sopenharmony_ci/*
49e1051a39Sopenharmony_ci * Returns 0 if attribute is not found, 1 if found,
50e1051a39Sopenharmony_ci * or -1 on attribute parsing failure.
51e1051a39Sopenharmony_ci */
52e1051a39Sopenharmony_cistatic int ossl_cms_signerinfo_get_signing_cert(const CMS_SignerInfo *si,
53e1051a39Sopenharmony_ci                                                ESS_SIGNING_CERT **psc)
54e1051a39Sopenharmony_ci{
55e1051a39Sopenharmony_ci    ASN1_STRING *str;
56e1051a39Sopenharmony_ci    ESS_SIGNING_CERT *sc;
57e1051a39Sopenharmony_ci    ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificate);
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ci    if (psc != NULL)
60e1051a39Sopenharmony_ci        *psc = NULL;
61e1051a39Sopenharmony_ci    str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE);
62e1051a39Sopenharmony_ci    if (str == NULL)
63e1051a39Sopenharmony_ci        return 0;
64e1051a39Sopenharmony_ci
65e1051a39Sopenharmony_ci    sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT));
66e1051a39Sopenharmony_ci    if (sc == NULL)
67e1051a39Sopenharmony_ci        return -1;
68e1051a39Sopenharmony_ci    if (psc != NULL)
69e1051a39Sopenharmony_ci        *psc = sc;
70e1051a39Sopenharmony_ci    else
71e1051a39Sopenharmony_ci        ESS_SIGNING_CERT_free(sc);
72e1051a39Sopenharmony_ci    return 1;
73e1051a39Sopenharmony_ci}
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci/*
76e1051a39Sopenharmony_ci * Returns 0 if attribute is not found, 1 if found,
77e1051a39Sopenharmony_ci * or -1 on attribute parsing failure.
78e1051a39Sopenharmony_ci */
79e1051a39Sopenharmony_cistatic int ossl_cms_signerinfo_get_signing_cert_v2(const CMS_SignerInfo *si,
80e1051a39Sopenharmony_ci                                                   ESS_SIGNING_CERT_V2 **psc)
81e1051a39Sopenharmony_ci{
82e1051a39Sopenharmony_ci    ASN1_STRING *str;
83e1051a39Sopenharmony_ci    ESS_SIGNING_CERT_V2 *sc;
84e1051a39Sopenharmony_ci    ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificateV2);
85e1051a39Sopenharmony_ci
86e1051a39Sopenharmony_ci    if (psc != NULL)
87e1051a39Sopenharmony_ci        *psc = NULL;
88e1051a39Sopenharmony_ci    str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE);
89e1051a39Sopenharmony_ci    if (str == NULL)
90e1051a39Sopenharmony_ci        return 0;
91e1051a39Sopenharmony_ci
92e1051a39Sopenharmony_ci    sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT_V2));
93e1051a39Sopenharmony_ci    if (sc == NULL)
94e1051a39Sopenharmony_ci        return -1;
95e1051a39Sopenharmony_ci    if (psc != NULL)
96e1051a39Sopenharmony_ci        *psc = sc;
97e1051a39Sopenharmony_ci    else
98e1051a39Sopenharmony_ci        ESS_SIGNING_CERT_V2_free(sc);
99e1051a39Sopenharmony_ci    return 1;
100e1051a39Sopenharmony_ci}
101e1051a39Sopenharmony_ci
102e1051a39Sopenharmony_ciint ossl_cms_check_signing_certs(const CMS_SignerInfo *si,
103e1051a39Sopenharmony_ci                                 const STACK_OF(X509) *chain)
104e1051a39Sopenharmony_ci{
105e1051a39Sopenharmony_ci    ESS_SIGNING_CERT *ss = NULL;
106e1051a39Sopenharmony_ci    ESS_SIGNING_CERT_V2 *ssv2 = NULL;
107e1051a39Sopenharmony_ci    int ret = ossl_cms_signerinfo_get_signing_cert(si, &ss) >= 0
108e1051a39Sopenharmony_ci        && ossl_cms_signerinfo_get_signing_cert_v2(si, &ssv2) >= 0
109e1051a39Sopenharmony_ci        && OSSL_ESS_check_signing_certs(ss, ssv2, chain, 1) > 0;
110e1051a39Sopenharmony_ci
111e1051a39Sopenharmony_ci    ESS_SIGNING_CERT_free(ss);
112e1051a39Sopenharmony_ci    ESS_SIGNING_CERT_V2_free(ssv2);
113e1051a39Sopenharmony_ci    return ret;
114e1051a39Sopenharmony_ci}
115e1051a39Sopenharmony_ci
116e1051a39Sopenharmony_ciCMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex(
117e1051a39Sopenharmony_ci    unsigned char *id, int idlen, int allorfirst,
118e1051a39Sopenharmony_ci    STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo,
119e1051a39Sopenharmony_ci    OSSL_LIB_CTX *libctx)
120e1051a39Sopenharmony_ci{
121e1051a39Sopenharmony_ci    CMS_ReceiptRequest *rr;
122e1051a39Sopenharmony_ci
123e1051a39Sopenharmony_ci    rr = CMS_ReceiptRequest_new();
124e1051a39Sopenharmony_ci    if (rr == NULL)
125e1051a39Sopenharmony_ci        goto merr;
126e1051a39Sopenharmony_ci    if (id)
127e1051a39Sopenharmony_ci        ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
128e1051a39Sopenharmony_ci    else {
129e1051a39Sopenharmony_ci        if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
130e1051a39Sopenharmony_ci            goto merr;
131e1051a39Sopenharmony_ci        if (RAND_bytes_ex(libctx, rr->signedContentIdentifier->data, 32,
132e1051a39Sopenharmony_ci                          0) <= 0)
133e1051a39Sopenharmony_ci            goto err;
134e1051a39Sopenharmony_ci    }
135e1051a39Sopenharmony_ci
136e1051a39Sopenharmony_ci    sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
137e1051a39Sopenharmony_ci    rr->receiptsTo = receiptsTo;
138e1051a39Sopenharmony_ci
139e1051a39Sopenharmony_ci    if (receiptList != NULL) {
140e1051a39Sopenharmony_ci        rr->receiptsFrom->type = 1;
141e1051a39Sopenharmony_ci        rr->receiptsFrom->d.receiptList = receiptList;
142e1051a39Sopenharmony_ci    } else {
143e1051a39Sopenharmony_ci        rr->receiptsFrom->type = 0;
144e1051a39Sopenharmony_ci        rr->receiptsFrom->d.allOrFirstTier = allorfirst;
145e1051a39Sopenharmony_ci    }
146e1051a39Sopenharmony_ci
147e1051a39Sopenharmony_ci    return rr;
148e1051a39Sopenharmony_ci
149e1051a39Sopenharmony_ci merr:
150e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
151e1051a39Sopenharmony_ci
152e1051a39Sopenharmony_ci err:
153e1051a39Sopenharmony_ci    CMS_ReceiptRequest_free(rr);
154e1051a39Sopenharmony_ci    return NULL;
155e1051a39Sopenharmony_ci
156e1051a39Sopenharmony_ci}
157e1051a39Sopenharmony_ci
158e1051a39Sopenharmony_ciCMS_ReceiptRequest *CMS_ReceiptRequest_create0(
159e1051a39Sopenharmony_ci    unsigned char *id, int idlen, int allorfirst,
160e1051a39Sopenharmony_ci    STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo)
161e1051a39Sopenharmony_ci{
162e1051a39Sopenharmony_ci    return CMS_ReceiptRequest_create0_ex(id, idlen, allorfirst, receiptList,
163e1051a39Sopenharmony_ci                                         receiptsTo, NULL);
164e1051a39Sopenharmony_ci}
165e1051a39Sopenharmony_ci
166e1051a39Sopenharmony_ciint CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
167e1051a39Sopenharmony_ci{
168e1051a39Sopenharmony_ci    unsigned char *rrder = NULL;
169e1051a39Sopenharmony_ci    int rrderlen, r = 0;
170e1051a39Sopenharmony_ci
171e1051a39Sopenharmony_ci    rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
172e1051a39Sopenharmony_ci    if (rrderlen < 0)
173e1051a39Sopenharmony_ci        goto merr;
174e1051a39Sopenharmony_ci
175e1051a39Sopenharmony_ci    if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
176e1051a39Sopenharmony_ci                                     V_ASN1_SEQUENCE, rrder, rrderlen))
177e1051a39Sopenharmony_ci        goto merr;
178e1051a39Sopenharmony_ci
179e1051a39Sopenharmony_ci    r = 1;
180e1051a39Sopenharmony_ci
181e1051a39Sopenharmony_ci merr:
182e1051a39Sopenharmony_ci    if (!r)
183e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
184e1051a39Sopenharmony_ci
185e1051a39Sopenharmony_ci    OPENSSL_free(rrder);
186e1051a39Sopenharmony_ci
187e1051a39Sopenharmony_ci    return r;
188e1051a39Sopenharmony_ci
189e1051a39Sopenharmony_ci}
190e1051a39Sopenharmony_ci
191e1051a39Sopenharmony_civoid CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
192e1051a39Sopenharmony_ci                                    ASN1_STRING **pcid,
193e1051a39Sopenharmony_ci                                    int *pallorfirst,
194e1051a39Sopenharmony_ci                                    STACK_OF(GENERAL_NAMES) **plist,
195e1051a39Sopenharmony_ci                                    STACK_OF(GENERAL_NAMES) **prto)
196e1051a39Sopenharmony_ci{
197e1051a39Sopenharmony_ci    if (pcid != NULL)
198e1051a39Sopenharmony_ci        *pcid = rr->signedContentIdentifier;
199e1051a39Sopenharmony_ci    if (rr->receiptsFrom->type == 0) {
200e1051a39Sopenharmony_ci        if (pallorfirst != NULL)
201e1051a39Sopenharmony_ci            *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
202e1051a39Sopenharmony_ci        if (plist != NULL)
203e1051a39Sopenharmony_ci            *plist = NULL;
204e1051a39Sopenharmony_ci    } else {
205e1051a39Sopenharmony_ci        if (pallorfirst != NULL)
206e1051a39Sopenharmony_ci            *pallorfirst = -1;
207e1051a39Sopenharmony_ci        if (plist != NULL)
208e1051a39Sopenharmony_ci            *plist = rr->receiptsFrom->d.receiptList;
209e1051a39Sopenharmony_ci    }
210e1051a39Sopenharmony_ci    if (prto != NULL)
211e1051a39Sopenharmony_ci        *prto = rr->receiptsTo;
212e1051a39Sopenharmony_ci}
213e1051a39Sopenharmony_ci
214e1051a39Sopenharmony_ci/* Digest a SignerInfo structure for msgSigDigest attribute processing */
215e1051a39Sopenharmony_ci
216e1051a39Sopenharmony_cistatic int cms_msgSigDigest(CMS_SignerInfo *si,
217e1051a39Sopenharmony_ci                            unsigned char *dig, unsigned int *diglen)
218e1051a39Sopenharmony_ci{
219e1051a39Sopenharmony_ci    const EVP_MD *md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
220e1051a39Sopenharmony_ci
221e1051a39Sopenharmony_ci    if (md == NULL)
222e1051a39Sopenharmony_ci        return 0;
223e1051a39Sopenharmony_ci    if (!ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
224e1051a39Sopenharmony_ci                                  si->signedAttrs, dig, diglen,
225e1051a39Sopenharmony_ci                                  ossl_cms_ctx_get0_libctx(si->cms_ctx),
226e1051a39Sopenharmony_ci                                  ossl_cms_ctx_get0_propq(si->cms_ctx)))
227e1051a39Sopenharmony_ci        return 0;
228e1051a39Sopenharmony_ci    return 1;
229e1051a39Sopenharmony_ci}
230e1051a39Sopenharmony_ci
231e1051a39Sopenharmony_ci/* Add a msgSigDigest attribute to a SignerInfo */
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_ciint ossl_cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
234e1051a39Sopenharmony_ci{
235e1051a39Sopenharmony_ci    unsigned char dig[EVP_MAX_MD_SIZE];
236e1051a39Sopenharmony_ci    unsigned int diglen;
237e1051a39Sopenharmony_ci
238e1051a39Sopenharmony_ci    if (!cms_msgSigDigest(src, dig, &diglen)) {
239e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR);
240e1051a39Sopenharmony_ci        return 0;
241e1051a39Sopenharmony_ci    }
242e1051a39Sopenharmony_ci    if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
243e1051a39Sopenharmony_ci                                     V_ASN1_OCTET_STRING, dig, diglen)) {
244e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
245e1051a39Sopenharmony_ci        return 0;
246e1051a39Sopenharmony_ci    }
247e1051a39Sopenharmony_ci    return 1;
248e1051a39Sopenharmony_ci}
249e1051a39Sopenharmony_ci
250e1051a39Sopenharmony_ci/* Verify signed receipt after it has already passed normal CMS verify */
251e1051a39Sopenharmony_ci
252e1051a39Sopenharmony_ciint ossl_cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
253e1051a39Sopenharmony_ci{
254e1051a39Sopenharmony_ci    int r = 0, i;
255e1051a39Sopenharmony_ci    CMS_ReceiptRequest *rr = NULL;
256e1051a39Sopenharmony_ci    CMS_Receipt *rct = NULL;
257e1051a39Sopenharmony_ci    STACK_OF(CMS_SignerInfo) *sis, *osis;
258e1051a39Sopenharmony_ci    CMS_SignerInfo *si, *osi = NULL;
259e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *msig, **pcont;
260e1051a39Sopenharmony_ci    ASN1_OBJECT *octype;
261e1051a39Sopenharmony_ci    unsigned char dig[EVP_MAX_MD_SIZE];
262e1051a39Sopenharmony_ci    unsigned int diglen;
263e1051a39Sopenharmony_ci
264e1051a39Sopenharmony_ci    /* Get SignerInfos, also checks SignedData content type */
265e1051a39Sopenharmony_ci    osis = CMS_get0_SignerInfos(req_cms);
266e1051a39Sopenharmony_ci    sis = CMS_get0_SignerInfos(cms);
267e1051a39Sopenharmony_ci    if (!osis || !sis)
268e1051a39Sopenharmony_ci        goto err;
269e1051a39Sopenharmony_ci
270e1051a39Sopenharmony_ci    if (sk_CMS_SignerInfo_num(sis) != 1) {
271e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_NEED_ONE_SIGNER);
272e1051a39Sopenharmony_ci        goto err;
273e1051a39Sopenharmony_ci    }
274e1051a39Sopenharmony_ci
275e1051a39Sopenharmony_ci    /* Check receipt content type */
276e1051a39Sopenharmony_ci    if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) {
277e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_NOT_A_SIGNED_RECEIPT);
278e1051a39Sopenharmony_ci        goto err;
279e1051a39Sopenharmony_ci    }
280e1051a39Sopenharmony_ci
281e1051a39Sopenharmony_ci    /* Extract and decode receipt content */
282e1051a39Sopenharmony_ci    pcont = CMS_get0_content(cms);
283e1051a39Sopenharmony_ci    if (pcont == NULL || *pcont == NULL) {
284e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT);
285e1051a39Sopenharmony_ci        goto err;
286e1051a39Sopenharmony_ci    }
287e1051a39Sopenharmony_ci
288e1051a39Sopenharmony_ci    rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
289e1051a39Sopenharmony_ci
290e1051a39Sopenharmony_ci    if (!rct) {
291e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_RECEIPT_DECODE_ERROR);
292e1051a39Sopenharmony_ci        goto err;
293e1051a39Sopenharmony_ci    }
294e1051a39Sopenharmony_ci
295e1051a39Sopenharmony_ci    /* Locate original request */
296e1051a39Sopenharmony_ci
297e1051a39Sopenharmony_ci    for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) {
298e1051a39Sopenharmony_ci        osi = sk_CMS_SignerInfo_value(osis, i);
299e1051a39Sopenharmony_ci        if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue))
300e1051a39Sopenharmony_ci            break;
301e1051a39Sopenharmony_ci    }
302e1051a39Sopenharmony_ci
303e1051a39Sopenharmony_ci    if (i == sk_CMS_SignerInfo_num(osis)) {
304e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_SIGNATURE);
305e1051a39Sopenharmony_ci        goto err;
306e1051a39Sopenharmony_ci    }
307e1051a39Sopenharmony_ci
308e1051a39Sopenharmony_ci    si = sk_CMS_SignerInfo_value(sis, 0);
309e1051a39Sopenharmony_ci
310e1051a39Sopenharmony_ci    /* Get msgSigDigest value and compare */
311e1051a39Sopenharmony_ci
312e1051a39Sopenharmony_ci    msig = CMS_signed_get0_data_by_OBJ(si,
313e1051a39Sopenharmony_ci                                       OBJ_nid2obj
314e1051a39Sopenharmony_ci                                       (NID_id_smime_aa_msgSigDigest), -3,
315e1051a39Sopenharmony_ci                                       V_ASN1_OCTET_STRING);
316e1051a39Sopenharmony_ci
317e1051a39Sopenharmony_ci    if (!msig) {
318e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_NO_MSGSIGDIGEST);
319e1051a39Sopenharmony_ci        goto err;
320e1051a39Sopenharmony_ci    }
321e1051a39Sopenharmony_ci
322e1051a39Sopenharmony_ci    if (!cms_msgSigDigest(osi, dig, &diglen)) {
323e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR);
324e1051a39Sopenharmony_ci        goto err;
325e1051a39Sopenharmony_ci    }
326e1051a39Sopenharmony_ci
327e1051a39Sopenharmony_ci    if (diglen != (unsigned int)msig->length) {
328e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
329e1051a39Sopenharmony_ci        goto err;
330e1051a39Sopenharmony_ci    }
331e1051a39Sopenharmony_ci
332e1051a39Sopenharmony_ci    if (memcmp(dig, msig->data, diglen)) {
333e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
334e1051a39Sopenharmony_ci        goto err;
335e1051a39Sopenharmony_ci    }
336e1051a39Sopenharmony_ci
337e1051a39Sopenharmony_ci    /* Compare content types */
338e1051a39Sopenharmony_ci
339e1051a39Sopenharmony_ci    octype = CMS_signed_get0_data_by_OBJ(osi,
340e1051a39Sopenharmony_ci                                         OBJ_nid2obj(NID_pkcs9_contentType),
341e1051a39Sopenharmony_ci                                         -3, V_ASN1_OBJECT);
342e1051a39Sopenharmony_ci    if (!octype) {
343e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE);
344e1051a39Sopenharmony_ci        goto err;
345e1051a39Sopenharmony_ci    }
346e1051a39Sopenharmony_ci
347e1051a39Sopenharmony_ci    /* Compare details in receipt request */
348e1051a39Sopenharmony_ci
349e1051a39Sopenharmony_ci    if (OBJ_cmp(octype, rct->contentType)) {
350e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_MISMATCH);
351e1051a39Sopenharmony_ci        goto err;
352e1051a39Sopenharmony_ci    }
353e1051a39Sopenharmony_ci
354e1051a39Sopenharmony_ci    /* Get original receipt request details */
355e1051a39Sopenharmony_ci
356e1051a39Sopenharmony_ci    if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) {
357e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST);
358e1051a39Sopenharmony_ci        goto err;
359e1051a39Sopenharmony_ci    }
360e1051a39Sopenharmony_ci
361e1051a39Sopenharmony_ci    if (ASN1_STRING_cmp(rr->signedContentIdentifier,
362e1051a39Sopenharmony_ci                        rct->signedContentIdentifier)) {
363e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_CONTENTIDENTIFIER_MISMATCH);
364e1051a39Sopenharmony_ci        goto err;
365e1051a39Sopenharmony_ci    }
366e1051a39Sopenharmony_ci
367e1051a39Sopenharmony_ci    r = 1;
368e1051a39Sopenharmony_ci
369e1051a39Sopenharmony_ci err:
370e1051a39Sopenharmony_ci    CMS_ReceiptRequest_free(rr);
371e1051a39Sopenharmony_ci    M_ASN1_free_of(rct, CMS_Receipt);
372e1051a39Sopenharmony_ci    return r;
373e1051a39Sopenharmony_ci
374e1051a39Sopenharmony_ci}
375e1051a39Sopenharmony_ci
376e1051a39Sopenharmony_ci/*
377e1051a39Sopenharmony_ci * Encode a Receipt into an OCTET STRING read for including into content of a
378e1051a39Sopenharmony_ci * SignedData ContentInfo.
379e1051a39Sopenharmony_ci */
380e1051a39Sopenharmony_ci
381e1051a39Sopenharmony_ciASN1_OCTET_STRING *ossl_cms_encode_Receipt(CMS_SignerInfo *si)
382e1051a39Sopenharmony_ci{
383e1051a39Sopenharmony_ci    CMS_Receipt rct;
384e1051a39Sopenharmony_ci    CMS_ReceiptRequest *rr = NULL;
385e1051a39Sopenharmony_ci    ASN1_OBJECT *ctype;
386e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *os = NULL;
387e1051a39Sopenharmony_ci
388e1051a39Sopenharmony_ci    /* Get original receipt request */
389e1051a39Sopenharmony_ci
390e1051a39Sopenharmony_ci    /* Get original receipt request details */
391e1051a39Sopenharmony_ci
392e1051a39Sopenharmony_ci    if (CMS_get1_ReceiptRequest(si, &rr) <= 0) {
393e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST);
394e1051a39Sopenharmony_ci        goto err;
395e1051a39Sopenharmony_ci    }
396e1051a39Sopenharmony_ci
397e1051a39Sopenharmony_ci    /* Get original content type */
398e1051a39Sopenharmony_ci
399e1051a39Sopenharmony_ci    ctype = CMS_signed_get0_data_by_OBJ(si,
400e1051a39Sopenharmony_ci                                        OBJ_nid2obj(NID_pkcs9_contentType),
401e1051a39Sopenharmony_ci                                        -3, V_ASN1_OBJECT);
402e1051a39Sopenharmony_ci    if (!ctype) {
403e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE);
404e1051a39Sopenharmony_ci        goto err;
405e1051a39Sopenharmony_ci    }
406e1051a39Sopenharmony_ci
407e1051a39Sopenharmony_ci    rct.version = 1;
408e1051a39Sopenharmony_ci    rct.contentType = ctype;
409e1051a39Sopenharmony_ci    rct.signedContentIdentifier = rr->signedContentIdentifier;
410e1051a39Sopenharmony_ci    rct.originatorSignatureValue = si->signature;
411e1051a39Sopenharmony_ci
412e1051a39Sopenharmony_ci    os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);
413e1051a39Sopenharmony_ci
414e1051a39Sopenharmony_ci err:
415e1051a39Sopenharmony_ci    CMS_ReceiptRequest_free(rr);
416e1051a39Sopenharmony_ci    return os;
417e1051a39Sopenharmony_ci}
418