ssl/libcrypto/src/crypto/pkcs12/p12_mutl.c
changeset 31 ce057bb09d0b
parent 0 e4d67989cc36
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     1 /* p12_mutl.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 #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 EXPORT_C 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 
       
    75 	if (!PKCS7_type_is_data(p12->authsafes))
       
    76 		{
       
    77 		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_CONTENT_TYPE_NOT_DATA);
       
    78 		return 0;
       
    79 		}
       
    80 
       
    81 	salt = p12->mac->salt->data;
       
    82 	saltlen = p12->mac->salt->length;
       
    83 	if (!p12->mac->iter) iter = 1;
       
    84 	else iter = ASN1_INTEGER_get (p12->mac->iter);
       
    85     	if(!(md_type =
       
    86 		 EVP_get_digestbyobj (p12->mac->dinfo->algor->algorithm))) {
       
    87 		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
       
    88 		return 0;
       
    89 	}
       
    90 	if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
       
    91 				 EVP_MD_size(md_type), key, md_type)) {
       
    92 		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR);
       
    93 		return 0;
       
    94 	}
       
    95 	HMAC_CTX_init(&hmac);
       
    96 	HMAC_Init_ex(&hmac, key, EVP_MD_size(md_type), md_type, NULL);
       
    97     	HMAC_Update(&hmac, p12->authsafes->d.data->data,
       
    98 					 p12->authsafes->d.data->length);
       
    99     	HMAC_Final(&hmac, mac, maclen);
       
   100     	HMAC_CTX_cleanup(&hmac);
       
   101 	return 1;
       
   102 
       
   103 }
       
   104 
       
   105 /* Verify the mac */
       
   106 EXPORT_C int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
       
   107 {
       
   108 	unsigned char mac[EVP_MAX_MD_SIZE];
       
   109 	unsigned int maclen;
       
   110 	if(p12->mac == NULL) {
       
   111 		PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC,PKCS12_R_MAC_ABSENT);
       
   112 		return 0;
       
   113 	}
       
   114 	if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) {
       
   115 		PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC,PKCS12_R_MAC_GENERATION_ERROR);
       
   116 		return 0;
       
   117 	}
       
   118 	if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
       
   119 	|| memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0;
       
   120 	return 1;
       
   121 }
       
   122 
       
   123 /* Set a mac */
       
   124 
       
   125 EXPORT_C int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
       
   126 	     unsigned char *salt, int saltlen, int iter, const EVP_MD *md_type)
       
   127 {
       
   128 	unsigned char mac[EVP_MAX_MD_SIZE];
       
   129 	unsigned int maclen;
       
   130 
       
   131 	if (!md_type) md_type = EVP_sha1();
       
   132 	if (PKCS12_setup_mac (p12, iter, salt, saltlen, md_type) ==
       
   133 				 	PKCS12_ERROR) {
       
   134 		PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_SETUP_ERROR);
       
   135 		return 0;
       
   136 	}
       
   137 	if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) {
       
   138 		PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_GENERATION_ERROR);
       
   139 		return 0;
       
   140 	}
       
   141 	if (!(M_ASN1_OCTET_STRING_set (p12->mac->dinfo->digest, mac, maclen))) {
       
   142 		PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_STRING_SET_ERROR);
       
   143 						return 0;
       
   144 	}
       
   145 	return 1;
       
   146 }
       
   147 
       
   148 /* Set up a mac structure */
       
   149 EXPORT_C int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
       
   150 	     const EVP_MD *md_type)
       
   151 {
       
   152 	if (!(p12->mac = PKCS12_MAC_DATA_new())) return PKCS12_ERROR;
       
   153 	if (iter > 1) {
       
   154 		if(!(p12->mac->iter = M_ASN1_INTEGER_new())) {
       
   155 			PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
       
   156 			return 0;
       
   157 		}
       
   158 		if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
       
   159 			PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
       
   160 			return 0;
       
   161 		}
       
   162 	}
       
   163 	if (!saltlen) saltlen = PKCS12_SALT_LEN;
       
   164 	p12->mac->salt->length = saltlen;
       
   165 	if (!(p12->mac->salt->data = OPENSSL_malloc (saltlen))) {
       
   166 		PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
       
   167 		return 0;
       
   168 	}
       
   169 	if (!salt) {
       
   170 		if (RAND_pseudo_bytes (p12->mac->salt->data, saltlen) < 0)
       
   171 			return 0;
       
   172 	}
       
   173 	else memcpy (p12->mac->salt->data, salt, saltlen);
       
   174 	p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type));
       
   175 	if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) {
       
   176 		PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
       
   177 		return 0;
       
   178 	}
       
   179 	p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL;
       
   180 	
       
   181 	return 1;
       
   182 }
       
   183 #endif