1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* pk7_smime.c */ 2e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project. 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the documentation and/or other materials provided with the 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * distribution. 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * software must display the following acknowledgment: 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * endorse or promote products derived from this software without 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * prior written permission. For written permission, please contact 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * licensing@OpenSSL.org. 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL" 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * nor may "OpenSSL" appear in their names without prior written 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * permission of the OpenSSL Project. 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * acknowledgment: 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE. 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ==================================================================== 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com). This product includes software written by Tim 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com). 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Simple PKCS#7 processing functions */ 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h> 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h" 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/x509.h> 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/x509v3.h> 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); 67221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *data, int flags) 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 71221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7 *p7; 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!(p7 = PKCS7_new())) 75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!PKCS7_set_type(p7, NID_pkcs7_signed)) 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!PKCS7_content_new(p7, NID_pkcs7_data)) 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) 87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR); 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!(flags & PKCS7_NOCERTS)) 93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom for(i = 0; i < sk_X509_num(certs); i++) 95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 98221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(flags & PKCS7_DETACHED) 102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7_set_detached(p7, 1); 103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 104221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (flags & (PKCS7_STREAM|PKCS7_PARTIAL)) 105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return p7; 106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (PKCS7_final(p7, data, flags)) 108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return p7; 109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom err: 111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7_free(p7); 112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return NULL; 113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint PKCS7_final(PKCS7 *p7, BIO *data, int flags) 116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom BIO *p7bio; 118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int ret = 0; 119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!(p7bio = PKCS7_dataInit(p7, NULL))) 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE); 122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom SMIME_crlf_copy(data, p7bio, flags); 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom (void)BIO_flush(p7bio); 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!PKCS7_dataFinal(p7,p7bio)) 131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN); 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ret = 1; 137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom err: 139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom BIO_free_all(p7bio); 140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ret; 142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Check to see if a cipher exists and if so add S/MIME capabilities */ 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) 148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (EVP_get_cipherbynid(nid)) 150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return PKCS7_simple_smimecap(sk, nid, arg); 151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 1; 152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) 155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (EVP_get_digestbynid(nid)) 157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return PKCS7_simple_smimecap(sk, nid, arg); 158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 1; 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 161221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromPKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, 162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom EVP_PKEY *pkey, const EVP_MD *md, 163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int flags) 164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7_SIGNER_INFO *si = NULL; 166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom STACK_OF(X509_ALGOR) *smcap = NULL; 167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!X509_check_private_key(signcert, pkey)) 168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 171221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return NULL; 172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!(si = PKCS7_add_signature(p7,signcert,pkey, md))) 175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); 178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return NULL; 179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!(flags & PKCS7_NOCERTS)) 182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!PKCS7_add_certificate(p7, signcert)) 184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!(flags & PKCS7_NOATTR)) 188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!PKCS7_add_attrib_content_type(si, NULL)) 190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Add SMIMECapabilities */ 192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!(flags & PKCS7_NOSMIMECAP)) 193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!(smcap = sk_X509_ALGOR_new_null())) 195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 196221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 197221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ERR_R_MALLOC_FAILURE); 198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) 201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) 202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) 203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) 204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) 205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) 206221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !add_cipher_smcap(smcap, NID_rc2_cbc, 128) 207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !add_cipher_smcap(smcap, NID_rc2_cbc, 64) 208221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !add_cipher_smcap(smcap, NID_des_cbc, -1) 209221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !add_cipher_smcap(smcap, NID_rc2_cbc, 40) 210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom || !PKCS7_add_attrib_smimecap (si, smcap)) 211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 213221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom smcap = NULL; 214221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 215221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (flags & PKCS7_REUSE_DIGEST) 216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 217221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!pkcs7_copy_existing_digest(p7, si)) 218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!(flags & PKCS7_PARTIAL) && 220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom !PKCS7_SIGNER_INFO_sign(si)) 221221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 222221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return si; 225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom err: 226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (smcap) 227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Search for a digest matching SignerInfo digest type and if found 232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * copy across. 233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */ 234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) 236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int i; 238221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom STACK_OF(PKCS7_SIGNER_INFO) *sinfos; 239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7_SIGNER_INFO *sitmp; 240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ASN1_OCTET_STRING *osdig = NULL; 241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sinfos = PKCS7_get_signer_info(p7); 242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) 243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); 245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (si == sitmp) 246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0) 248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom continue; 249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!OBJ_cmp(si->digest_alg->algorithm, 250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sitmp->digest_alg->algorithm)) 251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); 253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (osdig) 259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); 260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, 262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); 263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *indata, BIO *out, int flags) 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(X509) *signers; 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509 *signer; 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(PKCS7_SIGNER_INFO) *sinfos; 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7_SIGNER_INFO *si; 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_STORE_CTX cert_ctx; 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project char buf[4096]; 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, j=0, k, ret = 0; 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *p7bio; 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *tmpin, *tmpout; 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!p7) { 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_INVALID_NULL_POINTER); 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!PKCS7_type_is_signed(p7)) { 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE); 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Check for no data and no content: no data to verify signature */ 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(PKCS7_get_detached(p7) && !indata) { 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT); 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* NB: this test commented out because some versions of Netscape 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * illegally include zero length content when signing data. 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Check for data and content: two sets of data */ 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!PKCS7_get_detached(p7) && indata) { 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CONTENT_AND_DATA_PRESENT); 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sinfos = PKCS7_get_signer_info(p7); 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA); 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project signers = PKCS7_get0_signers(p7, certs, flags); 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!signers) return 0; 317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Now verify the certificates */ 319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!(flags & PKCS7_NOVERIFY)) for (k = 0; k < sk_X509_num(signers); k++) { 321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project signer = sk_X509_value (signers, k); 322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!(flags & PKCS7_NOCHAIN)) { 323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!X509_STORE_CTX_init(&cert_ctx, store, signer, 324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project p7->d.sign->cert)) 325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB); 327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_X509_free(signers); 328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 330e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu X509_STORE_CTX_set_default(&cert_ctx, "smime_sign"); 331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else if(!X509_STORE_CTX_init (&cert_ctx, store, signer, NULL)) { 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB); 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_X509_free(signers); 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!(flags & PKCS7_NOCRL)) 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i = X509_verify_cert(&cert_ctx); 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx); 340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_STORE_CTX_cleanup(&cert_ctx); 341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i <= 0) { 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CERTIFICATE_VERIFY_ERROR); 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ERR_add_error_data(2, "Verify error:", 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_verify_cert_error_string(j)); 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_X509_free(signers); 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Check for revocation status here */ 349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Performance optimization: if the content is a memory BIO then 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * store its contents in a temporary read only memory BIO. This 353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * avoids potentially large numbers of slow copies of data which will 354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * occur when reading from a read write memory BIO when signatures 355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are calculated. 356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project char *ptr; 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project long len; 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project len = BIO_get_mem_data(indata, &ptr); 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmpin = BIO_new_mem_buf(ptr, len); 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (tmpin == NULL) 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE); 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmpin = indata; 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!(p7bio=PKCS7_dataInit(p7,tmpin))) 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(flags & PKCS7_TEXT) { 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!(tmpout = BIO_new(BIO_s_mem()))) { 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE); 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 382e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIO_set_mem_eof_return(tmpout, 0); 383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else tmpout = out; 384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* We now have to 'read' from p7bio to calculate digests etc. */ 386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (;;) 387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i=BIO_read(p7bio,buf,sizeof(buf)); 389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i <= 0) break; 390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (tmpout) BIO_write(tmpout, buf, i); 391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(flags & PKCS7_TEXT) { 394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!SMIME_text(tmpout, out)) { 395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SMIME_TEXT_ERROR); 396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free(tmpout); 397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free(tmpout); 400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Now Verify All Signatures */ 403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!(flags & PKCS7_NOSIGS)) 404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sinfos); i++) 405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project si=sk_PKCS7_SIGNER_INFO_value(sinfos,i); 407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project signer = sk_X509_value (signers, i); 408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project j=PKCS7_signatureVerify(p7bio,p7,si, signer); 409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (j <= 0) { 410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SIGNATURE_FAILURE); 411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (tmpin == indata) 420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (indata) BIO_pop(p7bio); 422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free_all(p7bio); 424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_X509_free(signers); 426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectSTACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) 431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(X509) *signers; 433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(PKCS7_SIGNER_INFO) *sinfos; 434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7_SIGNER_INFO *si; 435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7_ISSUER_AND_SERIAL *ias; 436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509 *signer; 437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!p7) { 440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_INVALID_NULL_POINTER); 441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!PKCS7_type_is_signed(p7)) { 445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE); 446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Collect all the signers together */ 450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sinfos = PKCS7_get_signer_info(p7); 452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { 454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); 455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!(signers = sk_X509_new_null())) { 459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE); 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ias = si->issuer_and_serial; 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project signer = NULL; 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* If any certificates passed they take priority */ 469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (certs) signer = X509_find_by_issuer_and_serial (certs, 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ias->issuer, ias->serial); 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!signer && !(flags & PKCS7_NOINTERN) 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project && p7->d.sign->cert) signer = 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_find_by_issuer_and_serial (p7->d.sign->cert, 474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ias->issuer, ias->serial); 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!signer) { 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_X509_free(signers); 478221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!sk_X509_push(signers, signer)) { 482221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_X509_free(signers); 483221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return NULL; 484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return signers; 487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Build a complete PKCS#7 enveloped data */ 491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, 493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int flags) 494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7 *p7; 496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *p7bio = NULL; 497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509 *x509; 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!(p7 = PKCS7_new())) { 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) 505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 506221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!PKCS7_set_cipher(p7, cipher)) { 507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); 508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for(i = 0; i < sk_X509_num(certs); i++) { 512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x509 = sk_X509_value(certs, i); 513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!PKCS7_add_recipient(p7, x509)) { 514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_ENCRYPT, 515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7_R_ERROR_ADDING_RECIPIENT); 516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 520221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (flags & PKCS7_STREAM) 521221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return p7; 522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 523221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (PKCS7_final(p7, in, flags)) 524221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return p7; 525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free_all(p7bio); 529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7_free(p7); 530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) 535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *tmpmem; 537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret, i; 538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project char buf[4096]; 539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!p7) { 541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER); 542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!PKCS7_type_is_enveloped(p7)) { 546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE); 547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(cert && !X509_check_private_key(cert, pkey)) { 551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_DECRYPT, 552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) { 557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR); 558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (flags & PKCS7_TEXT) { 562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *tmpbuf, *bread; 563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ 564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!(tmpbuf = BIO_new(BIO_f_buffer()))) { 565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); 566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free_all(tmpmem); 567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!(bread = BIO_push(tmpbuf, tmpmem))) { 570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); 571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free_all(tmpbuf); 572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free_all(tmpmem); 573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = SMIME_text(bread, data); 57621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) 57721c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom { 57821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom if (!BIO_get_cipher_status(tmpmem)) 57921c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom ret = 0; 58021c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom } 581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free_all(bread); 582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for(;;) { 585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i = BIO_read(tmpmem, buf, sizeof(buf)); 58621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom if(i <= 0) 58721c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom { 58821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom ret = 1; 58921c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) 59021c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom { 59121c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom if (!BIO_get_cipher_status(tmpmem)) 59221c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom ret = 0; 59321c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom } 59421c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom 59521c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom break; 59621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom } 59721c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom if (BIO_write(data, buf, i) != i) 59821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom { 59921c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom ret = 0; 60021c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom break; 60121c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom } 602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free_all(tmpmem); 60421c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom return ret; 605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 607