1 /* p12_decr.c */ 2 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 3 * project 1999. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 #include <stdio.h> 60 #include "cryptlib.h" 61 #include <openssl/pkcs12.h> 62 63 /* Define this to dump decrypted output to files called DERnnn */ 64 /*#define DEBUG_DECRYPT*/ 65 66 67 /* Encrypt/Decrypt a buffer based on password and algor, result in a 68 * OPENSSL_malloc'ed buffer 69 */ 70 71 unsigned char * PKCS12_pbe_crypt (X509_ALGOR *algor, const char *pass, 72 int passlen, unsigned char *in, int inlen, unsigned char **data, 73 int *datalen, int en_de) 74 { 75 unsigned char *out; 76 int outlen, i; 77 EVP_CIPHER_CTX ctx; 78 79 /* Decrypt data */ 80 if (!EVP_PBE_CipherInit (algor->algorithm, pass, passlen, 81 algor->parameter, &ctx, en_de)) { 82 PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); 83 return NULL; 84 } 85 86 if(!(out = OPENSSL_malloc (inlen + EVP_CIPHER_CTX_block_size(&ctx)))) { 87 PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,ERR_R_MALLOC_FAILURE); 88 return NULL; 89 } 90 91 EVP_CipherUpdate (&ctx, out, &i, in, inlen); 92 outlen = i; 93 if(!EVP_CipherFinal (&ctx, out + i, &i)) { 94 OPENSSL_free (out); 95 PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_CIPHERFINAL_ERROR); 96 return NULL; 97 } 98 outlen += i; 99 if (datalen) *datalen = outlen; 100 if (data) *data = out; 101 return out; 102 103 } 104 105 /* Decrypt an OCTET STRING and decode ASN1 structure 106 * if seq & 1 'obj' is a stack of structures to be encoded 107 * if seq & 2 zero buffer after use 108 * as a sequence. 109 */ 110 111 char * PKCS12_decrypt_d2i (X509_ALGOR *algor, char * (*d2i)(), 112 void (*free_func)(void *), const char *pass, int passlen, 113 ASN1_OCTET_STRING *oct, int seq) 114 { 115 unsigned char *out, *p; 116 char *ret; 117 int outlen; 118 119 if (!PKCS12_pbe_crypt (algor, pass, passlen, oct->data, oct->length, 120 &out, &outlen, 0)) { 121 PKCS12err(PKCS12_F_PKCS12_DECRYPT_D2I,PKCS12_R_PKCS12_PBE_CRYPT_ERROR); 122 return NULL; 123 } 124 p = out; 125 #ifdef DEBUG_DECRYPT 126 { 127 FILE *op; 128 129 char fname[30]; 130 static int fnm = 1; 131 sprintf(fname, "DER%d", fnm++); 132 op = fopen(fname, "wb"); 133 fwrite (p, 1, outlen, op); 134 fclose(op); 135 } 136 #endif 137 if (seq & 1) ret = (char *) d2i_ASN1_SET(NULL, &p, outlen, d2i, 138 free_func, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); 139 else ret = d2i(NULL, &p, outlen); 140 if (seq & 2) memset(out, 0, outlen); 141 if(!ret) PKCS12err(PKCS12_F_PKCS12_DECRYPT_D2I,PKCS12_R_DECODE_ERROR); 142 OPENSSL_free (out); 143 return ret; 144 } 145 146 /* Encode ASN1 structure and encrypt, return OCTET STRING 147 * if 'seq' is non-zero 'obj' is a stack of structures to be encoded 148 * as a sequence 149 */ 150 151 ASN1_OCTET_STRING *PKCS12_i2d_encrypt (X509_ALGOR *algor, int (*i2d)(), 152 const char *pass, int passlen, 153 char *obj, int seq) 154 { 155 ASN1_OCTET_STRING *oct; 156 unsigned char *in, *p; 157 int inlen; 158 if (!(oct = M_ASN1_OCTET_STRING_new ())) { 159 PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE); 160 return NULL; 161 } 162 if (seq) inlen = i2d_ASN1_SET((STACK *)obj, NULL, i2d, V_ASN1_SEQUENCE, 163 V_ASN1_UNIVERSAL, IS_SEQUENCE); 164 else inlen = i2d (obj, NULL); 165 if (!inlen) { 166 PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,PKCS12_R_ENCODE_ERROR); 167 return NULL; 168 } 169 if (!(in = OPENSSL_malloc (inlen))) { 170 PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE); 171 return NULL; 172 } 173 p = in; 174 if (seq) i2d_ASN1_SET((STACK *)obj, &p, i2d, V_ASN1_SEQUENCE, 175 V_ASN1_UNIVERSAL, IS_SEQUENCE); 176 else i2d (obj, &p); 177 if (!PKCS12_pbe_crypt (algor, pass, passlen, in, inlen, &oct->data, 178 &oct->length, 1)) { 179 PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,PKCS12_R_ENCRYPT_ERROR); 180 OPENSSL_free(in); 181 return NULL; 182 } 183 OPENSSL_free (in); 184 return oct; 185 } 186 187 IMPLEMENT_PKCS12_STACK_OF(PKCS7) 188