Don't switch password formats using global state.
[openssl.git] / crypto / pkcs12 / p12_crpt.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 /* PKCS#12 PBE algorithms now in static table */
15
16 void PKCS12_PBE_add(void)
17 {
18 }
19
20 int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
21                         ASN1_TYPE *param, const EVP_CIPHER *cipher,
22                         const EVP_MD *md, int en_de)
23 {
24     PBEPARAM *pbe;
25     int saltlen, iter, ret;
26     unsigned char *salt;
27     unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
28     int (*pkcs12_key_gen)(const char *pass, int passlen,
29                           unsigned char *salt, int slen,
30                           int id, int iter, int n,
31                           unsigned char *out,
32                           const EVP_MD *md_type);
33
34     pkcs12_key_gen = PKCS12_key_gen_utf8;
35
36     if (cipher == NULL)
37         return 0;
38
39     /* Extract useful info from parameter */
40
41     pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param);
42     if (pbe == NULL) {
43         PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR);
44         return 0;
45     }
46
47     if (!pbe->iter)
48         iter = 1;
49     else
50         iter = ASN1_INTEGER_get(pbe->iter);
51     salt = pbe->salt->data;
52     saltlen = pbe->salt->length;
53     if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_KEY_ID,
54                            iter, EVP_CIPHER_key_length(cipher), key, md)) {
55         PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR);
56         PBEPARAM_free(pbe);
57         return 0;
58     }
59     if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_IV_ID,
60                            iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
61         PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR);
62         PBEPARAM_free(pbe);
63         return 0;
64     }
65     PBEPARAM_free(pbe);
66     ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de);
67     OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
68     OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
69     return ret;
70 }