1a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* crypto/cms/cms_ess.c */ 2a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3a88cfce91374498578c44013041416c0c5b09b1eKenny Root * project. 4a88cfce91374498578c44013041416c0c5b09b1eKenny Root */ 5a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* ==================================================================== 6a88cfce91374498578c44013041416c0c5b09b1eKenny Root * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 7a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 8a88cfce91374498578c44013041416c0c5b09b1eKenny Root * Redistribution and use in source and binary forms, with or without 9a88cfce91374498578c44013041416c0c5b09b1eKenny Root * modification, are permitted provided that the following conditions 10a88cfce91374498578c44013041416c0c5b09b1eKenny Root * are met: 11a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 12a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 1. Redistributions of source code must retain the above copyright 13a88cfce91374498578c44013041416c0c5b09b1eKenny Root * notice, this list of conditions and the following disclaimer. 14a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 15a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 2. Redistributions in binary form must reproduce the above copyright 16a88cfce91374498578c44013041416c0c5b09b1eKenny Root * notice, this list of conditions and the following disclaimer in 17a88cfce91374498578c44013041416c0c5b09b1eKenny Root * the documentation and/or other materials provided with the 18a88cfce91374498578c44013041416c0c5b09b1eKenny Root * distribution. 19a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 20a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 3. All advertising materials mentioning features or use of this 21a88cfce91374498578c44013041416c0c5b09b1eKenny Root * software must display the following acknowledgment: 22a88cfce91374498578c44013041416c0c5b09b1eKenny Root * "This product includes software developed by the OpenSSL Project 23a88cfce91374498578c44013041416c0c5b09b1eKenny Root * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 25a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26a88cfce91374498578c44013041416c0c5b09b1eKenny Root * endorse or promote products derived from this software without 27a88cfce91374498578c44013041416c0c5b09b1eKenny Root * prior written permission. For written permission, please contact 28a88cfce91374498578c44013041416c0c5b09b1eKenny Root * licensing@OpenSSL.org. 29a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 30a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 5. Products derived from this software may not be called "OpenSSL" 31a88cfce91374498578c44013041416c0c5b09b1eKenny Root * nor may "OpenSSL" appear in their names without prior written 32a88cfce91374498578c44013041416c0c5b09b1eKenny Root * permission of the OpenSSL Project. 33a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 34a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 6. Redistributions of any form whatsoever must retain the following 35a88cfce91374498578c44013041416c0c5b09b1eKenny Root * acknowledgment: 36a88cfce91374498578c44013041416c0c5b09b1eKenny Root * "This product includes software developed by the OpenSSL Project 37a88cfce91374498578c44013041416c0c5b09b1eKenny Root * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 39a88cfce91374498578c44013041416c0c5b09b1eKenny Root * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40a88cfce91374498578c44013041416c0c5b09b1eKenny Root * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41a88cfce91374498578c44013041416c0c5b09b1eKenny Root * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42a88cfce91374498578c44013041416c0c5b09b1eKenny Root * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43a88cfce91374498578c44013041416c0c5b09b1eKenny Root * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44a88cfce91374498578c44013041416c0c5b09b1eKenny Root * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45a88cfce91374498578c44013041416c0c5b09b1eKenny Root * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46a88cfce91374498578c44013041416c0c5b09b1eKenny Root * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47a88cfce91374498578c44013041416c0c5b09b1eKenny Root * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48a88cfce91374498578c44013041416c0c5b09b1eKenny Root * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49a88cfce91374498578c44013041416c0c5b09b1eKenny Root * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50a88cfce91374498578c44013041416c0c5b09b1eKenny Root * OF THE POSSIBILITY OF SUCH DAMAGE. 51a88cfce91374498578c44013041416c0c5b09b1eKenny Root * ==================================================================== 52a88cfce91374498578c44013041416c0c5b09b1eKenny Root */ 53a88cfce91374498578c44013041416c0c5b09b1eKenny Root 54a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cryptlib.h" 55a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/asn1t.h> 56a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/pem.h> 57a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/rand.h> 58a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/x509v3.h> 59a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/err.h> 60a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/cms.h> 61a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cms_lcl.h" 62a88cfce91374498578c44013041416c0c5b09b1eKenny Root 63a88cfce91374498578c44013041416c0c5b09b1eKenny RootDECLARE_ASN1_ITEM(CMS_ReceiptRequest) 64a88cfce91374498578c44013041416c0c5b09b1eKenny RootDECLARE_ASN1_ITEM(CMS_Receipt) 65a88cfce91374498578c44013041416c0c5b09b1eKenny Root 66a88cfce91374498578c44013041416c0c5b09b1eKenny RootIMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) 67a88cfce91374498578c44013041416c0c5b09b1eKenny Root 68a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* ESS services: for now just Signed Receipt related */ 69a88cfce91374498578c44013041416c0c5b09b1eKenny Root 70a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) 71a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 72a88cfce91374498578c44013041416c0c5b09b1eKenny Root ASN1_STRING *str; 73a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ReceiptRequest *rr = NULL; 74a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (prr) 75a88cfce91374498578c44013041416c0c5b09b1eKenny Root *prr = NULL; 76a88cfce91374498578c44013041416c0c5b09b1eKenny Root str = CMS_signed_get0_data_by_OBJ(si, 77a88cfce91374498578c44013041416c0c5b09b1eKenny Root OBJ_nid2obj(NID_id_smime_aa_receiptRequest), 78a88cfce91374498578c44013041416c0c5b09b1eKenny Root -3, V_ASN1_SEQUENCE); 79a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!str) 80a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 81a88cfce91374498578c44013041416c0c5b09b1eKenny Root 82a88cfce91374498578c44013041416c0c5b09b1eKenny Root rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest)); 83a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!rr) 84a88cfce91374498578c44013041416c0c5b09b1eKenny Root return -1; 85a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (prr) 86a88cfce91374498578c44013041416c0c5b09b1eKenny Root *prr = rr; 87a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 88a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ReceiptRequest_free(rr); 89a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 90a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 91a88cfce91374498578c44013041416c0c5b09b1eKenny Root 92a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, 93a88cfce91374498578c44013041416c0c5b09b1eKenny Root int allorfirst, 94a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(GENERAL_NAMES) *receiptList, 95a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(GENERAL_NAMES) *receiptsTo) 96a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 97a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ReceiptRequest *rr = NULL; 98a88cfce91374498578c44013041416c0c5b09b1eKenny Root 99a88cfce91374498578c44013041416c0c5b09b1eKenny Root rr = CMS_ReceiptRequest_new(); 100a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!rr) 101a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto merr; 102a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (id) 103a88cfce91374498578c44013041416c0c5b09b1eKenny Root ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen); 104a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 105a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 106a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) 107a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto merr; 108a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32) 109a88cfce91374498578c44013041416c0c5b09b1eKenny Root <= 0) 110a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 111a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 112a88cfce91374498578c44013041416c0c5b09b1eKenny Root 113a88cfce91374498578c44013041416c0c5b09b1eKenny Root sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); 114a88cfce91374498578c44013041416c0c5b09b1eKenny Root rr->receiptsTo = receiptsTo; 115a88cfce91374498578c44013041416c0c5b09b1eKenny Root 116a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (receiptList) 117a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 118a88cfce91374498578c44013041416c0c5b09b1eKenny Root rr->receiptsFrom->type = 1; 119a88cfce91374498578c44013041416c0c5b09b1eKenny Root rr->receiptsFrom->d.receiptList = receiptList; 120a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 121a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 122a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 123a88cfce91374498578c44013041416c0c5b09b1eKenny Root rr->receiptsFrom->type = 0; 124a88cfce91374498578c44013041416c0c5b09b1eKenny Root rr->receiptsFrom->d.allOrFirstTier = allorfirst; 125a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 126a88cfce91374498578c44013041416c0c5b09b1eKenny Root 127a88cfce91374498578c44013041416c0c5b09b1eKenny Root return rr; 128a88cfce91374498578c44013041416c0c5b09b1eKenny Root 129a88cfce91374498578c44013041416c0c5b09b1eKenny Root merr: 130a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE); 131a88cfce91374498578c44013041416c0c5b09b1eKenny Root 132a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 133a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (rr) 134a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ReceiptRequest_free(rr); 135a88cfce91374498578c44013041416c0c5b09b1eKenny Root 136a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 137a88cfce91374498578c44013041416c0c5b09b1eKenny Root 138a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 139a88cfce91374498578c44013041416c0c5b09b1eKenny Root 140a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) 141a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 142a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned char *rrder = NULL; 143a88cfce91374498578c44013041416c0c5b09b1eKenny Root int rrderlen, r = 0; 144a88cfce91374498578c44013041416c0c5b09b1eKenny Root 145a88cfce91374498578c44013041416c0c5b09b1eKenny Root rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder); 146a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (rrderlen < 0) 147a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto merr; 148a88cfce91374498578c44013041416c0c5b09b1eKenny Root 149a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest, 150a88cfce91374498578c44013041416c0c5b09b1eKenny Root V_ASN1_SEQUENCE, rrder, rrderlen)) 151a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto merr; 152a88cfce91374498578c44013041416c0c5b09b1eKenny Root 153a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = 1; 154a88cfce91374498578c44013041416c0c5b09b1eKenny Root 155a88cfce91374498578c44013041416c0c5b09b1eKenny Root merr: 156a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!r) 157a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE); 158a88cfce91374498578c44013041416c0c5b09b1eKenny Root 159a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (rrder) 160a88cfce91374498578c44013041416c0c5b09b1eKenny Root OPENSSL_free(rrder); 161a88cfce91374498578c44013041416c0c5b09b1eKenny Root 162a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 163a88cfce91374498578c44013041416c0c5b09b1eKenny Root 164a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 165a88cfce91374498578c44013041416c0c5b09b1eKenny Root 166a88cfce91374498578c44013041416c0c5b09b1eKenny Rootvoid CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, 167a88cfce91374498578c44013041416c0c5b09b1eKenny Root ASN1_STRING **pcid, 168a88cfce91374498578c44013041416c0c5b09b1eKenny Root int *pallorfirst, 169a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(GENERAL_NAMES) **plist, 170a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(GENERAL_NAMES) **prto) 171a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 172a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (pcid) 173a88cfce91374498578c44013041416c0c5b09b1eKenny Root *pcid = rr->signedContentIdentifier; 174a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (rr->receiptsFrom->type == 0) 175a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 176a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (pallorfirst) 177a88cfce91374498578c44013041416c0c5b09b1eKenny Root *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; 178a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (plist) 179a88cfce91374498578c44013041416c0c5b09b1eKenny Root *plist = NULL; 180a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 181a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 182a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 183a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (pallorfirst) 184a88cfce91374498578c44013041416c0c5b09b1eKenny Root *pallorfirst = -1; 185a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (plist) 186a88cfce91374498578c44013041416c0c5b09b1eKenny Root *plist = rr->receiptsFrom->d.receiptList; 187a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 188a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (prto) 189a88cfce91374498578c44013041416c0c5b09b1eKenny Root *prto = rr->receiptsTo; 190a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 191a88cfce91374498578c44013041416c0c5b09b1eKenny Root 192a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Digest a SignerInfo structure for msgSigDigest attribute processing */ 193a88cfce91374498578c44013041416c0c5b09b1eKenny Root 194a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_msgSigDigest(CMS_SignerInfo *si, 195a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned char *dig, unsigned int *diglen) 196a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 197a88cfce91374498578c44013041416c0c5b09b1eKenny Root const EVP_MD *md; 198a88cfce91374498578c44013041416c0c5b09b1eKenny Root md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 199a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (md == NULL) 200a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 201a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, 202a88cfce91374498578c44013041416c0c5b09b1eKenny Root si->signedAttrs, dig, diglen)) 203a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 204a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 205a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 206a88cfce91374498578c44013041416c0c5b09b1eKenny Root 207a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Add a msgSigDigest attribute to a SignerInfo */ 208a88cfce91374498578c44013041416c0c5b09b1eKenny Root 209a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) 210a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 211a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned char dig[EVP_MAX_MD_SIZE]; 212a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int diglen; 213a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms_msgSigDigest(src, dig, &diglen)) 214a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 215a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR); 216a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 217a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 218a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, 219a88cfce91374498578c44013041416c0c5b09b1eKenny Root V_ASN1_OCTET_STRING, dig, diglen)) 220a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 221a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE); 222a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 223a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 224a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 225a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 226a88cfce91374498578c44013041416c0c5b09b1eKenny Root 227a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Verify signed receipt after it has already passed normal CMS verify */ 228a88cfce91374498578c44013041416c0c5b09b1eKenny Root 229a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) 230a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 231a88cfce91374498578c44013041416c0c5b09b1eKenny Root int r = 0, i; 232a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ReceiptRequest *rr = NULL; 233a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_Receipt *rct = NULL; 234a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(CMS_SignerInfo) *sis, *osis; 235a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_SignerInfo *si, *osi = NULL; 236a88cfce91374498578c44013041416c0c5b09b1eKenny Root ASN1_OCTET_STRING *msig, **pcont; 237a88cfce91374498578c44013041416c0c5b09b1eKenny Root ASN1_OBJECT *octype; 238a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned char dig[EVP_MAX_MD_SIZE]; 239a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int diglen; 240a88cfce91374498578c44013041416c0c5b09b1eKenny Root 241a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Get SignerInfos, also checks SignedData content type */ 242a88cfce91374498578c44013041416c0c5b09b1eKenny Root osis = CMS_get0_SignerInfos(req_cms); 243a88cfce91374498578c44013041416c0c5b09b1eKenny Root sis = CMS_get0_SignerInfos(cms); 244a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!osis || !sis) 245a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 246a88cfce91374498578c44013041416c0c5b09b1eKenny Root 247a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (sk_CMS_SignerInfo_num(sis) != 1) 248a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 249a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER); 250a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 251a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 252a88cfce91374498578c44013041416c0c5b09b1eKenny Root 253a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Check receipt content type */ 254a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) 255a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 256a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT); 257a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 258a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 259a88cfce91374498578c44013041416c0c5b09b1eKenny Root 260a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Extract and decode receipt content */ 261a88cfce91374498578c44013041416c0c5b09b1eKenny Root pcont = CMS_get0_content(cms); 262a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!pcont || !*pcont) 263a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 264a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT); 265a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 266a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 267a88cfce91374498578c44013041416c0c5b09b1eKenny Root 268a88cfce91374498578c44013041416c0c5b09b1eKenny Root rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt)); 269a88cfce91374498578c44013041416c0c5b09b1eKenny Root 270a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!rct) 271a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 272a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR); 273a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 274a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 275a88cfce91374498578c44013041416c0c5b09b1eKenny Root 276a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Locate original request */ 277a88cfce91374498578c44013041416c0c5b09b1eKenny Root 278a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) 279a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 280a88cfce91374498578c44013041416c0c5b09b1eKenny Root osi = sk_CMS_SignerInfo_value(osis, i); 281a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!ASN1_STRING_cmp(osi->signature, 282a88cfce91374498578c44013041416c0c5b09b1eKenny Root rct->originatorSignatureValue)) 283a88cfce91374498578c44013041416c0c5b09b1eKenny Root break; 284a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 285a88cfce91374498578c44013041416c0c5b09b1eKenny Root 286a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (i == sk_CMS_SignerInfo_num(osis)) 287a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 288a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE); 289a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 290a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 291a88cfce91374498578c44013041416c0c5b09b1eKenny Root 292a88cfce91374498578c44013041416c0c5b09b1eKenny Root si = sk_CMS_SignerInfo_value(sis, 0); 293a88cfce91374498578c44013041416c0c5b09b1eKenny Root 294a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Get msgSigDigest value and compare */ 295a88cfce91374498578c44013041416c0c5b09b1eKenny Root 296a88cfce91374498578c44013041416c0c5b09b1eKenny Root msig = CMS_signed_get0_data_by_OBJ(si, 297a88cfce91374498578c44013041416c0c5b09b1eKenny Root OBJ_nid2obj(NID_id_smime_aa_msgSigDigest), 298a88cfce91374498578c44013041416c0c5b09b1eKenny Root -3, V_ASN1_OCTET_STRING); 299a88cfce91374498578c44013041416c0c5b09b1eKenny Root 300a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!msig) 301a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 302a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST); 303a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 304a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 305a88cfce91374498578c44013041416c0c5b09b1eKenny Root 306a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms_msgSigDigest(osi, dig, &diglen)) 307a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 308a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR); 309a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 310a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 311a88cfce91374498578c44013041416c0c5b09b1eKenny Root 312a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (diglen != (unsigned int)msig->length) 313a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 314a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, 315a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_MSGSIGDIGEST_WRONG_LENGTH); 316a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 317a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 318a88cfce91374498578c44013041416c0c5b09b1eKenny Root 319a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (memcmp(dig, msig->data, diglen)) 320a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 321a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, 322a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); 323a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 324a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 325a88cfce91374498578c44013041416c0c5b09b1eKenny Root 326a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Compare content types */ 327a88cfce91374498578c44013041416c0c5b09b1eKenny Root 328a88cfce91374498578c44013041416c0c5b09b1eKenny Root octype = CMS_signed_get0_data_by_OBJ(osi, 329a88cfce91374498578c44013041416c0c5b09b1eKenny Root OBJ_nid2obj(NID_pkcs9_contentType), 330a88cfce91374498578c44013041416c0c5b09b1eKenny Root -3, V_ASN1_OBJECT); 331a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!octype) 332a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 333a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE); 334a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 335a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 336a88cfce91374498578c44013041416c0c5b09b1eKenny Root 337a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Compare details in receipt request */ 338a88cfce91374498578c44013041416c0c5b09b1eKenny Root 339a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (OBJ_cmp(octype, rct->contentType)) 340a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 341a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH); 342a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 343a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 344a88cfce91374498578c44013041416c0c5b09b1eKenny Root 345a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Get original receipt request details */ 346a88cfce91374498578c44013041416c0c5b09b1eKenny Root 347a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) 348a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 349a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); 350a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 351a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 352a88cfce91374498578c44013041416c0c5b09b1eKenny Root 353a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (ASN1_STRING_cmp(rr->signedContentIdentifier, 354a88cfce91374498578c44013041416c0c5b09b1eKenny Root rct->signedContentIdentifier)) 355a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 356a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_RECEIPT_VERIFY, 357a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_CONTENTIDENTIFIER_MISMATCH); 358a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 359a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 360a88cfce91374498578c44013041416c0c5b09b1eKenny Root 361a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = 1; 362a88cfce91374498578c44013041416c0c5b09b1eKenny Root 363a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 364a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (rr) 365a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ReceiptRequest_free(rr); 366a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (rct) 367a88cfce91374498578c44013041416c0c5b09b1eKenny Root M_ASN1_free_of(rct, CMS_Receipt); 368a88cfce91374498578c44013041416c0c5b09b1eKenny Root 369a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 370a88cfce91374498578c44013041416c0c5b09b1eKenny Root 371a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 372a88cfce91374498578c44013041416c0c5b09b1eKenny Root 373a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Encode a Receipt into an OCTET STRING read for including into content of 374a88cfce91374498578c44013041416c0c5b09b1eKenny Root * a SignedData ContentInfo. 375a88cfce91374498578c44013041416c0c5b09b1eKenny Root */ 376a88cfce91374498578c44013041416c0c5b09b1eKenny Root 377a88cfce91374498578c44013041416c0c5b09b1eKenny RootASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) 378a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 379a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_Receipt rct; 380a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ReceiptRequest *rr = NULL; 381a88cfce91374498578c44013041416c0c5b09b1eKenny Root ASN1_OBJECT *ctype; 382a88cfce91374498578c44013041416c0c5b09b1eKenny Root ASN1_OCTET_STRING *os = NULL; 383a88cfce91374498578c44013041416c0c5b09b1eKenny Root 384a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Get original receipt request */ 385a88cfce91374498578c44013041416c0c5b09b1eKenny Root 386a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Get original receipt request details */ 387a88cfce91374498578c44013041416c0c5b09b1eKenny Root 388a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (CMS_get1_ReceiptRequest(si, &rr) <= 0) 389a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 390a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); 391a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 392a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 393a88cfce91374498578c44013041416c0c5b09b1eKenny Root 394a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Get original content type */ 395a88cfce91374498578c44013041416c0c5b09b1eKenny Root 396a88cfce91374498578c44013041416c0c5b09b1eKenny Root ctype = CMS_signed_get0_data_by_OBJ(si, 397a88cfce91374498578c44013041416c0c5b09b1eKenny Root OBJ_nid2obj(NID_pkcs9_contentType), 398a88cfce91374498578c44013041416c0c5b09b1eKenny Root -3, V_ASN1_OBJECT); 399a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!ctype) 400a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 401a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE); 402a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 403a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 404a88cfce91374498578c44013041416c0c5b09b1eKenny Root 405a88cfce91374498578c44013041416c0c5b09b1eKenny Root rct.version = 1; 406a88cfce91374498578c44013041416c0c5b09b1eKenny Root rct.contentType = ctype; 407a88cfce91374498578c44013041416c0c5b09b1eKenny Root rct.signedContentIdentifier = rr->signedContentIdentifier; 408a88cfce91374498578c44013041416c0c5b09b1eKenny Root rct.originatorSignatureValue = si->signature; 409a88cfce91374498578c44013041416c0c5b09b1eKenny Root 410a88cfce91374498578c44013041416c0c5b09b1eKenny Root os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL); 411a88cfce91374498578c44013041416c0c5b09b1eKenny Root 412a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 413a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (rr) 414a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ReceiptRequest_free(rr); 415a88cfce91374498578c44013041416c0c5b09b1eKenny Root 416a88cfce91374498578c44013041416c0c5b09b1eKenny Root return os; 417a88cfce91374498578c44013041416c0c5b09b1eKenny Root 418a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 419a88cfce91374498578c44013041416c0c5b09b1eKenny Root 420a88cfce91374498578c44013041416c0c5b09b1eKenny Root 421