1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* crypto/pkcs7/pk7_doit.c */ 2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * All rights reserved. 4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This package is an SSL implementation written 6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * by Eric Young (eay@cryptsoft.com). 7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The implementation was written so as to conform with Netscapes SSL. 8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This library is free for commercial and non-commercial use as long as 10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the following conditions are aheared to. The following conditions 11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * apply to all code found in this distribution, be it the RC4, RSA, 12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * included with this distribution is covered by the same copyright terms 14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright remains Eric Young's, and as such any Copyright notices in 17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the code are not to be removed. 18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * If this package is used in a product, Eric Young should be given attribution 19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * as the author of the parts of the library used. 20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This can be in the form of a textual message at program startup or 21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * in documentation (online or textual) provided with the package. 22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without 24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions 25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met: 26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the copyright 27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer. 28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer in the 30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * documentation and/or other materials provided with the distribution. 31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this software 32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * must display the following acknowledgement: 33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes cryptographic software written by 34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Eric Young (eay@cryptsoft.com)" 35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The word 'cryptographic' can be left out if the rouines from the library 36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * being used are not cryptographic related :-). 37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. If you include any Windows specific code (or a derivative thereof) from 38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the apps directory (application code) you must include an acknowledgement: 39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SUCH DAMAGE. 52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The licence and distribution terms for any publically available version or 54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * derivative of this code cannot be changed. i.e. this code cannot simply be 55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * copied and put under another distribution licence 56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * [including the GNU Public Licence.] 57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <stdio.h> 60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h" 61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/rand.h> 62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/objects.h> 63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/x509.h> 64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/x509v3.h> 65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/err.h> 66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 67c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, 68c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org void *value); 69c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); 70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int PKCS7_type_is_other(PKCS7* p7) 72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 73c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int isOther=1; 74c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 75c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int nid=OBJ_obj2nid(p7->type); 76c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 77c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch( nid ) 78c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 79c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_data: 80c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_signed: 81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_enveloped: 82c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_signedAndEnveloped: 83c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_digest: 84c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_encrypted: 85c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org isOther=0; 86c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 87c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 88c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org isOther=1; 89c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 90c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 91c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return isOther; 92c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 93c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 94c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 95c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) 96c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 97c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( PKCS7_type_is_data(p7)) 98c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return p7->d.data; 99c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( PKCS7_type_is_other(p7) && p7->d.other 100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org && (p7->d.other->type == V_ASN1_OCTET_STRING)) 101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return p7->d.other->value.octet_string; 102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 103c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 104c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) 106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO *btmp; 108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const EVP_MD *md; 109c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((btmp=BIO_new(BIO_f_md())) == NULL) 110c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 111c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB); 112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 113c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 114c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 115c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org md=EVP_get_digestbyobj(alg->algorithm); 116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (md == NULL) 117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,PKCS7_R_UNKNOWN_DIGEST_TYPE); 119c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 120c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_md(btmp,md); 123c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (*pbio == NULL) 124c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pbio=btmp; 125c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (!BIO_push(*pbio,btmp)) 126c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 127c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB); 128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org btmp=NULL; 131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 133c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org err: 135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (btmp) 136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_free(btmp); 137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 141480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, 142480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned char *key, int keylen) 143480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 144480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_CTX *pctx = NULL; 145480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY *pkey = NULL; 146480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned char *ek = NULL; 147480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int ret = 0; 148480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org size_t eklen; 149480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 150480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org pkey = X509_get_pubkey(ri->cert); 151480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 152480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!pkey) 153480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 154480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 155480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org pctx = EVP_PKEY_CTX_new(pkey, NULL); 156480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!pctx) 157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_encrypt_init(pctx) <= 0) 160480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 161480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 162480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, 163480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) 164480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 165480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR); 166480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 167480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 168480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 169480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) 170480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 171480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 172480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ek = OPENSSL_malloc(eklen); 173480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 174480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (ek == NULL) 175480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 176480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE); 177480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 178480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 179480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 180480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) 181480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 182480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 183480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ASN1_STRING_set0(ri->enc_key, ek, eklen); 184480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ek = NULL; 185480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 186480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret = 1; 187480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 188480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org err: 189480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (pkey) 190480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_free(pkey); 191480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (pctx) 192480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_CTX_free(pctx); 193480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (ek) 194480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_free(ek); 195480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return ret; 196480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 197480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 198480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 199480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 200480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, 201480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) 202480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 203480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_CTX *pctx = NULL; 204480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned char *ek = NULL; 205480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org size_t eklen; 206480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 2072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int ret = -1; 208480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 209480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org pctx = EVP_PKEY_CTX_new(pkey, NULL); 210480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!pctx) 2112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 212480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 213480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_decrypt_init(pctx) <= 0) 214480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 215480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 216480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, 217480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) 218480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 219480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR); 220480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 221480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 222480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 223480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_decrypt(pctx, NULL, &eklen, 224480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ri->enc_key->data, ri->enc_key->length) <= 0) 225480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 226480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 227480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ek = OPENSSL_malloc(eklen); 228480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 229480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (ek == NULL) 230480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 231480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE); 232480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 233480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 234480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 235480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_decrypt(pctx, ek, &eklen, 236480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ri->enc_key->data, ri->enc_key->length) <= 0) 237480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 2382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = 0; 239480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); 240480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 241480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 242480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 243480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret = 1; 244480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 2452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (*pek) 2462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 2472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_cleanse(*pek, *peklen); 2482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_free(*pek); 2492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 2502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 251480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *pek = ek; 252480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *peklen = eklen; 253480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 254480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org err: 255480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (pctx) 256480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_CTX_free(pctx); 257480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!ret && ek) 258480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_free(ek); 259480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 260480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return ret; 261480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 262480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 263c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgBIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) 264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO *out=NULL,*btmp=NULL; 267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ALGOR *xa = NULL; 268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const EVP_CIPHER *evp_cipher=NULL; 269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509_ALGOR) *md_sk=NULL; 270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; 271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ALGOR *xalg=NULL; 272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_RECIP_INFO *ri=NULL; 273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_OCTET_STRING *os=NULL; 274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=OBJ_obj2nid(p7->type); 276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p7->state=PKCS7_S_HEADER; 277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 278c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (i) 279c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_signed: 281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org md_sk=p7->d.sign->md_algs; 282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org os = PKCS7_get_octet_string(p7->d.sign->contents); 283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 284c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_signedAndEnveloped: 285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org rsk=p7->d.signed_and_enveloped->recipientinfo; 286c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org md_sk=p7->d.signed_and_enveloped->md_algs; 287c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org xalg=p7->d.signed_and_enveloped->enc_data->algorithm; 288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher; 289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (evp_cipher == NULL) 290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAINIT, 292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_R_CIPHER_NOT_INITIALIZED); 293c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 294c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_enveloped: 297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org rsk=p7->d.enveloped->recipientinfo; 298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org xalg=p7->d.enveloped->enc_data->algorithm; 299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org evp_cipher=p7->d.enveloped->enc_data->cipher; 300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (evp_cipher == NULL) 301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAINIT, 303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_R_CIPHER_NOT_INITIALIZED); 304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_digest: 308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org xa = p7->d.digest->md; 309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org os = PKCS7_get_octet_string(p7->d.digest->contents); 310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 311480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case NID_pkcs7_data: 312480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 313c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 316c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 317c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 318c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) 319c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) 320c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 321c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 322c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (xa && !PKCS7_bio_add_digest(&out, xa)) 323c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 324c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 325c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (evp_cipher != NULL) 326c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 327c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char key[EVP_MAX_KEY_LENGTH]; 328c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char iv[EVP_MAX_IV_LENGTH]; 329c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int keylen,ivlen; 330c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_CIPHER_CTX *ctx; 331c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 332c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((btmp=BIO_new(BIO_f_cipher())) == NULL) 333c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 334c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); 335c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_get_cipher_ctx(btmp, &ctx); 338c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org keylen=EVP_CIPHER_key_length(evp_cipher); 339c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ivlen=EVP_CIPHER_iv_length(evp_cipher); 340c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); 341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ivlen > 0) 342c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (RAND_pseudo_bytes(iv,ivlen) <= 0) 343c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 344c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0) 345c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 346c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) 347c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 348c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) 349c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 350c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 351c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ivlen > 0) { 352c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (xalg->parameter == NULL) { 353c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org xalg->parameter = ASN1_TYPE_new(); 354c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (xalg->parameter == NULL) 355c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 356c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) 358480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 359c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 360c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 361c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Lets do the pub key stuff :-) */ 362c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 363c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 365480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) 366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 367c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 368c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_cleanse(key, keylen); 369c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 370c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (out == NULL) 371c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org out=btmp; 372c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 373c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_push(out,btmp); 374c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org btmp=NULL; 375c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 376c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 377c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (bio == NULL) 378c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 379c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (PKCS7_is_detached(p7)) 380c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio=BIO_new(BIO_s_null()); 381c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (os && os->length > 0) 382c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio = BIO_new_mem_buf(os->data, os->length); 383c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(bio == NULL) 384c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 385c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio=BIO_new(BIO_s_mem()); 386c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (bio == NULL) 387c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 388c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_mem_eof_return(bio,0); 389c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 390c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 391480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (out) 392480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_push(out,bio); 393480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else 394480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org out = bio; 395c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio=NULL; 396c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (0) 397c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 398c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgerr: 399c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (out != NULL) 400c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_free_all(out); 401c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (btmp != NULL) 402c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_free_all(btmp); 403c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org out=NULL; 404c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 405c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(out); 406c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 407c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 408c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) 409c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 410c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret; 411c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, 412c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org pcert->cert_info->issuer); 413c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret) 414c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ret; 415c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, 416c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ri->issuer_and_serial->serial); 417c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 418c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 419c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* int */ 420c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgBIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) 421c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 422c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i,j; 423c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; 424c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ALGOR *xa; 425c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_OCTET_STRING *data_body=NULL; 426c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const EVP_MD *evp_md; 427c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const EVP_CIPHER *evp_cipher=NULL; 428c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_CIPHER_CTX *evp_ctx=NULL; 429c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ALGOR *enc_alg=NULL; 430c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509_ALGOR) *md_sk=NULL; 431c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; 432c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_RECIP_INFO *ri=NULL; 4332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org unsigned char *ek = NULL, *tkey = NULL; 4342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int eklen = 0, tkeylen = 0; 435c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 436c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=OBJ_obj2nid(p7->type); 437c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p7->state=PKCS7_S_HEADER; 438c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 439c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (i) 440c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 441c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_signed: 442c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data_body=PKCS7_get_octet_string(p7->d.sign->contents); 443c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org md_sk=p7->d.sign->md_algs; 444c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 445c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_signedAndEnveloped: 446c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org rsk=p7->d.signed_and_enveloped->recipientinfo; 447c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org md_sk=p7->d.signed_and_enveloped->md_algs; 448c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data_body=p7->d.signed_and_enveloped->enc_data->enc_data; 449c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm; 450c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); 451c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (evp_cipher == NULL) 452c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 453c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 454c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 455c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 456c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 457c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_enveloped: 458c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org rsk=p7->d.enveloped->recipientinfo; 459c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org enc_alg=p7->d.enveloped->enc_data->algorithm; 460c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data_body=p7->d.enveloped->enc_data->enc_data; 461c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); 462c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (evp_cipher == NULL) 463c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 464c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 465c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 466c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 467c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 468c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 469c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 470c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 471c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 472c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 473c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* We will be checking the signature */ 474c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (md_sk != NULL) 475c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 476c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) 477c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 478c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org xa=sk_X509_ALGOR_value(md_sk,i); 479c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((btmp=BIO_new(BIO_f_md())) == NULL) 480c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 481c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); 482c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 483c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 484c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 485c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org j=OBJ_obj2nid(xa->algorithm); 486c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org evp_md=EVP_get_digestbynid(j); 487c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (evp_md == NULL) 488c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 489c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE); 490c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 491c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 492c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 493c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_md(btmp,evp_md); 494c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (out == NULL) 495c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org out=btmp; 496c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 497c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_push(out,btmp); 498c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org btmp=NULL; 499c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 500c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 501c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 502c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (evp_cipher != NULL) 503c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 504c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0 505c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char key[EVP_MAX_KEY_LENGTH]; 506c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char iv[EVP_MAX_IV_LENGTH]; 507c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char *p; 508c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int keylen,ivlen; 509c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int max; 510c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_OBJECT ret; 511c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 512c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 513c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((etmp=BIO_new(BIO_f_cipher())) == NULL) 514c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 515c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); 516c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 517c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 518c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 519c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* It was encrypted, we need to decrypt the secret key 520c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * with the private key */ 521c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 522c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Find the recipientInfo which matches the passed certificate 523c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (if any) 524c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 525c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 526480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (pcert) 527480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 528480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 529480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 530c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 531c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!pkcs7_cmp_ri(ri, pcert)) 532c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 533c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ri=NULL; 534480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 535480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (ri == NULL) 536480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 537c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATADECODE, 538c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); 539c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 540480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 541c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 542c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 543c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If we haven't got a certificate try each ri in turn */ 544c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (pcert == NULL) 545c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 5462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Always attempt to decrypt all rinfo even 5472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * after sucess as a defence against MMA timing 5482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * attacks. 5492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 550c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 551c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 552c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 5532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 554480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (pkcs7_decrypt_rinfo(&ek, &eklen, 5552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ri, pkey) < 0) 5562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 557c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ERR_clear_error(); 558c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 559c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 560c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 561c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 5622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Only exit on fatal errors, not decrypt failure */ 5632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) 564c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 5652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ERR_clear_error(); 566c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 567c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 568c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org evp_ctx=NULL; 569c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_get_cipher_ctx(etmp,&evp_ctx); 570c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) 571c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 572c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) 573c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 5742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Generate random key as MMA defence */ 5752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); 5762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org tkey = OPENSSL_malloc(tkeylen); 5772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!tkey) 5782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 5792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) 5802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 5812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ek == NULL) 5822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 5832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ek = tkey; 5842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org eklen = tkeylen; 5852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org tkey = NULL; 5862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 587c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 588480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { 589c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Some S/MIME clients don't use the same key 590c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * and effective key length. The key length is 591c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * determined by the size of the decrypted RSA key. 592c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 593480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) 594c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 5952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Use random key as MMA defence */ 5962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_cleanse(ek, eklen); 5972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_free(ek); 5982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ek = tkey; 5992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org eklen = tkeylen; 6002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org tkey = NULL; 601c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 602c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 6032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Clear errors so we don't leak information useful in MMA */ 6042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ERR_clear_error(); 605480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0) 606c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 607c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 608480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (ek) 609480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 610480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_cleanse(ek,eklen); 611480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_free(ek); 6122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ek = NULL; 6132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 6142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (tkey) 6152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 6162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_cleanse(tkey,tkeylen); 6172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_free(tkey); 6182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org tkey = NULL; 619480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 620c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 621c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (out == NULL) 622c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org out=etmp; 623c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 624c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_push(out,etmp); 625c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org etmp=NULL; 626c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 627c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 628c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 1 629c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (PKCS7_is_detached(p7) || (in_bio != NULL)) 630c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 631c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio=in_bio; 632c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 633c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 634c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 635c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0 636c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio=BIO_new(BIO_s_mem()); 637c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* We need to set this so that when we have read all 638c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the data, the encrypt BIO, if present, will read 639c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EOF and encode the last few bytes */ 640c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_mem_eof_return(bio,0); 641c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 642c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data_body->length > 0) 643c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_write(bio,(char *)data_body->data,data_body->length); 644c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 645c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data_body->length > 0) 646c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio = BIO_new_mem_buf(data_body->data,data_body->length); 647c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else { 648c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio=BIO_new(BIO_s_mem()); 649c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_mem_eof_return(bio,0); 650c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 651c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (bio == NULL) 652c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 653c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 654c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 655c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_push(out,bio); 656c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio=NULL; 657c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 658c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (0) 659c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 660c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgerr: 6612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ek) 6622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 6632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_cleanse(ek,eklen); 6642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_free(ek); 6652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 6662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (tkey) 6672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 6682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_cleanse(tkey,tkeylen); 6692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_free(tkey); 6702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 671c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (out != NULL) BIO_free_all(out); 672c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (btmp != NULL) BIO_free_all(btmp); 673c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (etmp != NULL) BIO_free_all(etmp); 674c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (bio != NULL) BIO_free_all(bio); 675c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org out=NULL; 676c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 677c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(out); 678c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 679c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 680c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) 681c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 682c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (;;) 683c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 684c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio=BIO_find_type(bio,BIO_TYPE_MD); 685c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (bio == NULL) 686c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 687c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 688c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 689c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 690c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_get_md_ctx(bio,pmd); 691c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (*pmd == NULL) 692c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 693c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR); 694c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 695c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 696c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EVP_MD_CTX_type(*pmd) == nid) 697c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return bio; 698c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio=BIO_next(bio); 699c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 700c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 701c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 702c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 703480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) 704480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 705480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned char md_data[EVP_MAX_MD_SIZE]; 706480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned int md_len; 707480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 708480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Add signing time if not already present */ 709480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) 710480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 711480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!PKCS7_add0_attrib_signing_time(si, NULL)) 712480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 713480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, 714480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ERR_R_MALLOC_FAILURE); 715480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 716480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 717480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 718480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 719480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Add digest */ 7202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_DigestFinal_ex(mctx, md_data,&md_len)) 7212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 7222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB); 7232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return 0; 7242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 725480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) 726480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 727480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); 728480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 729480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 730480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 731480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Now sign the attributes */ 732480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!PKCS7_SIGNER_INFO_sign(si)) 733480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 734480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 735480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 736480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 737480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 738480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 739c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 740c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 741c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret=0; 742c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i,j; 743c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO *btmp; 744c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_SIGNER_INFO *si; 745c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_MD_CTX *mdc,ctx_tmp; 746c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509_ATTRIBUTE) *sk; 747c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL; 748c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_OCTET_STRING *os=NULL; 749c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 750c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_MD_CTX_init(&ctx_tmp); 751c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=OBJ_obj2nid(p7->type); 752c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p7->state=PKCS7_S_HEADER; 753c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 754c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (i) 755c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 756480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case NID_pkcs7_data: 757480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org os = p7->d.data; 758480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 759c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_signedAndEnveloped: 760c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* XXXXXXXXXXXXXXXX */ 761c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org si_sk=p7->d.signed_and_enveloped->signer_info; 762480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org os = p7->d.signed_and_enveloped->enc_data->enc_data; 763480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!os) 764c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 765480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org os=M_ASN1_OCTET_STRING_new(); 766480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!os) 767480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 768480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 769480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 770480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 771480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org p7->d.signed_and_enveloped->enc_data->enc_data=os; 772c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 773c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 774c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_enveloped: 775c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* XXXXXXXXXXXXXXXX */ 776480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org os = p7->d.enveloped->enc_data->enc_data; 777480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!os) 778c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 779480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org os=M_ASN1_OCTET_STRING_new(); 780480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!os) 781480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 782480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 783480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 784480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 785480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org p7->d.enveloped->enc_data->enc_data=os; 786c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 787c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 788c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_signed: 789c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org si_sk=p7->d.sign->signer_info; 790c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org os=PKCS7_get_octet_string(p7->d.sign->contents); 791c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If detached data then the content is excluded */ 792c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { 793c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org M_ASN1_OCTET_STRING_free(os); 794c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p7->d.sign->contents->d.data = NULL; 795c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 796c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 797c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 798c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs7_digest: 799c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org os=PKCS7_get_octet_string(p7->d.digest->contents); 800c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If detached data then the content is excluded */ 801c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) 802c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 803c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org M_ASN1_OCTET_STRING_free(os); 804c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p7->d.digest->contents->d.data = NULL; 805c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 806c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 807c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 808480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org default: 809480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 810480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 811c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 812c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 813c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (si_sk != NULL) 814c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 815c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) 816c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 817c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); 818480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (si->pkey == NULL) 819480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org continue; 820c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 821480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org j = OBJ_obj2nid(si->digest_alg->algorithm); 822c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 823c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org btmp=bio; 824c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 825c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org btmp = PKCS7_find_digest(&mdc, btmp, j); 826c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 827c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (btmp == NULL) 828c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 829c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 830c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* We now have the EVP_MD_CTX, lets do the 831c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * signing. */ 8322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_MD_CTX_copy_ex(&ctx_tmp,mdc)) 8332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 834c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 835c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk=si->auth_attr; 836c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 837c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If there are attributes, we add the digest 838c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * attribute and only sign the attributes */ 839480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (sk_X509_ATTRIBUTE_num(sk) > 0) 840c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 841480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) 842c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 843480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 844480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else 845480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 846480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned char *abuf = NULL; 847480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned int abuflen; 848480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org abuflen = EVP_PKEY_size(si->pkey); 849480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org abuf = OPENSSL_malloc(abuflen); 850480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!abuf) 851c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 852480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 853480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, 854480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org si->pkey)) 855c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 856480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 857480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ERR_R_EVP_LIB); 858c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 859c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 860480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ASN1_STRING_set0(si->enc_digest, abuf, abuflen); 861c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 862c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 863c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 864c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (i == NID_pkcs7_digest) 865c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 866c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char md_data[EVP_MAX_MD_SIZE]; 867c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned int md_len; 868c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!PKCS7_find_digest(&mdc, bio, 869c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OBJ_obj2nid(p7->d.digest->md->algorithm))) 870c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 8712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_DigestFinal_ex(mdc,md_data,&md_len)) 8722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 873c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); 874c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 875c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 876480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF)) 877c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 878480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org char *cont; 879480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org long contlen; 880c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org btmp=BIO_find_type(bio,BIO_TYPE_MEM); 881c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (btmp == NULL) 882c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 883c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 884c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 885c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 886480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org contlen = BIO_get_mem_data(btmp, &cont); 887c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Mark the BIO read only then we can use its copy of the data 888c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * instead of making an extra copy. 889c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 890c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 891c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_mem_eof_return(btmp, 0); 892480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ASN1_STRING_set0(os, (unsigned char *)cont, contlen); 893c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 894c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=1; 895c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgerr: 896c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_MD_CTX_cleanup(&ctx_tmp); 897c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 898c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 899c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 900480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) 901480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 902480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_MD_CTX mctx; 903480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_CTX *pctx; 904480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned char *abuf = NULL; 905480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int alen; 906480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org size_t siglen; 907480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org const EVP_MD *md = NULL; 908480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 909480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org md = EVP_get_digestbyobj(si->digest_alg->algorithm); 910480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (md == NULL) 911480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 912480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 913480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_MD_CTX_init(&mctx); 914480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_DigestSignInit(&mctx, &pctx, md,NULL, si->pkey) <= 0) 915480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 916480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 917480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 918480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) 919480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 920480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); 921480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 922480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 923480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 924480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf, 925480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); 926480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if(!abuf) 927480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 928480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0) 929480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 930480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_free(abuf); 931063a4b93646788bd883fc0cb1b5eafc991ddacc4agl@chromium.org abuf = NULL; 932480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) 933480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 934480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org abuf = OPENSSL_malloc(siglen); 935480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if(!abuf) 936480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 937480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) 938480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 939480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 940480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 941480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) 942480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 943480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); 944480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 945480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 946480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 947480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_MD_CTX_cleanup(&mctx); 948480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 949480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ASN1_STRING_set0(si->enc_digest, abuf, siglen); 950480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 951480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 952480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 953480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org err: 954480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (abuf) 955480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_free(abuf); 956480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_MD_CTX_cleanup(&mctx); 957480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 958480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 959480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 960480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 961c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 962c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7 *p7, PKCS7_SIGNER_INFO *si) 963c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 964c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_ISSUER_AND_SERIAL *ias; 965c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret=0,i; 966c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509) *cert; 967c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509 *x509; 968c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 969c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (PKCS7_type_is_signed(p7)) 970c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 971c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org cert=p7->d.sign->cert; 972c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 973c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (PKCS7_type_is_signedAndEnveloped(p7)) 974c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 975c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org cert=p7->d.signed_and_enveloped->cert; 976c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 977c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 978c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 979c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE); 980c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 981c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 982c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* XXXXXXXXXXXXXXXXXXXXXXX */ 983c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ias=si->issuer_and_serial; 984c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 985c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial); 986c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 987c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* were we able to find the cert in passed to us */ 988c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (x509 == NULL) 989c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 990c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); 991c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 992c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 993c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 994c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Lets verify */ 995c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert)) 996c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 997c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); 998c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 999c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1000c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); 1001c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=X509_verify_cert(ctx); 1002c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (i <= 0) 1003c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1004c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); 1005c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_STORE_CTX_cleanup(ctx); 1006c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 1007c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1008c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_STORE_CTX_cleanup(ctx); 1009c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1010c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return PKCS7_signatureVerify(bio, p7, si, x509); 1011c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org err: 1012c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ret; 1013c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1014c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1015c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, 1016c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509 *x509) 1017c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1018c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_OCTET_STRING *os; 1019c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_MD_CTX mdc_tmp,*mdc; 1020c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret=0,i; 1021c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int md_type; 1022c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509_ATTRIBUTE) *sk; 1023c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO *btmp; 1024c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_PKEY *pkey; 1025c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1026c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_MD_CTX_init(&mdc_tmp); 1027c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1028c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!PKCS7_type_is_signed(p7) && 1029c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org !PKCS7_type_is_signedAndEnveloped(p7)) { 1030c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1031c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_R_WRONG_PKCS7_TYPE); 1032c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 1033c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1034c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1035c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org md_type=OBJ_obj2nid(si->digest_alg->algorithm); 1036c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1037c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org btmp=bio; 1038c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (;;) 1039c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1040c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((btmp == NULL) || 1041c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL)) 1042c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1043c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1044c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1045c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 1046c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1047c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_get_md_ctx(btmp,&mdc); 1048c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (mdc == NULL) 1049c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1050c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1051c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ERR_R_INTERNAL_ERROR); 1052c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 1053c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1054c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EVP_MD_CTX_type(mdc) == md_type) 1055c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 1056c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Workaround for some broken clients that put the signature 1057c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OID instead of the digest OID in digest_alg->algorithm 1058c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 1059c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) 1060c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 1061c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org btmp=BIO_next(btmp); 1062c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1063c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1064c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* mdc is the digest ctx that we want, unless there are attributes, 1065c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * in which case the digest is the signed attributes */ 10662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_MD_CTX_copy_ex(&mdc_tmp,mdc)) 10672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 1068c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1069c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk=si->auth_attr; 1070c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 1071c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1072c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 1073480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned int md_len; 1074480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int alen; 1075c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_OCTET_STRING *message_digest; 1076c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 10772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len)) 10782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 1079c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org message_digest=PKCS7_digest_from_attributes(sk); 1080c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!message_digest) 1081c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1082c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1083c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1084c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 1085c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1086c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((message_digest->length != (int)md_len) || 1087c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org (memcmp(message_digest->data,md_dat,md_len))) 1088c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1089c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0 1090c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ 1091c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint ii; 1092c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgfor (ii=0; ii<message_digest->length; ii++) 1093c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org printf("%02X",message_digest->data[ii]); printf(" sent\n"); 1094c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgfor (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); 1095c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org} 1096c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1097c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1098c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_R_DIGEST_FAILURE); 1099c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret= -1; 1100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 1101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 11032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL)) 11042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 1105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); 1108480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (alen <= 0) 1109480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 1110480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,ERR_R_ASN1_LIB); 1111480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret = -1; 1112480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 1113480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 11142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) 11152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 1116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(abuf); 1118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1119c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1120c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org os=si->enc_digest; 1121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org pkey = X509_get_pubkey(x509); 1122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!pkey) 1123c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1124c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = -1; 1125c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 1126c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1127c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); 1129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_PKEY_free(pkey); 1130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (i <= 0) 1131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1133c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_R_SIGNATURE_FAILURE); 1134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret= -1; 1135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 1136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 1138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=1; 1139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgerr: 1140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EVP_MD_CTX_cleanup(&mdc_tmp); 1141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 1142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgPKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) 1145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(PKCS7_RECIP_INFO) *rsk; 1147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7_RECIP_INFO *ri; 1148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 1149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=OBJ_obj2nid(p7->type); 1151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (i != NID_pkcs7_signedAndEnveloped) 1152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 1153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (p7->d.signed_and_enveloped == NULL) 1154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 1155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org rsk=p7->d.signed_and_enveloped->recipientinfo; 1156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (rsk == NULL) 1157c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 1158c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ri=sk_PKCS7_RECIP_INFO_value(rsk,0); 1159c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL); 1160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ri=sk_PKCS7_RECIP_INFO_value(rsk,idx); 1161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ri->issuer_and_serial); 1162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) 1165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(get_attribute(si->auth_attr,nid)); 1167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) 1170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(get_attribute(si->unauth_attr,nid)); 1172c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) 1175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 1177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ATTRIBUTE *xa; 1178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_OBJECT *o; 1179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org o=OBJ_nid2obj(nid); 1181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!o || !sk) return(NULL); 1182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org xa=sk_X509_ATTRIBUTE_value(sk,i); 1185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (OBJ_cmp(xa->object,o) == 0) 1186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) 1188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(sk_ASN1_TYPE_value(xa->value.set,0)); 1189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 1190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(NULL); 1191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(NULL); 1194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) 1197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ 1198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_TYPE *astype; 1199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL; 1200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return astype->value.octet_string; 1201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org} 1202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, 1204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509_ATTRIBUTE) *sk) 1205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 1207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (p7si->auth_attr != NULL) 1209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); 1210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk); 1211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (p7si->auth_attr == NULL) 1212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 1213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i, 1216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) 1217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org == NULL) 1218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(0); 1219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(1); 1221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) 1224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 1226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (p7si->unauth_attr != NULL) 1228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, 1229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ATTRIBUTE_free); 1230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk); 1231c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (p7si->unauth_attr == NULL) 1232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 1233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i, 1236c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) 1237c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org == NULL) 1238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(0); 1239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(1); 1241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1242c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org void *value) 1245c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(add_attribute(&(p7si->auth_attr),nid,atrtype,value)); 1247c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org void *value) 1251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value)); 1253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, 1256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org void *value) 1257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ATTRIBUTE *attr=NULL; 1259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1260c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (*sk == NULL) 1261c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1262480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *sk = sk_X509_ATTRIBUTE_new_null(); 1263480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (*sk == NULL) 1264480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 1265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgnew_attrib: 1266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) 1267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 1268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!sk_X509_ATTRIBUTE_push(*sk,attr)) 1269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ATTRIBUTE_free(attr); 1271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 1272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 1275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 1277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1278c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++) 1279c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org attr=sk_X509_ATTRIBUTE_value(*sk,i); 1281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (OBJ_obj2nid(attr->object) == nid) 1282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ATTRIBUTE_free(attr); 1284c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org attr=X509_ATTRIBUTE_create(nid,atrtype,value); 1285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (attr == NULL) 1286c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 1287c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!sk_X509_ATTRIBUTE_set(*sk,i,attr)) 1288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_ATTRIBUTE_free(attr); 1290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 1291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto end; 1293c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1294c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto new_attrib; 1296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgend: 1298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(1); 1299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1301