mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
pkcs12.c
00001 /* 00002 * PKCS#12 Personal Information Exchange Syntax 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 /* 00023 * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 00024 * 00025 * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf 00026 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn 00027 */ 00028 00029 #if !defined(POLARSSL_CONFIG_FILE) 00030 #include "polarssl/config.h" 00031 #else 00032 #include POLARSSL_CONFIG_FILE 00033 #endif 00034 00035 #if defined(POLARSSL_PKCS12_C) 00036 00037 #include "polarssl/pkcs12.h" 00038 #include "polarssl/asn1.h" 00039 #include "polarssl/cipher.h" 00040 00041 #include <string.h> 00042 00043 #if defined(POLARSSL_ARC4_C) 00044 #include "polarssl/arc4.h" 00045 #endif 00046 00047 #if defined(POLARSSL_DES_C) 00048 #include "polarssl/des.h" 00049 #endif 00050 00051 /* Implementation that should never be optimized out by the compiler */ 00052 static void polarssl_zeroize( void *v, size_t n ) { 00053 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00054 } 00055 00056 static int pkcs12_parse_pbe_params( asn1_buf *params, 00057 asn1_buf *salt, int *iterations ) 00058 { 00059 int ret; 00060 unsigned char **p = ¶ms->p; 00061 const unsigned char *end = params->p + params->len; 00062 00063 /* 00064 * pkcs-12PbeParams ::= SEQUENCE { 00065 * salt OCTET STRING, 00066 * iterations INTEGER 00067 * } 00068 * 00069 */ 00070 if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) 00071 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + 00072 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); 00073 00074 if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 ) 00075 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); 00076 00077 salt->p = *p; 00078 *p += salt->len; 00079 00080 if( ( ret = asn1_get_int( p, end, iterations ) ) != 0 ) 00081 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); 00082 00083 if( *p != end ) 00084 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + 00085 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00086 00087 return( 0 ); 00088 } 00089 00090 static int pkcs12_pbe_derive_key_iv( asn1_buf *pbe_params, md_type_t md_type, 00091 const unsigned char *pwd, size_t pwdlen, 00092 unsigned char *key, size_t keylen, 00093 unsigned char *iv, size_t ivlen ) 00094 { 00095 int ret, iterations; 00096 asn1_buf salt; 00097 size_t i; 00098 unsigned char unipwd[258]; 00099 00100 memset( &salt, 0, sizeof(asn1_buf) ); 00101 memset( &unipwd, 0, sizeof(unipwd) ); 00102 00103 if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, 00104 &iterations ) ) != 0 ) 00105 return( ret ); 00106 00107 for( i = 0; i < pwdlen; i++ ) 00108 unipwd[i * 2 + 1] = pwd[i]; 00109 00110 if( ( ret = pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, 00111 salt.p, salt.len, md_type, 00112 PKCS12_DERIVE_KEY, iterations ) ) != 0 ) 00113 { 00114 return( ret ); 00115 } 00116 00117 if( iv == NULL || ivlen == 0 ) 00118 return( 0 ); 00119 00120 if( ( ret = pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, 00121 salt.p, salt.len, md_type, 00122 PKCS12_DERIVE_IV, iterations ) ) != 0 ) 00123 { 00124 return( ret ); 00125 } 00126 return( 0 ); 00127 } 00128 00129 int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode, 00130 const unsigned char *pwd, size_t pwdlen, 00131 const unsigned char *data, size_t len, 00132 unsigned char *output ) 00133 { 00134 #if !defined(POLARSSL_ARC4_C) 00135 ((void) pbe_params); 00136 ((void) mode); 00137 ((void) pwd); 00138 ((void) pwdlen); 00139 ((void) data); 00140 ((void) len); 00141 ((void) output); 00142 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00143 #else 00144 int ret; 00145 unsigned char key[16]; 00146 arc4_context ctx; 00147 ((void) mode); 00148 00149 arc4_init( &ctx ); 00150 00151 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, POLARSSL_MD_SHA1, 00152 pwd, pwdlen, 00153 key, 16, NULL, 0 ) ) != 0 ) 00154 { 00155 return( ret ); 00156 } 00157 00158 arc4_setup( &ctx, key, 16 ); 00159 if( ( ret = arc4_crypt( &ctx, len, data, output ) ) != 0 ) 00160 goto exit; 00161 00162 exit: 00163 polarssl_zeroize( key, sizeof( key ) ); 00164 arc4_free( &ctx ); 00165 00166 return( ret ); 00167 #endif /* POLARSSL_ARC4_C */ 00168 } 00169 00170 int pkcs12_pbe( asn1_buf *pbe_params, int mode, 00171 cipher_type_t cipher_type, md_type_t md_type, 00172 const unsigned char *pwd, size_t pwdlen, 00173 const unsigned char *data, size_t len, 00174 unsigned char *output ) 00175 { 00176 int ret, keylen = 0; 00177 unsigned char key[32]; 00178 unsigned char iv[16]; 00179 const cipher_info_t *cipher_info; 00180 cipher_context_t cipher_ctx; 00181 size_t olen = 0; 00182 00183 cipher_info = cipher_info_from_type( cipher_type ); 00184 if( cipher_info == NULL ) 00185 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00186 00187 keylen = cipher_info->key_length / 8; 00188 00189 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, 00190 key, keylen, 00191 iv, cipher_info->iv_size ) ) != 0 ) 00192 { 00193 return( ret ); 00194 } 00195 00196 cipher_init( &cipher_ctx ); 00197 00198 if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 ) 00199 goto exit; 00200 00201 if( ( ret = cipher_setkey( &cipher_ctx, key, 8 * keylen, (operation_t) mode ) ) != 0 ) 00202 goto exit; 00203 00204 if( ( ret = cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) 00205 goto exit; 00206 00207 if( ( ret = cipher_reset( &cipher_ctx ) ) != 0 ) 00208 goto exit; 00209 00210 if( ( ret = cipher_update( &cipher_ctx, data, len, 00211 output, &olen ) ) != 0 ) 00212 { 00213 goto exit; 00214 } 00215 00216 if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) 00217 ret = POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH; 00218 00219 exit: 00220 polarssl_zeroize( key, sizeof( key ) ); 00221 polarssl_zeroize( iv, sizeof( iv ) ); 00222 cipher_free( &cipher_ctx ); 00223 00224 return( ret ); 00225 } 00226 00227 static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, 00228 const unsigned char *filler, size_t fill_len ) 00229 { 00230 unsigned char *p = data; 00231 size_t use_len; 00232 00233 while( data_len > 0 ) 00234 { 00235 use_len = ( data_len > fill_len ) ? fill_len : data_len; 00236 memcpy( p, filler, use_len ); 00237 p += use_len; 00238 data_len -= use_len; 00239 } 00240 } 00241 00242 int pkcs12_derivation( unsigned char *data, size_t datalen, 00243 const unsigned char *pwd, size_t pwdlen, 00244 const unsigned char *salt, size_t saltlen, 00245 md_type_t md_type, int id, int iterations ) 00246 { 00247 int ret; 00248 unsigned int j; 00249 00250 unsigned char diversifier[128]; 00251 unsigned char salt_block[128], pwd_block[128], hash_block[128]; 00252 unsigned char hash_output[POLARSSL_MD_MAX_SIZE]; 00253 unsigned char *p; 00254 unsigned char c; 00255 00256 size_t hlen, use_len, v, i; 00257 00258 const md_info_t *md_info; 00259 md_context_t md_ctx; 00260 00261 // This version only allows max of 64 bytes of password or salt 00262 if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) 00263 return( POLARSSL_ERR_PKCS12_BAD_INPUT_DATA ); 00264 00265 md_info = md_info_from_type( md_type ); 00266 if( md_info == NULL ) 00267 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00268 00269 md_init( &md_ctx ); 00270 00271 if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 ) 00272 return( ret ); 00273 hlen = md_get_size( md_info ); 00274 00275 if( hlen <= 32 ) 00276 v = 64; 00277 else 00278 v = 128; 00279 00280 memset( diversifier, (unsigned char) id, v ); 00281 00282 pkcs12_fill_buffer( salt_block, v, salt, saltlen ); 00283 pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); 00284 00285 p = data; 00286 while( datalen > 0 ) 00287 { 00288 // Calculate hash( diversifier || salt_block || pwd_block ) 00289 if( ( ret = md_starts( &md_ctx ) ) != 0 ) 00290 goto exit; 00291 00292 if( ( ret = md_update( &md_ctx, diversifier, v ) ) != 0 ) 00293 goto exit; 00294 00295 if( ( ret = md_update( &md_ctx, salt_block, v ) ) != 0 ) 00296 goto exit; 00297 00298 if( ( ret = md_update( &md_ctx, pwd_block, v ) ) != 0 ) 00299 goto exit; 00300 00301 if( ( ret = md_finish( &md_ctx, hash_output ) ) != 0 ) 00302 goto exit; 00303 00304 // Perform remaining ( iterations - 1 ) recursive hash calculations 00305 for( i = 1; i < (size_t) iterations; i++ ) 00306 { 00307 if( ( ret = md( md_info, hash_output, hlen, hash_output ) ) != 0 ) 00308 goto exit; 00309 } 00310 00311 use_len = ( datalen > hlen ) ? hlen : datalen; 00312 memcpy( p, hash_output, use_len ); 00313 datalen -= use_len; 00314 p += use_len; 00315 00316 if( datalen == 0 ) 00317 break; 00318 00319 // Concatenating copies of hash_output into hash_block (B) 00320 pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); 00321 00322 // B += 1 00323 for( i = v; i > 0; i-- ) 00324 if( ++hash_block[i - 1] != 0 ) 00325 break; 00326 00327 // salt_block += B 00328 c = 0; 00329 for( i = v; i > 0; i-- ) 00330 { 00331 j = salt_block[i - 1] + hash_block[i - 1] + c; 00332 c = (unsigned char) (j >> 8); 00333 salt_block[i - 1] = j & 0xFF; 00334 } 00335 00336 // pwd_block += B 00337 c = 0; 00338 for( i = v; i > 0; i-- ) 00339 { 00340 j = pwd_block[i - 1] + hash_block[i - 1] + c; 00341 c = (unsigned char) (j >> 8); 00342 pwd_block[i - 1] = j & 0xFF; 00343 } 00344 } 00345 00346 ret = 0; 00347 00348 exit: 00349 polarssl_zeroize( salt_block, sizeof( salt_block ) ); 00350 polarssl_zeroize( pwd_block, sizeof( pwd_block ) ); 00351 polarssl_zeroize( hash_block, sizeof( hash_block ) ); 00352 polarssl_zeroize( hash_output, sizeof( hash_output ) ); 00353 00354 md_free( &md_ctx ); 00355 00356 return( ret ); 00357 } 00358 00359 #endif /* POLARSSL_PKCS12_C */ 00360
Generated on Tue Jul 12 2022 13:50:37 by 1.7.2