• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 1999-2018 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/crypto.h>
13 #include <openssl/hmac.h>
14 #include <openssl/rand.h>
15 #include <openssl/pkcs12.h>
16 #include "p12_local.h"
17 
PKCS12_mac_present(const PKCS12 * p12)18 int PKCS12_mac_present(const PKCS12 *p12)
19 {
20     return p12->mac ? 1 : 0;
21 }
22 
PKCS12_get0_mac(const ASN1_OCTET_STRING ** pmac,const X509_ALGOR ** pmacalg,const ASN1_OCTET_STRING ** psalt,const ASN1_INTEGER ** piter,const PKCS12 * p12)23 void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac,
24                      const X509_ALGOR **pmacalg,
25                      const ASN1_OCTET_STRING **psalt,
26                      const ASN1_INTEGER **piter,
27                      const PKCS12 *p12)
28 {
29     if (p12->mac) {
30         X509_SIG_get0(p12->mac->dinfo, pmacalg, pmac);
31         if (psalt)
32             *psalt = p12->mac->salt;
33         if (piter)
34             *piter = p12->mac->iter;
35     } else {
36         if (pmac)
37             *pmac = NULL;
38         if (pmacalg)
39             *pmacalg = NULL;
40         if (psalt)
41             *psalt = NULL;
42         if (piter)
43             *piter = NULL;
44     }
45 }
46 
47 #define TK26_MAC_KEY_LEN 32
48 
pkcs12_gen_gost_mac_key(const char * pass,int passlen,const unsigned char * salt,int saltlen,int iter,int keylen,unsigned char * key,const EVP_MD * digest)49 static int pkcs12_gen_gost_mac_key(const char *pass, int passlen,
50                                    const unsigned char *salt, int saltlen,
51                                    int iter, int keylen, unsigned char *key,
52                                    const EVP_MD *digest)
53 {
54     unsigned char out[96];
55 
56     if (keylen != TK26_MAC_KEY_LEN) {
57         return 0;
58     }
59 
60     if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter,
61                            digest, sizeof(out), out)) {
62         return 0;
63     }
64     memcpy(key, out + sizeof(out) - TK26_MAC_KEY_LEN, TK26_MAC_KEY_LEN);
65     OPENSSL_cleanse(out, sizeof(out));
66     return 1;
67 }
68 
69 /* Generate a MAC */
pkcs12_gen_mac(PKCS12 * p12,const char * pass,int passlen,unsigned char * mac,unsigned int * maclen,int (* pkcs12_key_gen)(const char * pass,int passlen,unsigned char * salt,int slen,int id,int iter,int n,unsigned char * out,const EVP_MD * md_type))70 static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
71                           unsigned char *mac, unsigned int *maclen,
72                           int (*pkcs12_key_gen)(const char *pass, int passlen,
73                                                 unsigned char *salt, int slen,
74                                                 int id, int iter, int n,
75                                                 unsigned char *out,
76                                                 const EVP_MD *md_type))
77 {
78     int ret = 0;
79     const EVP_MD *md_type;
80     HMAC_CTX *hmac = NULL;
81     unsigned char key[EVP_MAX_MD_SIZE], *salt;
82     int saltlen, iter;
83     int md_size = 0;
84     int md_type_nid;
85     const X509_ALGOR *macalg;
86     const ASN1_OBJECT *macoid;
87 
88     if (pkcs12_key_gen == NULL)
89         pkcs12_key_gen = PKCS12_key_gen_utf8;
90 
91     if (!PKCS7_type_is_data(p12->authsafes)) {
92         PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA);
93         return 0;
94     }
95 
96     salt = p12->mac->salt->data;
97     saltlen = p12->mac->salt->length;
98     if (!p12->mac->iter)
99         iter = 1;
100     else
101         iter = ASN1_INTEGER_get(p12->mac->iter);
102     X509_SIG_get0(p12->mac->dinfo, &macalg, NULL);
103     X509_ALGOR_get0(&macoid, NULL, NULL, macalg);
104     if ((md_type = EVP_get_digestbyobj(macoid)) == NULL) {
105         PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
106         return 0;
107     }
108     md_size = EVP_MD_size(md_type);
109     md_type_nid = EVP_MD_type(md_type);
110     if (md_size < 0)
111         return 0;
112     if ((md_type_nid == NID_id_GostR3411_94
113          || md_type_nid == NID_id_GostR3411_2012_256
114          || md_type_nid == NID_id_GostR3411_2012_512)
115         && ossl_safe_getenv("LEGACY_GOST_PKCS12") == NULL) {
116         md_size = TK26_MAC_KEY_LEN;
117         if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter,
118                                      md_size, key, md_type)) {
119             PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
120             goto err;
121         }
122     } else
123         if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID,
124                                iter, md_size, key, md_type)) {
125         PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
126         goto err;
127     }
128     if ((hmac = HMAC_CTX_new()) == NULL
129         || !HMAC_Init_ex(hmac, key, md_size, md_type, NULL)
130         || !HMAC_Update(hmac, p12->authsafes->d.data->data,
131                         p12->authsafes->d.data->length)
132         || !HMAC_Final(hmac, mac, maclen)) {
133         goto err;
134     }
135     ret = 1;
136 
137 err:
138     OPENSSL_cleanse(key, sizeof(key));
139     HMAC_CTX_free(hmac);
140     return ret;
141 }
142 
PKCS12_gen_mac(PKCS12 * p12,const char * pass,int passlen,unsigned char * mac,unsigned int * maclen)143 int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
144                    unsigned char *mac, unsigned int *maclen)
145 {
146     return pkcs12_gen_mac(p12, pass, passlen, mac, maclen, NULL);
147 }
148 
149 /* Verify the mac */
PKCS12_verify_mac(PKCS12 * p12,const char * pass,int passlen)150 int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
151 {
152     unsigned char mac[EVP_MAX_MD_SIZE];
153     unsigned int maclen;
154     const ASN1_OCTET_STRING *macoct;
155 
156     if (p12->mac == NULL) {
157         PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT);
158         return 0;
159     }
160     if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen,
161                         PKCS12_key_gen_utf8)) {
162         PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR);
163         return 0;
164     }
165     X509_SIG_get0(p12->mac->dinfo, NULL, &macoct);
166     if ((maclen != (unsigned int)ASN1_STRING_length(macoct))
167         || CRYPTO_memcmp(mac, ASN1_STRING_get0_data(macoct), maclen) != 0)
168         return 0;
169 
170     return 1;
171 }
172 
173 /* Set a mac */
174 
PKCS12_set_mac(PKCS12 * p12,const char * pass,int passlen,unsigned char * salt,int saltlen,int iter,const EVP_MD * md_type)175 int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
176                    unsigned char *salt, int saltlen, int iter,
177                    const EVP_MD *md_type)
178 {
179     unsigned char mac[EVP_MAX_MD_SIZE];
180     unsigned int maclen;
181     ASN1_OCTET_STRING *macoct;
182 
183     if (!md_type)
184         md_type = EVP_sha1();
185     if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) {
186         PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR);
187         return 0;
188     }
189     /*
190      * Note that output mac is forced to UTF-8...
191      */
192     if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen,
193                         PKCS12_key_gen_utf8)) {
194         PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR);
195         return 0;
196     }
197     X509_SIG_getm(p12->mac->dinfo, NULL, &macoct);
198     if (!ASN1_OCTET_STRING_set(macoct, mac, maclen)) {
199         PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR);
200         return 0;
201     }
202     return 1;
203 }
204 
205 /* Set up a mac structure */
PKCS12_setup_mac(PKCS12 * p12,int iter,unsigned char * salt,int saltlen,const EVP_MD * md_type)206 int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
207                      const EVP_MD *md_type)
208 {
209     X509_ALGOR *macalg;
210 
211     PKCS12_MAC_DATA_free(p12->mac);
212     p12->mac = NULL;
213 
214     if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL)
215         return PKCS12_ERROR;
216     if (iter > 1) {
217         if ((p12->mac->iter = ASN1_INTEGER_new()) == NULL) {
218             PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
219             return 0;
220         }
221         if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
222             PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
223             return 0;
224         }
225     }
226     if (!saltlen)
227         saltlen = PKCS12_SALT_LEN;
228     if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) {
229         PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
230         return 0;
231     }
232     p12->mac->salt->length = saltlen;
233     if (!salt) {
234         if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0)
235             return 0;
236     } else
237         memcpy(p12->mac->salt->data, salt, saltlen);
238     X509_SIG_getm(p12->mac->dinfo, &macalg, NULL);
239     if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(EVP_MD_type(md_type)),
240                          V_ASN1_NULL, NULL)) {
241         PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
242         return 0;
243     }
244 
245     return 1;
246 }
247