OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
p12_mutl.c
Go to the documentation of this file.
1 /* p12_mutl.c */
2 /* Written by Dr Stephen N Henson ([email protected]) 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
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  * ([email protected]). This product includes software written by Tim
55  * Hudson ([email protected]).
56  *
57  */
58 
59 #ifndef OPENSSL_NO_HMAC
60 #include <stdio.h>
61 #include "cryptlib.h"
62 #include <openssl/hmac.h>
63 #include <openssl/rand.h>
64 #include <openssl/pkcs12.h>
65 
66 /* Generate a MAC */
67 int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
68  unsigned char *mac, unsigned int *maclen)
69 {
70  const EVP_MD *md_type;
71  HMAC_CTX hmac;
72  unsigned char key[EVP_MAX_MD_SIZE], *salt;
73  int saltlen, iter;
74  int md_size;
75 
76  if (!PKCS7_type_is_data(p12->authsafes))
77  {
79  return 0;
80  }
81 
82  salt = p12->mac->salt->data;
83  saltlen = p12->mac->salt->length;
84  if (!p12->mac->iter) iter = 1;
85  else iter = ASN1_INTEGER_get (p12->mac->iter);
86  if(!(md_type =
89  return 0;
90  }
91  md_size = EVP_MD_size(md_type);
92  if (md_size < 0)
93  return 0;
94  if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
95  md_size, key, md_type)) {
97  return 0;
98  }
99  HMAC_CTX_init(&hmac);
100  if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL)
101  || !HMAC_Update(&hmac, p12->authsafes->d.data->data,
102  p12->authsafes->d.data->length)
103  || !HMAC_Final(&hmac, mac, maclen))
104  {
105  HMAC_CTX_cleanup(&hmac);
106  return 0;
107  }
108  HMAC_CTX_cleanup(&hmac);
109  return 1;
110 }
111 
112 /* Verify the mac */
113 int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
114 {
115  unsigned char mac[EVP_MAX_MD_SIZE];
116  unsigned int maclen;
117  if(p12->mac == NULL) {
119  return 0;
120  }
121  if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) {
123  return 0;
124  }
125  if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
126  || memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0;
127  return 1;
128 }
129 
130 /* Set a mac */
131 
132 int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
133  unsigned char *salt, int saltlen, int iter, const EVP_MD *md_type)
134 {
135  unsigned char mac[EVP_MAX_MD_SIZE];
136  unsigned int maclen;
137 
138  if (!md_type) md_type = EVP_sha1();
139  if (PKCS12_setup_mac (p12, iter, salt, saltlen, md_type) ==
140  PKCS12_ERROR) {
142  return 0;
143  }
144  if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) {
146  return 0;
147  }
148  if (!(M_ASN1_OCTET_STRING_set (p12->mac->dinfo->digest, mac, maclen))) {
150  return 0;
151  }
152  return 1;
153 }
154 
155 /* Set up a mac structure */
156 int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
157  const EVP_MD *md_type)
158 {
159  if (!(p12->mac = PKCS12_MAC_DATA_new())) return PKCS12_ERROR;
160  if (iter > 1) {
161  if(!(p12->mac->iter = M_ASN1_INTEGER_new())) {
163  return 0;
164  }
165  if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
167  return 0;
168  }
169  }
170  if (!saltlen) saltlen = PKCS12_SALT_LEN;
171  p12->mac->salt->length = saltlen;
172  if (!(p12->mac->salt->data = OPENSSL_malloc (saltlen))) {
174  return 0;
175  }
176  if (!salt) {
177  if (RAND_pseudo_bytes (p12->mac->salt->data, saltlen) < 0)
178  return 0;
179  }
180  else memcpy (p12->mac->salt->data, salt, saltlen);
181  p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type));
182  if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) {
184  return 0;
185  }
187 
188  return 1;
189 }
190 #endif