1a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* crypto/cms/cms_smime.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/x509.h> 57a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/x509v3.h> 58a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/err.h> 59a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/cms.h> 60a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cms_lcl.h" 61a88cfce91374498578c44013041416c0c5b09b1eKenny Root 62a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_copy_content(BIO *out, BIO *in, unsigned int flags) 63a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 64a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned char buf[4096]; 65a88cfce91374498578c44013041416c0c5b09b1eKenny Root int r = 0, i; 66a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *tmpout = NULL; 67a88cfce91374498578c44013041416c0c5b09b1eKenny Root 68a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (out == NULL) 69a88cfce91374498578c44013041416c0c5b09b1eKenny Root tmpout = BIO_new(BIO_s_null()); 70a88cfce91374498578c44013041416c0c5b09b1eKenny Root else if (flags & CMS_TEXT) 71a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 72a88cfce91374498578c44013041416c0c5b09b1eKenny Root tmpout = BIO_new(BIO_s_mem()); 73a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO_set_mem_eof_return(tmpout, 0); 74a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 75a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 76a88cfce91374498578c44013041416c0c5b09b1eKenny Root tmpout = out; 77a88cfce91374498578c44013041416c0c5b09b1eKenny Root 78a88cfce91374498578c44013041416c0c5b09b1eKenny Root if(!tmpout) 79a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 80a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE); 81a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 82a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 83a88cfce91374498578c44013041416c0c5b09b1eKenny Root 84a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Read all content through chain to process digest, decrypt etc */ 85a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (;;) 86a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 87a88cfce91374498578c44013041416c0c5b09b1eKenny Root i=BIO_read(in,buf,sizeof(buf)); 88a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (i <= 0) 89a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 90a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (BIO_method_type(in) == BIO_TYPE_CIPHER) 91a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 92a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!BIO_get_cipher_status(in)) 93a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 94a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 95a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (i < 0) 96a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 97a88cfce91374498578c44013041416c0c5b09b1eKenny Root break; 98a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 99a88cfce91374498578c44013041416c0c5b09b1eKenny Root 100a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (tmpout && (BIO_write(tmpout, buf, i) != i)) 101a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 102a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 103a88cfce91374498578c44013041416c0c5b09b1eKenny Root 104a88cfce91374498578c44013041416c0c5b09b1eKenny Root if(flags & CMS_TEXT) 105a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 106a88cfce91374498578c44013041416c0c5b09b1eKenny Root if(!SMIME_text(tmpout, out)) 107a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 108a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_COPY_CONTENT,CMS_R_SMIME_TEXT_ERROR); 109a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 110a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 111a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 112a88cfce91374498578c44013041416c0c5b09b1eKenny Root 113a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = 1; 114a88cfce91374498578c44013041416c0c5b09b1eKenny Root 115a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 116a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (tmpout && (tmpout != out)) 117a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO_free(tmpout); 118a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 119a88cfce91374498578c44013041416c0c5b09b1eKenny Root 120a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 121a88cfce91374498578c44013041416c0c5b09b1eKenny Root 122a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int check_content(CMS_ContentInfo *cms) 123a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 124a88cfce91374498578c44013041416c0c5b09b1eKenny Root ASN1_OCTET_STRING **pos = CMS_get0_content(cms); 125a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!pos || !*pos) 126a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 127a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT); 128a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 129a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 130a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 131a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 132a88cfce91374498578c44013041416c0c5b09b1eKenny Root 133a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic void do_free_upto(BIO *f, BIO *upto) 134a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 135a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (upto) 136a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 137a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *tbio; 138a88cfce91374498578c44013041416c0c5b09b1eKenny Root do 139a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 140a88cfce91374498578c44013041416c0c5b09b1eKenny Root tbio = BIO_pop(f); 141a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO_free(f); 142a88cfce91374498578c44013041416c0c5b09b1eKenny Root f = tbio; 143a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 144a88cfce91374498578c44013041416c0c5b09b1eKenny Root while (f != upto); 145a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 146a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 147a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO_free_all(f); 148a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 149a88cfce91374498578c44013041416c0c5b09b1eKenny Root 150a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) 151a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 152a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *cont; 153a88cfce91374498578c44013041416c0c5b09b1eKenny Root int r; 154a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) 155a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 156a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA); 157a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 158a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 159a88cfce91374498578c44013041416c0c5b09b1eKenny Root cont = CMS_dataInit(cms, NULL); 160a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cont) 161a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 162a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = cms_copy_content(out, cont, flags); 163a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO_free_all(cont); 164a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 165a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 166a88cfce91374498578c44013041416c0c5b09b1eKenny Root 167a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) 168a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 169a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo *cms; 170a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms = cms_Data_create(); 171a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms) 172a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 173a88cfce91374498578c44013041416c0c5b09b1eKenny Root 174a88cfce91374498578c44013041416c0c5b09b1eKenny Root if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 175a88cfce91374498578c44013041416c0c5b09b1eKenny Root return cms; 176a88cfce91374498578c44013041416c0c5b09b1eKenny Root 177a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo_free(cms); 178a88cfce91374498578c44013041416c0c5b09b1eKenny Root 179a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 180a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 181a88cfce91374498578c44013041416c0c5b09b1eKenny Root 182a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, 183a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int flags) 184a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 185a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *cont; 186a88cfce91374498578c44013041416c0c5b09b1eKenny Root int r; 187a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) 188a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 189a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA); 190a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 191a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 192a88cfce91374498578c44013041416c0c5b09b1eKenny Root 193a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!dcont && !check_content(cms)) 194a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 195a88cfce91374498578c44013041416c0c5b09b1eKenny Root 196a88cfce91374498578c44013041416c0c5b09b1eKenny Root cont = CMS_dataInit(cms, dcont); 197a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cont) 198a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 199a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = cms_copy_content(out, cont, flags); 200a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (r) 201a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = cms_DigestedData_do_final(cms, cont, 1); 202a88cfce91374498578c44013041416c0c5b09b1eKenny Root do_free_upto(cont, dcont); 203a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 204a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 205a88cfce91374498578c44013041416c0c5b09b1eKenny Root 206a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, 207a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int flags) 208a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 209a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo *cms; 210a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!md) 211a88cfce91374498578c44013041416c0c5b09b1eKenny Root md = EVP_sha1(); 212a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms = cms_DigestedData_create(md); 213a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms) 214a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 215a88cfce91374498578c44013041416c0c5b09b1eKenny Root 216a88cfce91374498578c44013041416c0c5b09b1eKenny Root if(!(flags & CMS_DETACHED)) 217a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_set_detached(cms, 0); 218a88cfce91374498578c44013041416c0c5b09b1eKenny Root 219a88cfce91374498578c44013041416c0c5b09b1eKenny Root if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 220a88cfce91374498578c44013041416c0c5b09b1eKenny Root return cms; 221a88cfce91374498578c44013041416c0c5b09b1eKenny Root 222a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo_free(cms); 223a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 224a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 225a88cfce91374498578c44013041416c0c5b09b1eKenny Root 226a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, 227a88cfce91374498578c44013041416c0c5b09b1eKenny Root const unsigned char *key, size_t keylen, 228a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *dcont, BIO *out, unsigned int flags) 229a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 230a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *cont; 231a88cfce91374498578c44013041416c0c5b09b1eKenny Root int r; 232a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) 233a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 234a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, 235a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_TYPE_NOT_ENCRYPTED_DATA); 236a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 237a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 238a88cfce91374498578c44013041416c0c5b09b1eKenny Root 239a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!dcont && !check_content(cms)) 240a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 241a88cfce91374498578c44013041416c0c5b09b1eKenny Root 242a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) 243a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 244a88cfce91374498578c44013041416c0c5b09b1eKenny Root cont = CMS_dataInit(cms, dcont); 245a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cont) 246a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 247a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = cms_copy_content(out, cont, flags); 248a88cfce91374498578c44013041416c0c5b09b1eKenny Root do_free_upto(cont, dcont); 249a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 250a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 251a88cfce91374498578c44013041416c0c5b09b1eKenny Root 252a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, 253a88cfce91374498578c44013041416c0c5b09b1eKenny Root const unsigned char *key, size_t keylen, 254a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int flags) 255a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 256a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo *cms; 257a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cipher) 258a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 259a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER); 260a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 261a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 262a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms = CMS_ContentInfo_new(); 263a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms) 264a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 265a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) 266a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 267a88cfce91374498578c44013041416c0c5b09b1eKenny Root 268a88cfce91374498578c44013041416c0c5b09b1eKenny Root if(!(flags & CMS_DETACHED)) 269a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_set_detached(cms, 0); 270a88cfce91374498578c44013041416c0c5b09b1eKenny Root 271a88cfce91374498578c44013041416c0c5b09b1eKenny Root if ((flags & (CMS_STREAM|CMS_PARTIAL)) 272a88cfce91374498578c44013041416c0c5b09b1eKenny Root || CMS_final(cms, in, NULL, flags)) 273a88cfce91374498578c44013041416c0c5b09b1eKenny Root return cms; 274a88cfce91374498578c44013041416c0c5b09b1eKenny Root 275a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo_free(cms); 276a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 277a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 278a88cfce91374498578c44013041416c0c5b09b1eKenny Root 279a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_signerinfo_verify_cert(CMS_SignerInfo *si, 280a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509_STORE *store, 281a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(X509) *certs, 282a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(X509_CRL) *crls, 283a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int flags) 284a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 285a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509_STORE_CTX ctx; 286a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509 *signer; 287a88cfce91374498578c44013041416c0c5b09b1eKenny Root int i, j, r = 0; 288a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); 289a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!X509_STORE_CTX_init(&ctx, store, signer, certs)) 290a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 291a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, 292a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_STORE_INIT_ERROR); 293a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 294a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 295a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509_STORE_CTX_set_default(&ctx, "smime_sign"); 296a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (crls) 297a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509_STORE_CTX_set0_crls(&ctx, crls); 298a88cfce91374498578c44013041416c0c5b09b1eKenny Root 299a88cfce91374498578c44013041416c0c5b09b1eKenny Root i = X509_verify_cert(&ctx); 300a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (i <= 0) 301a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 302a88cfce91374498578c44013041416c0c5b09b1eKenny Root j = X509_STORE_CTX_get_error(&ctx); 303a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, 304a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_CERTIFICATE_VERIFY_ERROR); 305a88cfce91374498578c44013041416c0c5b09b1eKenny Root ERR_add_error_data(2, "Verify error:", 306a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509_verify_cert_error_string(j)); 307a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 308a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 309a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = 1; 310a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 311a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509_STORE_CTX_cleanup(&ctx); 312a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 313a88cfce91374498578c44013041416c0c5b09b1eKenny Root 314a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 315a88cfce91374498578c44013041416c0c5b09b1eKenny Root 316a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, 317a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags) 318a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 319a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_SignerInfo *si; 320a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(CMS_SignerInfo) *sinfos; 321a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(X509) *cms_certs = NULL; 322a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(X509_CRL) *crls = NULL; 323a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509 *signer; 324a88cfce91374498578c44013041416c0c5b09b1eKenny Root int i, scount = 0, ret = 0; 325a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *cmsbio = NULL, *tmpin = NULL; 326a88cfce91374498578c44013041416c0c5b09b1eKenny Root 327a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!dcont && !check_content(cms)) 328a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 329a88cfce91374498578c44013041416c0c5b09b1eKenny Root 330a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Attempt to find all signer certificates */ 331a88cfce91374498578c44013041416c0c5b09b1eKenny Root 332a88cfce91374498578c44013041416c0c5b09b1eKenny Root sinfos = CMS_get0_SignerInfos(cms); 333a88cfce91374498578c44013041416c0c5b09b1eKenny Root 334a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (sk_CMS_SignerInfo_num(sinfos) <= 0) 335a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 336a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS); 337a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 338a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 339a88cfce91374498578c44013041416c0c5b09b1eKenny Root 340a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) 341a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 342a88cfce91374498578c44013041416c0c5b09b1eKenny Root si = sk_CMS_SignerInfo_value(sinfos, i); 343a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); 344a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (signer) 345a88cfce91374498578c44013041416c0c5b09b1eKenny Root scount++; 346a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 347a88cfce91374498578c44013041416c0c5b09b1eKenny Root 348a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (scount != sk_CMS_SignerInfo_num(sinfos)) 349a88cfce91374498578c44013041416c0c5b09b1eKenny Root scount += CMS_set1_signers_certs(cms, certs, flags); 350a88cfce91374498578c44013041416c0c5b09b1eKenny Root 351a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (scount != sk_CMS_SignerInfo_num(sinfos)) 352a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 353a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); 354a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 355a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 356a88cfce91374498578c44013041416c0c5b09b1eKenny Root 357a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Attempt to verify all signers certs */ 358a88cfce91374498578c44013041416c0c5b09b1eKenny Root 359a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) 360a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 361a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms_certs = CMS_get1_certs(cms); 362a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!(flags & CMS_NOCRL)) 363a88cfce91374498578c44013041416c0c5b09b1eKenny Root crls = CMS_get1_crls(cms); 364a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) 365a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 366a88cfce91374498578c44013041416c0c5b09b1eKenny Root si = sk_CMS_SignerInfo_value(sinfos, i); 367a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms_signerinfo_verify_cert(si, store, 368a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms_certs, crls, flags)) 369a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 370a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 371a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 372a88cfce91374498578c44013041416c0c5b09b1eKenny Root 373a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Attempt to verify all SignerInfo signed attribute signatures */ 374a88cfce91374498578c44013041416c0c5b09b1eKenny Root 375a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!(flags & CMS_NO_ATTR_VERIFY)) 376a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 377a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) 378a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 379a88cfce91374498578c44013041416c0c5b09b1eKenny Root si = sk_CMS_SignerInfo_value(sinfos, i); 380a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (CMS_signed_get_attr_count(si) < 0) 381a88cfce91374498578c44013041416c0c5b09b1eKenny Root continue; 382a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (CMS_SignerInfo_verify(si) <= 0) 383a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 384a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 385a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 386a88cfce91374498578c44013041416c0c5b09b1eKenny Root 387a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Performance optimization: if the content is a memory BIO then 388a88cfce91374498578c44013041416c0c5b09b1eKenny Root * store its contents in a temporary read only memory BIO. This 389a88cfce91374498578c44013041416c0c5b09b1eKenny Root * avoids potentially large numbers of slow copies of data which will 390a88cfce91374498578c44013041416c0c5b09b1eKenny Root * occur when reading from a read write memory BIO when signatures 391a88cfce91374498578c44013041416c0c5b09b1eKenny Root * are calculated. 392a88cfce91374498578c44013041416c0c5b09b1eKenny Root */ 393a88cfce91374498578c44013041416c0c5b09b1eKenny Root 394a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) 395a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 396a88cfce91374498578c44013041416c0c5b09b1eKenny Root char *ptr; 397a88cfce91374498578c44013041416c0c5b09b1eKenny Root long len; 398a88cfce91374498578c44013041416c0c5b09b1eKenny Root len = BIO_get_mem_data(dcont, &ptr); 399a88cfce91374498578c44013041416c0c5b09b1eKenny Root tmpin = BIO_new_mem_buf(ptr, len); 400a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (tmpin == NULL) 401a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 402a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_VERIFY,ERR_R_MALLOC_FAILURE); 403a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 404a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 405a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 406a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 407a88cfce91374498578c44013041416c0c5b09b1eKenny Root tmpin = dcont; 408a88cfce91374498578c44013041416c0c5b09b1eKenny Root 409a88cfce91374498578c44013041416c0c5b09b1eKenny Root 410a88cfce91374498578c44013041416c0c5b09b1eKenny Root cmsbio=CMS_dataInit(cms, tmpin); 411a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cmsbio) 412a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 413a88cfce91374498578c44013041416c0c5b09b1eKenny Root 414a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms_copy_content(out, cmsbio, flags)) 415a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 416a88cfce91374498578c44013041416c0c5b09b1eKenny Root 417a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!(flags & CMS_NO_CONTENT_VERIFY)) 418a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 419a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) 420a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 421a88cfce91374498578c44013041416c0c5b09b1eKenny Root si = sk_CMS_SignerInfo_value(sinfos, i); 422a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) 423a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 424a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_VERIFY, 425a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_CONTENT_VERIFY_ERROR); 426a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 427a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 428a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 429a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 430a88cfce91374498578c44013041416c0c5b09b1eKenny Root 431a88cfce91374498578c44013041416c0c5b09b1eKenny Root ret = 1; 432a88cfce91374498578c44013041416c0c5b09b1eKenny Root 433a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 434a88cfce91374498578c44013041416c0c5b09b1eKenny Root 435a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (dcont && (tmpin == dcont)) 436a88cfce91374498578c44013041416c0c5b09b1eKenny Root do_free_upto(cmsbio, dcont); 437a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 438a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO_free_all(cmsbio); 439a88cfce91374498578c44013041416c0c5b09b1eKenny Root 440a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (cms_certs) 441a88cfce91374498578c44013041416c0c5b09b1eKenny Root sk_X509_pop_free(cms_certs, X509_free); 442a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (crls) 443a88cfce91374498578c44013041416c0c5b09b1eKenny Root sk_X509_CRL_pop_free(crls, X509_CRL_free); 444a88cfce91374498578c44013041416c0c5b09b1eKenny Root 445a88cfce91374498578c44013041416c0c5b09b1eKenny Root return ret; 446a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 447a88cfce91374498578c44013041416c0c5b09b1eKenny Root 448a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, 449a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(X509) *certs, 450a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509_STORE *store, unsigned int flags) 451a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 452a88cfce91374498578c44013041416c0c5b09b1eKenny Root int r; 453a88cfce91374498578c44013041416c0c5b09b1eKenny Root flags &= ~(CMS_DETACHED|CMS_TEXT); 454a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = CMS_verify(rcms, certs, store, NULL, NULL, flags); 455a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (r <= 0) 456a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 457a88cfce91374498578c44013041416c0c5b09b1eKenny Root return cms_Receipt_verify(rcms, ocms); 458a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 459a88cfce91374498578c44013041416c0c5b09b1eKenny Root 460a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, 461a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *data, unsigned int flags) 462a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 463a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo *cms; 464a88cfce91374498578c44013041416c0c5b09b1eKenny Root int i; 465a88cfce91374498578c44013041416c0c5b09b1eKenny Root 466a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms = CMS_ContentInfo_new(); 467a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms || !CMS_SignedData_init(cms)) 468a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto merr; 469a88cfce91374498578c44013041416c0c5b09b1eKenny Root 470a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) 471a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 472a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR); 473a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 474a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 475a88cfce91374498578c44013041416c0c5b09b1eKenny Root 476a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_X509_num(certs); i++) 477a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 478a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509 *x = sk_X509_value(certs, i); 479a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!CMS_add1_cert(cms, x)) 480a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto merr; 481a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 482a88cfce91374498578c44013041416c0c5b09b1eKenny Root 483a88cfce91374498578c44013041416c0c5b09b1eKenny Root if(!(flags & CMS_DETACHED)) 484a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_set_detached(cms, 0); 485a88cfce91374498578c44013041416c0c5b09b1eKenny Root 486a88cfce91374498578c44013041416c0c5b09b1eKenny Root if ((flags & (CMS_STREAM|CMS_PARTIAL)) 487a88cfce91374498578c44013041416c0c5b09b1eKenny Root || CMS_final(cms, data, NULL, flags)) 488a88cfce91374498578c44013041416c0c5b09b1eKenny Root return cms; 489a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 490a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 491a88cfce91374498578c44013041416c0c5b09b1eKenny Root 492a88cfce91374498578c44013041416c0c5b09b1eKenny Root merr: 493a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE); 494a88cfce91374498578c44013041416c0c5b09b1eKenny Root 495a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 496a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (cms) 497a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo_free(cms); 498a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 499a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 500a88cfce91374498578c44013041416c0c5b09b1eKenny Root 501a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, 502a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509 *signcert, EVP_PKEY *pkey, 503a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(X509) *certs, 504a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int flags) 505a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 506a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_SignerInfo *rct_si; 507a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo *cms = NULL; 508a88cfce91374498578c44013041416c0c5b09b1eKenny Root ASN1_OCTET_STRING **pos, *os; 509a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *rct_cont = NULL; 510a88cfce91374498578c44013041416c0c5b09b1eKenny Root int r = 0; 511a88cfce91374498578c44013041416c0c5b09b1eKenny Root 512a88cfce91374498578c44013041416c0c5b09b1eKenny Root flags &= ~(CMS_STREAM|CMS_TEXT); 513a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Not really detached but avoids content being allocated */ 514a88cfce91374498578c44013041416c0c5b09b1eKenny Root flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED; 515a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!pkey || !signcert) 516a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 517a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT); 518a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 519a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 520a88cfce91374498578c44013041416c0c5b09b1eKenny Root 521a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Initialize signed data */ 522a88cfce91374498578c44013041416c0c5b09b1eKenny Root 523a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms = CMS_sign(NULL, NULL, certs, NULL, flags); 524a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms) 525a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 526a88cfce91374498578c44013041416c0c5b09b1eKenny Root 527a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Set inner content type to signed receipt */ 528a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) 529a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 530a88cfce91374498578c44013041416c0c5b09b1eKenny Root 531a88cfce91374498578c44013041416c0c5b09b1eKenny Root rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); 532a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!rct_si) 533a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 534a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR); 535a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 536a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 537a88cfce91374498578c44013041416c0c5b09b1eKenny Root 538a88cfce91374498578c44013041416c0c5b09b1eKenny Root os = cms_encode_Receipt(si); 539a88cfce91374498578c44013041416c0c5b09b1eKenny Root 540a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!os) 541a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 542a88cfce91374498578c44013041416c0c5b09b1eKenny Root 543a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Set content to digest */ 544a88cfce91374498578c44013041416c0c5b09b1eKenny Root rct_cont = BIO_new_mem_buf(os->data, os->length); 545a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!rct_cont) 546a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 547a88cfce91374498578c44013041416c0c5b09b1eKenny Root 548a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Add msgSigDigest attribute */ 549a88cfce91374498578c44013041416c0c5b09b1eKenny Root 550a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms_msgSigDigest_add1(rct_si, si)) 551a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 552a88cfce91374498578c44013041416c0c5b09b1eKenny Root 553a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Finalize structure */ 554a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!CMS_final(cms, rct_cont, NULL, flags)) 555a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 556a88cfce91374498578c44013041416c0c5b09b1eKenny Root 557a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* Set embedded content */ 558a88cfce91374498578c44013041416c0c5b09b1eKenny Root pos = CMS_get0_content(cms); 559a88cfce91374498578c44013041416c0c5b09b1eKenny Root *pos = os; 560a88cfce91374498578c44013041416c0c5b09b1eKenny Root 561a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = 1; 562a88cfce91374498578c44013041416c0c5b09b1eKenny Root 563a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 564a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (rct_cont) 565a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO_free(rct_cont); 566a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (r) 567a88cfce91374498578c44013041416c0c5b09b1eKenny Root return cms; 568a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo_free(cms); 569a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 570a88cfce91374498578c44013041416c0c5b09b1eKenny Root 571a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 572a88cfce91374498578c44013041416c0c5b09b1eKenny Root 573a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, 574a88cfce91374498578c44013041416c0c5b09b1eKenny Root const EVP_CIPHER *cipher, unsigned int flags) 575a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 576a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo *cms; 577a88cfce91374498578c44013041416c0c5b09b1eKenny Root int i; 578a88cfce91374498578c44013041416c0c5b09b1eKenny Root X509 *recip; 579a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms = CMS_EnvelopedData_create(cipher); 580a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms) 581a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto merr; 582a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_X509_num(certs); i++) 583a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 584a88cfce91374498578c44013041416c0c5b09b1eKenny Root recip = sk_X509_value(certs, i); 585a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!CMS_add1_recipient_cert(cms, recip, flags)) 586a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 587a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR); 588a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 589a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 590a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 591a88cfce91374498578c44013041416c0c5b09b1eKenny Root 592a88cfce91374498578c44013041416c0c5b09b1eKenny Root if(!(flags & CMS_DETACHED)) 593a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_set_detached(cms, 0); 594a88cfce91374498578c44013041416c0c5b09b1eKenny Root 595a88cfce91374498578c44013041416c0c5b09b1eKenny Root if ((flags & (CMS_STREAM|CMS_PARTIAL)) 596a88cfce91374498578c44013041416c0c5b09b1eKenny Root || CMS_final(cms, data, NULL, flags)) 597a88cfce91374498578c44013041416c0c5b09b1eKenny Root return cms; 598a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 599a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 600a88cfce91374498578c44013041416c0c5b09b1eKenny Root 601a88cfce91374498578c44013041416c0c5b09b1eKenny Root merr: 602a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE); 603a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 604a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (cms) 605a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo_free(cms); 606a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 607a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 608a88cfce91374498578c44013041416c0c5b09b1eKenny Root 609a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) 610a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 611a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(CMS_RecipientInfo) *ris; 612a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_RecipientInfo *ri; 613a88cfce91374498578c44013041416c0c5b09b1eKenny Root int i, r; 61477c6be7176c48d2ce4d5979a84876d34204eedafKenny Root int debug = 0, ri_match = 0; 615a88cfce91374498578c44013041416c0c5b09b1eKenny Root ris = CMS_get0_RecipientInfos(cms); 616a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (ris) 617a88cfce91374498578c44013041416c0c5b09b1eKenny Root debug = cms->d.envelopedData->encryptedContentInfo->debug; 618a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) 619a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 620a88cfce91374498578c44013041416c0c5b09b1eKenny Root ri = sk_CMS_RecipientInfo_value(ris, i); 621a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS) 622a88cfce91374498578c44013041416c0c5b09b1eKenny Root continue; 62377c6be7176c48d2ce4d5979a84876d34204eedafKenny Root ri_match = 1; 624a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* If we have a cert try matching RecipientInfo 625a88cfce91374498578c44013041416c0c5b09b1eKenny Root * otherwise try them all. 626a88cfce91374498578c44013041416c0c5b09b1eKenny Root */ 627a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0)) 628a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 629a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_RecipientInfo_set0_pkey(ri, pk); 630a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = CMS_RecipientInfo_decrypt(cms, ri); 631a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_RecipientInfo_set0_pkey(ri, NULL); 632a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (cert) 633a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 634a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* If not debugging clear any error and 635a88cfce91374498578c44013041416c0c5b09b1eKenny Root * return success to avoid leaking of 636a88cfce91374498578c44013041416c0c5b09b1eKenny Root * information useful to MMA 637a88cfce91374498578c44013041416c0c5b09b1eKenny Root */ 638a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!debug) 639a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 640a88cfce91374498578c44013041416c0c5b09b1eKenny Root ERR_clear_error(); 641a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 642a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 643a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (r > 0) 644a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 645a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, 646a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_DECRYPT_ERROR); 647a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 648a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 649a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* If no cert and not debugging don't leave loop 650a88cfce91374498578c44013041416c0c5b09b1eKenny Root * after first successful decrypt. Always attempt 651a88cfce91374498578c44013041416c0c5b09b1eKenny Root * to decrypt all recipients to avoid leaking timing 652a88cfce91374498578c44013041416c0c5b09b1eKenny Root * of a successful decrypt. 653a88cfce91374498578c44013041416c0c5b09b1eKenny Root */ 654a88cfce91374498578c44013041416c0c5b09b1eKenny Root else if (r > 0 && debug) 655a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 656a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 657a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 658a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* If no cert and not debugging always return success */ 65977c6be7176c48d2ce4d5979a84876d34204eedafKenny Root if (ri_match && !cert && !debug) 660a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 661a88cfce91374498578c44013041416c0c5b09b1eKenny Root ERR_clear_error(); 662a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 663a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 664a88cfce91374498578c44013041416c0c5b09b1eKenny Root 665a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); 666a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 667a88cfce91374498578c44013041416c0c5b09b1eKenny Root 668a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 669a88cfce91374498578c44013041416c0c5b09b1eKenny Root 670a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_decrypt_set1_key(CMS_ContentInfo *cms, 671a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned char *key, size_t keylen, 672a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned char *id, size_t idlen) 673a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 674a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(CMS_RecipientInfo) *ris; 675a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_RecipientInfo *ri; 676a88cfce91374498578c44013041416c0c5b09b1eKenny Root int i, r; 677a88cfce91374498578c44013041416c0c5b09b1eKenny Root ris = CMS_get0_RecipientInfos(cms); 678a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) 679a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 680a88cfce91374498578c44013041416c0c5b09b1eKenny Root ri = sk_CMS_RecipientInfo_value(ris, i); 681a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) 682a88cfce91374498578c44013041416c0c5b09b1eKenny Root continue; 683a88cfce91374498578c44013041416c0c5b09b1eKenny Root 684a88cfce91374498578c44013041416c0c5b09b1eKenny Root /* If we have an id try matching RecipientInfo 685a88cfce91374498578c44013041416c0c5b09b1eKenny Root * otherwise try them all. 686a88cfce91374498578c44013041416c0c5b09b1eKenny Root */ 687a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) 688a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 689a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_RecipientInfo_set0_key(ri, key, keylen); 690a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = CMS_RecipientInfo_decrypt(cms, ri); 691a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_RecipientInfo_set0_key(ri, NULL, 0); 692a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (r > 0) 693a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 694a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (id) 695a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 696a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, 697a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_DECRYPT_ERROR); 698a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 699a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 700a88cfce91374498578c44013041416c0c5b09b1eKenny Root ERR_clear_error(); 701a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 702a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 703a88cfce91374498578c44013041416c0c5b09b1eKenny Root 704a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT); 705a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 706a88cfce91374498578c44013041416c0c5b09b1eKenny Root 707a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 708a88cfce91374498578c44013041416c0c5b09b1eKenny Root 709a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_decrypt_set1_password(CMS_ContentInfo *cms, 710a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned char *pass, ossl_ssize_t passlen) 711a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 712a88cfce91374498578c44013041416c0c5b09b1eKenny Root STACK_OF(CMS_RecipientInfo) *ris; 713a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_RecipientInfo *ri; 714a88cfce91374498578c44013041416c0c5b09b1eKenny Root int i, r; 715a88cfce91374498578c44013041416c0c5b09b1eKenny Root ris = CMS_get0_RecipientInfos(cms); 716a88cfce91374498578c44013041416c0c5b09b1eKenny Root for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) 717a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 718a88cfce91374498578c44013041416c0c5b09b1eKenny Root ri = sk_CMS_RecipientInfo_value(ris, i); 719a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) 720a88cfce91374498578c44013041416c0c5b09b1eKenny Root continue; 721a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_RecipientInfo_set0_password(ri, pass, passlen); 722a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = CMS_RecipientInfo_decrypt(cms, ri); 723a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_RecipientInfo_set0_password(ri, NULL, 0); 724a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (r > 0) 725a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 726a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 727a88cfce91374498578c44013041416c0c5b09b1eKenny Root 728a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT); 729a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 730a88cfce91374498578c44013041416c0c5b09b1eKenny Root 731a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 732a88cfce91374498578c44013041416c0c5b09b1eKenny Root 733a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, 734a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *dcont, BIO *out, 735a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int flags) 736a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 737a88cfce91374498578c44013041416c0c5b09b1eKenny Root int r; 738a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *cont; 739a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) 740a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 741a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); 742a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 743a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 744a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!dcont && !check_content(cms)) 745a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 746a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (flags & CMS_DEBUG_DECRYPT) 747a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms->d.envelopedData->encryptedContentInfo->debug = 1; 748a88cfce91374498578c44013041416c0c5b09b1eKenny Root else 749a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms->d.envelopedData->encryptedContentInfo->debug = 0; 750a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!pk && !cert && !dcont && !out) 751a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 1; 752a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) 753a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 754a88cfce91374498578c44013041416c0c5b09b1eKenny Root cont = CMS_dataInit(cms, dcont); 755a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cont) 756a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 757a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = cms_copy_content(out, cont, flags); 758a88cfce91374498578c44013041416c0c5b09b1eKenny Root do_free_upto(cont, dcont); 759a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 760a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 761a88cfce91374498578c44013041416c0c5b09b1eKenny Root 762a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) 763a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 764a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *cmsbio; 765a88cfce91374498578c44013041416c0c5b09b1eKenny Root int ret = 0; 766a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!(cmsbio = CMS_dataInit(cms, dcont))) 767a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 768a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_FINAL,ERR_R_MALLOC_FAILURE); 769a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 770a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 771a88cfce91374498578c44013041416c0c5b09b1eKenny Root 772a88cfce91374498578c44013041416c0c5b09b1eKenny Root SMIME_crlf_copy(data, cmsbio, flags); 773a88cfce91374498578c44013041416c0c5b09b1eKenny Root 774a88cfce91374498578c44013041416c0c5b09b1eKenny Root (void)BIO_flush(cmsbio); 775a88cfce91374498578c44013041416c0c5b09b1eKenny Root 776a88cfce91374498578c44013041416c0c5b09b1eKenny Root 777a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!CMS_dataFinal(cms, cmsbio)) 778a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 779a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_FINAL,CMS_R_CMS_DATAFINAL_ERROR); 780a88cfce91374498578c44013041416c0c5b09b1eKenny Root goto err; 781a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 782a88cfce91374498578c44013041416c0c5b09b1eKenny Root 783a88cfce91374498578c44013041416c0c5b09b1eKenny Root ret = 1; 784a88cfce91374498578c44013041416c0c5b09b1eKenny Root 785a88cfce91374498578c44013041416c0c5b09b1eKenny Root err: 786a88cfce91374498578c44013041416c0c5b09b1eKenny Root do_free_upto(cmsbio, dcont); 787a88cfce91374498578c44013041416c0c5b09b1eKenny Root 788a88cfce91374498578c44013041416c0c5b09b1eKenny Root return ret; 789a88cfce91374498578c44013041416c0c5b09b1eKenny Root 790a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 791a88cfce91374498578c44013041416c0c5b09b1eKenny Root 792a88cfce91374498578c44013041416c0c5b09b1eKenny Root#ifdef ZLIB 793a88cfce91374498578c44013041416c0c5b09b1eKenny Root 794a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, 795a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int flags) 796a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 797a88cfce91374498578c44013041416c0c5b09b1eKenny Root BIO *cont; 798a88cfce91374498578c44013041416c0c5b09b1eKenny Root int r; 799a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) 800a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 801a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_UNCOMPRESS, 802a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_R_TYPE_NOT_COMPRESSED_DATA); 803a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 804a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 805a88cfce91374498578c44013041416c0c5b09b1eKenny Root 806a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!dcont && !check_content(cms)) 807a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 808a88cfce91374498578c44013041416c0c5b09b1eKenny Root 809a88cfce91374498578c44013041416c0c5b09b1eKenny Root cont = CMS_dataInit(cms, dcont); 810a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cont) 811a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 812a88cfce91374498578c44013041416c0c5b09b1eKenny Root r = cms_copy_content(out, cont, flags); 813a88cfce91374498578c44013041416c0c5b09b1eKenny Root do_free_upto(cont, dcont); 814a88cfce91374498578c44013041416c0c5b09b1eKenny Root return r; 815a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 816a88cfce91374498578c44013041416c0c5b09b1eKenny Root 817a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) 818a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 819a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo *cms; 820a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (comp_nid <= 0) 821a88cfce91374498578c44013041416c0c5b09b1eKenny Root comp_nid = NID_zlib_compression; 822a88cfce91374498578c44013041416c0c5b09b1eKenny Root cms = cms_CompressedData_create(comp_nid); 823a88cfce91374498578c44013041416c0c5b09b1eKenny Root if (!cms) 824a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 825a88cfce91374498578c44013041416c0c5b09b1eKenny Root 826a88cfce91374498578c44013041416c0c5b09b1eKenny Root if(!(flags & CMS_DETACHED)) 827a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_set_detached(cms, 0); 828a88cfce91374498578c44013041416c0c5b09b1eKenny Root 829a88cfce91374498578c44013041416c0c5b09b1eKenny Root if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 830a88cfce91374498578c44013041416c0c5b09b1eKenny Root return cms; 831a88cfce91374498578c44013041416c0c5b09b1eKenny Root 832a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMS_ContentInfo_free(cms); 833a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 834a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 835a88cfce91374498578c44013041416c0c5b09b1eKenny Root 836a88cfce91374498578c44013041416c0c5b09b1eKenny Root#else 837a88cfce91374498578c44013041416c0c5b09b1eKenny Root 838a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, 839a88cfce91374498578c44013041416c0c5b09b1eKenny Root unsigned int flags) 840a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 841a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 842a88cfce91374498578c44013041416c0c5b09b1eKenny Root return 0; 843a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 844a88cfce91374498578c44013041416c0c5b09b1eKenny Root 845a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) 846a88cfce91374498578c44013041416c0c5b09b1eKenny Root { 847a88cfce91374498578c44013041416c0c5b09b1eKenny Root CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 848a88cfce91374498578c44013041416c0c5b09b1eKenny Root return NULL; 849a88cfce91374498578c44013041416c0c5b09b1eKenny Root } 850a88cfce91374498578c44013041416c0c5b09b1eKenny Root 851a88cfce91374498578c44013041416c0c5b09b1eKenny Root#endif 852