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