p12_mutl.c revision 280304
1457SN/A/* p12_mutl.c */ 22453Sihse/* 3457SN/A * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4457SN/A * 1999. 5457SN/A */ 6457SN/A/* ==================================================================== 7457SN/A * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 8457SN/A * 9457SN/A * Redistribution and use in source and binary forms, with or without 10457SN/A * modification, are permitted provided that the following conditions 11457SN/A * are met: 12457SN/A * 13457SN/A * 1. Redistributions of source code must retain the above copyright 14457SN/A * notice, this list of conditions and the following disclaimer. 15457SN/A * 16457SN/A * 2. Redistributions in binary form must reproduce the above copyright 17457SN/A * notice, this list of conditions and the following disclaimer in 18457SN/A * the documentation and/or other materials provided with the 19457SN/A * distribution. 20457SN/A * 21457SN/A * 3. All advertising materials mentioning features or use of this 22457SN/A * software must display the following acknowledgment: 23457SN/A * "This product includes software developed by the OpenSSL Project 24457SN/A * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25457SN/A * 261410Sihse * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 271410Sihse * endorse or promote products derived from this software without 281410Sihse * prior written permission. For written permission, please contact 291410Sihse * licensing@OpenSSL.org. 301410Sihse * 31457SN/A * 5. Products derived from this software may not be called "OpenSSL" 321410Sihse * nor may "OpenSSL" appear in their names without prior written 331410Sihse * permission of the OpenSSL Project. 34457SN/A * 351410Sihse * 6. Redistributions of any form whatsoever must retain the following 362518Sihse * acknowledgment: 372518Sihse * "This product includes software developed by the OpenSSL Project 382518Sihse * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 392518Sihse * 402518Sihse * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 411410Sihse * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 421410Sihse * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 431410Sihse * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 441410Sihse * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 451410Sihse * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46492SN/A * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 471410Sihse * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 482518Sihse * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 492518Sihse * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50492SN/A * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 511410Sihse * OF THE POSSIBILITY OF SUCH DAMAGE. 521410Sihse * ==================================================================== 53492SN/A * 541410Sihse * This product includes cryptographic software written by Eric Young 551410Sihse * (eay@cryptsoft.com). This product includes software written by Tim 561410Sihse * Hudson (tjh@cryptsoft.com). 571410Sihse * 581410Sihse */ 59492SN/A 601410Sihse#ifndef OPENSSL_NO_HMAC 611410Sihse# include <stdio.h> 621651Sihse# include "cryptlib.h" 631410Sihse# include <openssl/hmac.h> 641410Sihse# include <openssl/rand.h> 651426Sihse# include <openssl/pkcs12.h> 661426Sihse 671651Sihse/* Generate a MAC */ 681651Sihseint PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, 691651Sihse unsigned char *mac, unsigned int *maclen) 70492SN/A{ 711426Sihse const EVP_MD *md_type; 721426Sihse HMAC_CTX hmac; 731426Sihse unsigned char key[EVP_MAX_MD_SIZE], *salt; 741426Sihse int saltlen, iter; 751426Sihse int md_size; 761426Sihse 771410Sihse if (!PKCS7_type_is_data(p12->authsafes)) { 781410Sihse PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA); 791410Sihse return 0; 801410Sihse } 811410Sihse 821426Sihse salt = p12->mac->salt->data; 831426Sihse saltlen = p12->mac->salt->length; 841410Sihse if (!p12->mac->iter) 851410Sihse iter = 1; 861410Sihse else 871410Sihse iter = ASN1_INTEGER_get(p12->mac->iter); 881410Sihse if (!(md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm))) { 891410Sihse PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); 901410Sihse return 0; 911410Sihse } 92492SN/A md_size = EVP_MD_size(md_type); 931410Sihse if (md_size < 0) 941410Sihse return 0; 951410Sihse if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, 961410Sihse md_size, key, md_type)) { 971410Sihse PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); 981410Sihse return 0; 991410Sihse } 1001410Sihse HMAC_CTX_init(&hmac); 1011410Sihse if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) 1021410Sihse || !HMAC_Update(&hmac, p12->authsafes->d.data->data, 1031410Sihse p12->authsafes->d.data->length) 104492SN/A || !HMAC_Final(&hmac, mac, maclen)) { 1051410Sihse HMAC_CTX_cleanup(&hmac); 1061410Sihse return 0; 1071410Sihse } 1081410Sihse HMAC_CTX_cleanup(&hmac); 1091410Sihse return 1; 1101410Sihse} 1111410Sihse 1121410Sihse/* Verify the mac */ 1131410Sihseint PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) 1141410Sihse{ 1151410Sihse unsigned char mac[EVP_MAX_MD_SIZE]; 1161410Sihse unsigned int maclen; 117492SN/A if (p12->mac == NULL) { 1181410Sihse PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT); 1191410Sihse return 0; 1201410Sihse } 1211410Sihse if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { 1221410Sihse PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR); 1231410Sihse return 0; 1241410Sihse } 1251410Sihse if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) 1261410Sihse || memcmp(mac, p12->mac->dinfo->digest->data, maclen)) 1271410Sihse return 0; 128492SN/A return 1; 1291915Sihse} 1301915Sihse 1311915Sihse/* Set a mac */ 1321915Sihse 1331915Sihseint PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, 1341915Sihse unsigned char *salt, int saltlen, int iter, 1351915Sihse const EVP_MD *md_type) 1361915Sihse{ 1371915Sihse unsigned char mac[EVP_MAX_MD_SIZE]; 1381915Sihse unsigned int maclen; 1391915Sihse 1401915Sihse if (!md_type) 1411915Sihse md_type = EVP_sha1(); 1421915Sihse if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) { 1431915Sihse PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR); 1441915Sihse return 0; 1451915Sihse } 1461410Sihse if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { 1471410Sihse PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR); 1481410Sihse return 0; 1491410Sihse } 1501410Sihse if (!(M_ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen))) { 1511410Sihse PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR); 152492SN/A return 0; 1531410Sihse } 154505SN/A return 1; 155837SN/A} 1561915Sihse 1571915Sihse/* Set up a mac structure */ 1581915Sihseint PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, 1591915Sihse const EVP_MD *md_type) 1601915Sihse{ 1612535Sasemenyuk if (!(p12->mac = PKCS12_MAC_DATA_new())) 1622535Sasemenyuk return PKCS12_ERROR; 1632535Sasemenyuk if (iter > 1) { 1642535Sasemenyuk if (!(p12->mac->iter = M_ASN1_INTEGER_new())) { 1652535Sasemenyuk PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); 1662535Sasemenyuk return 0; 1672535Sasemenyuk } 1682535Sasemenyuk if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { 1692535Sasemenyuk PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); 1702535Sasemenyuk return 0; 1712535Sasemenyuk } 1722535Sasemenyuk } 1731915Sihse if (!saltlen) 174476SN/A saltlen = PKCS12_SALT_LEN; 175837SN/A p12->mac->salt->length = saltlen; 1761410Sihse if (!(p12->mac->salt->data = OPENSSL_malloc(saltlen))) { 1771410Sihse PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); 178837SN/A return 0; 1791410Sihse } 1801410Sihse if (!salt) { 1811410Sihse if (RAND_pseudo_bytes(p12->mac->salt->data, saltlen) < 0) 1821410Sihse return 0; 1831410Sihse } else 1841410Sihse memcpy(p12->mac->salt->data, salt, saltlen); 1851410Sihse p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type)); 1861410Sihse if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) { 1871862Serikj PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); 188457SN/A return 0; 1891915Sihse } 1902535Sasemenyuk p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL; 1911915Sihse 1921410Sihse return 1; 193457SN/A} 1941410Sihse#endif 195457SN/A