3c860584e80bf8d8cd9c10cc431f544457cca613
[openssl.git] / crypto / pkcs12 / p12_decr.c
1 /*
2  * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/pkcs12.h>
13
14 /* Define this to dump decrypted output to files called DERnnn */
15 /*
16  * #define OPENSSL_DEBUG_DECRYPT
17  */
18
19 /*
20  * Encrypt/Decrypt a buffer based on password and algor, result in a
21  * OPENSSL_malloc'ed buffer
22  */
23 unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
24                                 const char *pass, int passlen,
25                                 const unsigned char *in, int inlen,
26                                 unsigned char **data, int *datalen, int en_de)
27 {
28     unsigned char *out = NULL;
29     int outlen, i;
30     EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
31
32     if (ctx == NULL) {
33         PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
34         goto err;
35     }
36
37     /* Decrypt data */
38     if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
39                             algor->parameter, ctx, en_de)) {
40         PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
41                   PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
42         goto err;
43     }
44
45     if ((out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(ctx)))
46             == NULL) {
47         PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
48         goto err;
49     }
50
51     if (!EVP_CipherUpdate(ctx, out, &i, in, inlen)) {
52         OPENSSL_free(out);
53         out = NULL;
54         PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB);
55         goto err;
56     }
57
58     outlen = i;
59     if (!EVP_CipherFinal_ex(ctx, out + i, &i)) {
60         OPENSSL_free(out);
61         out = NULL;
62         PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
63                   PKCS12_R_PKCS12_CIPHERFINAL_ERROR);
64         goto err;
65     }
66     outlen += i;
67     if (datalen)
68         *datalen = outlen;
69     if (data)
70         *data = out;
71  err:
72     EVP_CIPHER_CTX_free(ctx);
73     return out;
74
75 }
76
77 /*
78  * Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer
79  * after use.
80  */
81
82 void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
83                               const char *pass, int passlen,
84                               const ASN1_OCTET_STRING *oct, int zbuf)
85 {
86     unsigned char *out;
87     const unsigned char *p;
88     void *ret;
89     int outlen;
90
91     if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
92                           &out, &outlen, 0)) {
93         PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,
94                   PKCS12_R_PKCS12_PBE_CRYPT_ERROR);
95         return NULL;
96     }
97     p = out;
98 #ifdef OPENSSL_DEBUG_DECRYPT
99     {
100         FILE *op;
101
102         char fname[30];
103         static int fnm = 1;
104         sprintf(fname, "DER%d", fnm++);
105         op = fopen(fname, "wb");
106         fwrite(p, 1, outlen, op);
107         fclose(op);
108     }
109 #endif
110     ret = ASN1_item_d2i(NULL, &p, outlen, it);
111     if (zbuf)
112         OPENSSL_cleanse(out, outlen);
113     if (!ret)
114         PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, PKCS12_R_DECODE_ERROR);
115     OPENSSL_free(out);
116     return ret;
117 }
118
119 /*
120  * Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero
121  * encoding.
122  */
123
124 ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
125                                            const ASN1_ITEM *it,
126                                            const char *pass, int passlen,
127                                            void *obj, int zbuf)
128 {
129     ASN1_OCTET_STRING *oct = NULL;
130     unsigned char *in = NULL;
131     int inlen;
132
133     if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
134         PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, ERR_R_MALLOC_FAILURE);
135         goto err;
136     }
137     inlen = ASN1_item_i2d(obj, &in, it);
138     if (!in) {
139         PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCODE_ERROR);
140         goto err;
141     }
142     if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
143                           &oct->length, 1)) {
144         PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
145         OPENSSL_free(in);
146         goto err;
147     }
148     if (zbuf)
149         OPENSSL_cleanse(in, inlen);
150     OPENSSL_free(in);
151     return oct;
152  err:
153     ASN1_OCTET_STRING_free(oct);
154     return NULL;
155 }