File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / crypto / pkcs5.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:44 2020 UTC (4 years, 2 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    1: /*
    2:  * Copyright (C) 2012-2013 Tobias Brunner
    3:  * HSR Hochschule fuer Technik Rapperswil
    4:  *
    5:  * This program is free software; you can redistribute it and/or modify it
    6:  * under the terms of the GNU General Public License as published by the
    7:  * Free Software Foundation; either version 2 of the License, or (at your
    8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
    9:  *
   10:  * This program is distributed in the hope that it will be useful, but
   11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13:  * for more details.
   14:  */
   15: 
   16: #include "pkcs5.h"
   17: 
   18: #include <utils/debug.h>
   19: #include <asn1/oid.h>
   20: #include <asn1/asn1.h>
   21: #include <asn1/asn1_parser.h>
   22: #include <credentials/containers/pkcs12.h>
   23: 
   24: typedef struct private_pkcs5_t private_pkcs5_t;
   25: 
   26: /**
   27:  * Private data of a pkcs5_t object
   28:  */
   29: struct private_pkcs5_t {
   30: 
   31: 	/**
   32: 	 * Implements pkcs5_t.
   33: 	 */
   34: 	pkcs5_t public;
   35: 
   36: 	/**
   37: 	 * Salt used during encryption
   38: 	 */
   39: 	chunk_t salt;
   40: 
   41: 	/**
   42: 	 * Iterations for key derivation
   43: 	 */
   44: 	uint64_t iterations;
   45: 
   46: 	/**
   47: 	 * Encryption algorithm
   48: 	 */
   49: 	encryption_algorithm_t encr;
   50: 
   51: 	/**
   52: 	 * Encryption key length
   53: 	 */
   54: 	size_t keylen;
   55: 
   56: 	/**
   57: 	 * Crypter
   58: 	 */
   59: 	crypter_t *crypter;
   60: 
   61: 
   62: 	/**
   63: 	 * The encryption scheme
   64: 	 */
   65: 	enum {
   66: 		PKCS5_SCHEME_PBES1,
   67: 		PKCS5_SCHEME_PBES2,
   68: 		PKCS5_SCHEME_PKCS12,
   69: 	} scheme;
   70: 
   71: 	/**
   72: 	 * Data used for individual schemes
   73: 	 */
   74: 	union {
   75: 		struct {
   76: 			/**
   77: 			 * Hash algorithm
   78: 			 */
   79: 			hash_algorithm_t hash;
   80: 
   81: 			/**
   82: 			 * Hasher
   83: 			 */
   84: 			hasher_t *hasher;
   85: 
   86: 		} pbes1;
   87: 		struct {
   88: 			/**
   89: 			 * PRF algorithm
   90: 			 */
   91: 			pseudo_random_function_t prf_alg;
   92: 
   93: 			/**
   94: 			 * PRF
   95: 			 */
   96: 			prf_t * prf;
   97: 
   98: 			/**
   99: 			 * IV
  100: 			 */
  101: 			chunk_t iv;
  102: 
  103: 		} pbes2;
  104: 	} data;
  105: };
  106: 
  107: /**
  108:  * Verify padding of decrypted blob.
  109:  * Length of blob is adjusted accordingly.
  110:  */
  111: static bool verify_padding(crypter_t *crypter, chunk_t *blob)
  112: {
  113: 	uint8_t padding, count;
  114: 
  115: 	padding = count = blob->ptr[blob->len - 1];
  116: 
  117: 	if (padding > crypter->get_block_size(crypter))
  118: 	{
  119: 		return FALSE;
  120: 	}
  121: 	for (; blob->len && count; --blob->len, --count)
  122: 	{
  123: 		if (blob->ptr[blob->len - 1] != padding)
  124: 		{
  125: 			return FALSE;
  126: 		}
  127: 	}
  128: 	return TRUE;
  129: }
  130: 
  131: /**
  132:  * Prototype for key derivation functions.
  133:  */
  134: typedef bool (*kdf_t)(private_pkcs5_t *this, chunk_t password, chunk_t key);
  135: 
  136: /**
  137:  * Try to decrypt the given data with the given password using the given
  138:  * key derivation function. keymat is where the kdf function writes the key
  139:  * to, key and iv point to the actual keys and initialization vectors resp.
  140:  */
  141: static bool decrypt_generic(private_pkcs5_t *this, chunk_t password,
  142: 							chunk_t data, chunk_t *decrypted, kdf_t kdf,
  143: 							chunk_t keymat, chunk_t key, chunk_t iv)
  144: {
  145: 	if (!kdf(this, password, keymat))
  146: 	{
  147: 		return FALSE;
  148: 	}
  149: 	if (!this->crypter->set_key(this->crypter, key) ||
  150: 		!this->crypter->decrypt(this->crypter, data, iv, decrypted))
  151: 	{
  152: 		memwipe(keymat.ptr, keymat.len);
  153: 		return FALSE;
  154: 	}
  155: 	memwipe(keymat.ptr, keymat.len);
  156: 	if (verify_padding(this->crypter, decrypted))
  157: 	{
  158: 		return TRUE;
  159: 	}
  160: 	chunk_free(decrypted);
  161: 	return FALSE;
  162: }
  163: 
  164: /**
  165:  * KDF as used by PKCS#12
  166:  */
  167: static bool pkcs12_kdf(private_pkcs5_t *this, chunk_t password, chunk_t keymat)
  168: {
  169: 	chunk_t key, iv;
  170: 
  171: 	key = chunk_create(keymat.ptr, this->keylen);
  172: 	iv = chunk_create(keymat.ptr + this->keylen, keymat.len - this->keylen);
  173: 
  174: 	return pkcs12_derive_key(this->data.pbes1.hash, password, this->salt,
  175: 							 this->iterations, PKCS12_KEY_ENCRYPTION, key) &&
  176: 		   pkcs12_derive_key(this->data.pbes1.hash, password, this->salt,
  177: 							 this->iterations, PKCS12_KEY_IV, iv);
  178: }
  179: 
  180: /**
  181:  * Function F of PBKDF2
  182:  */
  183: static bool pbkdf2_f(chunk_t block, prf_t *prf, chunk_t seed,
  184: 					 uint64_t iterations)
  185: {
  186: 	chunk_t u;
  187: 	uint64_t i;
  188: 
  189: 	u = chunk_alloca(prf->get_block_size(prf));
  190: 	if (!prf->get_bytes(prf, seed, u.ptr))
  191: 	{
  192: 		return FALSE;
  193: 	}
  194: 	memcpy(block.ptr, u.ptr, block.len);
  195: 
  196: 	for (i = 1; i < iterations; i++)
  197: 	{
  198: 		if (!prf->get_bytes(prf, u, u.ptr))
  199: 		{
  200: 			return FALSE;
  201: 		}
  202: 		memxor(block.ptr, u.ptr, block.len);
  203: 	}
  204: 	return TRUE;
  205: }
  206: 
  207: /**
  208:  * PBKDF2 key derivation function for PBES2, key must be allocated
  209:  */
  210: static bool pbkdf2(private_pkcs5_t *this, chunk_t password, chunk_t key)
  211: {
  212: 	prf_t *prf;
  213: 	chunk_t keymat, block, seed;
  214: 	size_t blocks;
  215: 	uint32_t i = 0;
  216: 
  217: 	prf = this->data.pbes2.prf;
  218: 
  219: 	if (!prf->set_key(prf, password))
  220: 	{
  221: 		return FALSE;
  222: 	}
  223: 
  224: 	block.len = prf->get_block_size(prf);
  225: 	blocks = (key.len - 1) / block.len + 1;
  226: 	keymat = chunk_alloca(blocks * block.len);
  227: 
  228: 	seed = chunk_cata("cc", this->salt, chunk_from_thing(i));
  229: 
  230: 	for (; i < blocks; i++)
  231: 	{
  232: 		htoun32(seed.ptr + this->salt.len, i + 1);
  233: 		block.ptr = keymat.ptr + (i * block.len);
  234: 		if (!pbkdf2_f(block, prf, seed, this->iterations))
  235: 		{
  236: 			return FALSE;
  237: 		}
  238: 	}
  239: 	memcpy(key.ptr, keymat.ptr, key.len);
  240: 	return TRUE;
  241: }
  242: 
  243: /**
  244:  * PBKDF1 key derivation function for PBES1, key must be allocated
  245:  */
  246: static bool pbkdf1(private_pkcs5_t *this, chunk_t password, chunk_t key)
  247: {
  248: 	hasher_t *hasher;
  249: 	chunk_t hash;
  250: 	uint64_t i;
  251: 
  252: 	hasher = this->data.pbes1.hasher;
  253: 
  254: 	hash = chunk_alloca(hasher->get_hash_size(hasher));
  255: 	if (!hasher->get_hash(hasher, password, NULL) ||
  256: 		!hasher->get_hash(hasher, this->salt, hash.ptr))
  257: 	{
  258: 		return FALSE;
  259: 	}
  260: 
  261: 	for (i = 1; i < this->iterations; i++)
  262: 	{
  263: 		if (!hasher->get_hash(hasher, hash, hash.ptr))
  264: 		{
  265: 			return FALSE;
  266: 		}
  267: 	}
  268: 	memcpy(key.ptr, hash.ptr, key.len);
  269: 	return TRUE;
  270: }
  271: 
  272: static bool ensure_crypto_primitives(private_pkcs5_t *this, chunk_t data)
  273: {
  274: 	if (!this->crypter)
  275: 	{
  276: 		this->crypter = lib->crypto->create_crypter(lib->crypto, this->encr,
  277: 													this->keylen);
  278: 		if (!this->crypter)
  279: 		{
  280: 			DBG1(DBG_ASN, "  %N encryption algorithm not available",
  281: 				 encryption_algorithm_names, this->encr);
  282: 			return FALSE;
  283: 		}
  284: 	}
  285: 	if (data.len % this->crypter->get_block_size(this->crypter))
  286: 	{
  287: 		DBG1(DBG_ASN, "  data size is not a multiple of block size");
  288: 		return FALSE;
  289: 	}
  290: 	switch (this->scheme)
  291: 	{
  292: 		case PKCS5_SCHEME_PBES1:
  293: 		{
  294: 			if (!this->data.pbes1.hasher)
  295: 			{
  296: 				hasher_t *hasher;
  297: 
  298: 				hasher = lib->crypto->create_hasher(lib->crypto,
  299: 													this->data.pbes1.hash);
  300: 				if (!hasher)
  301: 				{
  302: 					DBG1(DBG_ASN, "  %N hash algorithm not available",
  303: 						 hash_algorithm_names, this->data.pbes1.hash);
  304: 					return  FALSE;
  305: 				}
  306: 				if (hasher->get_hash_size(hasher) < this->keylen)
  307: 				{
  308: 					hasher->destroy(hasher);
  309: 					return FALSE;
  310: 				}
  311: 				this->data.pbes1.hasher = hasher;
  312: 			}
  313: 			break;
  314: 		}
  315: 		case PKCS5_SCHEME_PBES2:
  316: 		{
  317: 			if (!this->data.pbes2.prf)
  318: 			{
  319: 				prf_t *prf;
  320: 
  321: 				prf = lib->crypto->create_prf(lib->crypto,
  322: 											  this->data.pbes2.prf_alg);
  323: 				if (!prf)
  324: 				{
  325: 					DBG1(DBG_ASN, "  %N prf algorithm not available",
  326: 						 pseudo_random_function_names,
  327: 						 this->data.pbes2.prf_alg);
  328: 					return FALSE;
  329: 				}
  330: 				this->data.pbes2.prf = prf;
  331: 			}
  332: 			break;
  333: 		}
  334: 		case PKCS5_SCHEME_PKCS12:
  335: 			break;
  336: 	}
  337: 	return TRUE;
  338: }
  339: 
  340: METHOD(pkcs5_t, decrypt, bool,
  341: 	private_pkcs5_t *this, chunk_t password, chunk_t data, chunk_t *decrypted)
  342: {
  343: 	chunk_t keymat, key, iv;
  344: 	kdf_t kdf;
  345: 
  346: 	if (!ensure_crypto_primitives(this, data) || !decrypted)
  347: 	{
  348: 		return FALSE;
  349: 	}
  350: 	kdf = pbkdf1;
  351: 	switch (this->scheme)
  352: 	{
  353: 		case PKCS5_SCHEME_PKCS12:
  354: 			kdf = pkcs12_kdf;
  355: 			/* fall-through */
  356: 		case PKCS5_SCHEME_PBES1:
  357: 			keymat = chunk_alloca(this->keylen +
  358: 								  this->crypter->get_iv_size(this->crypter));
  359: 			key = chunk_create(keymat.ptr, this->keylen);
  360: 			iv = chunk_create(keymat.ptr + this->keylen,
  361: 							  keymat.len - this->keylen);
  362: 			break;
  363: 		case PKCS5_SCHEME_PBES2:
  364: 			kdf = pbkdf2;
  365: 			keymat = chunk_alloca(this->keylen);
  366: 			key = keymat;
  367: 			iv = this->data.pbes2.iv;
  368: 			break;
  369: 		default:
  370: 			return FALSE;
  371: 	}
  372: 	return decrypt_generic(this, password, data, decrypted, kdf,
  373: 						   keymat, key, iv);
  374: }
  375: 
  376: /**
  377:  * ASN.1 definition of a PBEParameter structure
  378:  */
  379: static const asn1Object_t pbeParameterObjects[] = {
  380: 	{ 0, "PBEParameter",		ASN1_SEQUENCE,		ASN1_NONE	}, /* 0 */
  381: 	{ 1,   "salt",				ASN1_OCTET_STRING,	ASN1_BODY	}, /* 1 */
  382: 	{ 1,   "iterationCount",	ASN1_INTEGER,		ASN1_BODY	}, /* 2 */
  383: 	{ 0, "exit",				ASN1_EOC,			ASN1_EXIT	}
  384: };
  385: #define PBEPARAM_SALT					1
  386: #define PBEPARAM_ITERATION_COUNT		2
  387: 
  388: /**
  389:  * Parse a PBEParameter structure
  390:  */
  391: static bool parse_pbes1_params(private_pkcs5_t *this, chunk_t blob, int level0)
  392: {
  393: 	asn1_parser_t *parser;
  394: 	chunk_t object;
  395: 	int objectID;
  396: 	bool success;
  397: 
  398: 	parser = asn1_parser_create(pbeParameterObjects, blob);
  399: 	parser->set_top_level(parser, level0);
  400: 
  401: 	while (parser->iterate(parser, &objectID, &object))
  402: 	{
  403: 		switch (objectID)
  404: 		{
  405: 			case PBEPARAM_SALT:
  406: 			{
  407: 				this->salt = chunk_clone(object);
  408: 				break;
  409: 			}
  410: 			case PBEPARAM_ITERATION_COUNT:
  411: 			{
  412: 				this->iterations = asn1_parse_integer_uint64(object);
  413: 				break;
  414: 			}
  415: 		}
  416: 	}
  417: 	success = parser->success(parser);
  418: 	parser->destroy(parser);
  419: 	return success;
  420: }
  421: 
  422: /**
  423:  * ASN.1 definition of a PBKDF2-params structure
  424:  * The salt is actually a CHOICE and could be an AlgorithmIdentifier from
  425:  * PBKDF2-SaltSources (but as per RFC 8018 that's for future versions).
  426:  * The PRF algorithm is actually defined as DEFAULT and not OPTIONAL, but the
  427:  * parser can't handle ASN1_DEF with SEQUENCEs.
  428:  */
  429: static const asn1Object_t pbkdf2ParamsObjects[] = {
  430: 	{ 0, "PBKDF2-params",	ASN1_SEQUENCE,		ASN1_NONE			}, /* 0 */
  431: 	{ 1,   "salt",			ASN1_OCTET_STRING,	ASN1_BODY			}, /* 1 */
  432: 	{ 1,   "iterationCount",ASN1_INTEGER,		ASN1_BODY			}, /* 2 */
  433: 	{ 1,   "keyLength",		ASN1_INTEGER,		ASN1_OPT|ASN1_BODY	}, /* 3 */
  434: 	{ 1,   "end opt",		ASN1_EOC,			ASN1_END			}, /* 4 */
  435: 	{ 1,   "prf",			ASN1_SEQUENCE,		ASN1_OPT|ASN1_RAW	}, /* 5 */
  436: 	{ 1,   "end opt",		ASN1_EOC,			ASN1_END			}, /* 6 */
  437: 	{ 0, "exit",			ASN1_EOC,			ASN1_EXIT			}
  438: };
  439: #define PBKDF2_SALT					1
  440: #define PBKDF2_ITERATION_COUNT		2
  441: #define PBKDF2_KEYLENGTH			3
  442: #define PBKDF2_PRF					5
  443: 
  444: /**
  445:  * Parse a PBKDF2-params structure
  446:  */
  447: static bool parse_pbkdf2_params(private_pkcs5_t *this, chunk_t blob, int level0)
  448: {
  449: 	asn1_parser_t *parser;
  450: 	chunk_t object;
  451: 	int objectID;
  452: 	bool success = FALSE;
  453: 
  454: 	parser = asn1_parser_create(pbkdf2ParamsObjects, blob);
  455: 	parser->set_top_level(parser, level0);
  456: 
  457:  	/* keylen is optional */
  458: 	this->keylen = 0;
  459: 	/* defaults to id-hmacWithSHA1 */
  460: 	this->data.pbes2.prf_alg = PRF_HMAC_SHA1;
  461: 
  462: 	while (parser->iterate(parser, &objectID, &object))
  463: 	{
  464: 		switch (objectID)
  465: 		{
  466: 			case PBKDF2_SALT:
  467: 			{
  468: 				this->salt = chunk_clone(object);
  469: 				break;
  470: 			}
  471: 			case PBKDF2_ITERATION_COUNT:
  472: 			{
  473: 				this->iterations = asn1_parse_integer_uint64(object);
  474: 				break;
  475: 			}
  476: 			case PBKDF2_KEYLENGTH:
  477: 			{
  478: 				this->keylen = (size_t)asn1_parse_integer_uint64(object);
  479: 				break;
  480: 			}
  481: 			case PBKDF2_PRF:
  482: 			{
  483: 				int oid;
  484: 
  485: 				oid = asn1_parse_algorithmIdentifier(object,
  486: 										parser->get_level(parser) + 1, NULL);
  487: 				this->data.pbes2.prf_alg = pseudo_random_function_from_oid(oid);
  488: 				if (this->data.pbes2.prf_alg == PRF_UNDEFINED)
  489: 				{	/* unsupported PRF algorithm */
  490: 					goto end;
  491: 				}
  492: 				break;
  493: 			}
  494: 		}
  495: 	}
  496: 	success = parser->success(parser);
  497: end:
  498: 	parser->destroy(parser);
  499: 	return success;
  500: }
  501: 
  502: /**
  503:  * ASN.1 definition of a PBES2-params structure
  504:  */
  505: static const asn1Object_t pbes2ParamsObjects[] = {
  506: 	{ 0, "PBES2-params",		ASN1_SEQUENCE,		ASN1_NONE	}, /* 0 */
  507: 	{ 1,   "keyDerivationFunc",	ASN1_EOC,			ASN1_RAW	}, /* 1 */
  508: 	{ 1,   "encryptionScheme",	ASN1_EOC,			ASN1_RAW	}, /* 2 */
  509: 	{ 0, "exit",				ASN1_EOC,			ASN1_EXIT	}
  510: };
  511: #define PBES2PARAMS_KEY_DERIVATION_FUNC		1
  512: #define PBES2PARAMS_ENCRYPTION_SCHEME		2
  513: 
  514: /**
  515:  * Parse a PBES2-params structure
  516:  */
  517: static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0)
  518: {
  519: 	asn1_parser_t *parser;
  520: 	chunk_t object, params;
  521: 	size_t keylen;
  522: 	int objectID;
  523: 	bool success = FALSE;
  524: 
  525: 	parser = asn1_parser_create(pbes2ParamsObjects, blob);
  526: 	parser->set_top_level(parser, level0);
  527: 
  528: 	while (parser->iterate(parser, &objectID, &object))
  529: 	{
  530: 		switch (objectID)
  531: 		{
  532: 			case PBES2PARAMS_KEY_DERIVATION_FUNC:
  533: 			{
  534: 				int oid = asn1_parse_algorithmIdentifier(object,
  535: 									parser->get_level(parser) + 1, &params);
  536: 				if (oid != OID_PBKDF2)
  537: 				{	/* unsupported key derivation function */
  538: 					goto end;
  539: 				}
  540: 				if (!parse_pbkdf2_params(this, params,
  541: 										 parser->get_level(parser) + 1))
  542: 				{
  543: 					goto end;
  544: 				}
  545: 				break;
  546: 			}
  547: 			case PBES2PARAMS_ENCRYPTION_SCHEME:
  548: 			{
  549: 				int oid = asn1_parse_algorithmIdentifier(object,
  550: 									parser->get_level(parser) + 1, &params);
  551: 				this->encr = encryption_algorithm_from_oid(oid, &keylen);
  552: 				if (this->encr == ENCR_UNDEFINED)
  553: 				{	/* unsupported encryption scheme */
  554: 					goto end;
  555: 				}
  556: 				/* prefer encoded key length */
  557: 				this->keylen = this->keylen ?: keylen / 8;
  558: 				if (!this->keylen)
  559: 				{	/* set default key length for known algorithms */
  560: 					switch (this->encr)
  561: 					{
  562: 						case ENCR_DES:
  563: 							this->keylen = 8;
  564: 							break;
  565: 						case ENCR_3DES:
  566: 							this->keylen = 24;
  567: 							break;
  568: 						case ENCR_BLOWFISH:
  569: 							this->keylen = 16;
  570: 							break;
  571: 						default:
  572: 							goto end;
  573: 					}
  574: 				}
  575: 				if (!asn1_parse_simple_object(&params, ASN1_OCTET_STRING,
  576: 									parser->get_level(parser) + 1, "IV"))
  577: 				{
  578: 					goto end;
  579: 				}
  580: 				this->data.pbes2.iv = chunk_clone(params);
  581: 				break;
  582: 			}
  583: 		}
  584: 	}
  585: 	success = parser->success(parser);
  586: end:
  587: 	parser->destroy(parser);
  588: 	return success;
  589: }
  590: 
  591: METHOD(pkcs5_t, destroy, void,
  592: 	private_pkcs5_t *this)
  593: {
  594: 	DESTROY_IF(this->crypter);
  595: 	chunk_free(&this->salt);
  596: 	switch (this->scheme)
  597: 	{
  598: 		case PKCS5_SCHEME_PBES1:
  599: 			DESTROY_IF(this->data.pbes1.hasher);
  600: 			break;
  601: 		case PKCS5_SCHEME_PBES2:
  602: 			DESTROY_IF(this->data.pbes2.prf);
  603: 			chunk_free(&this->data.pbes2.iv);
  604: 			break;
  605: 		case PKCS5_SCHEME_PKCS12:
  606: 			break;
  607: 	}
  608: 	free(this);
  609: }
  610: 
  611: /*
  612:  * Described in header
  613:  */
  614: pkcs5_t *pkcs5_from_algorithmIdentifier(chunk_t blob, int level0)
  615: {
  616: 	private_pkcs5_t *this;
  617: 	chunk_t params;
  618: 	int oid;
  619: 
  620: 	INIT(this,
  621: 		.public = {
  622: 			.decrypt = _decrypt,
  623: 			.destroy = _destroy,
  624: 		},
  625: 		.scheme = PKCS5_SCHEME_PBES1,
  626: 		.keylen = 8,
  627: 	);
  628: 
  629: 	oid = asn1_parse_algorithmIdentifier(blob, level0, &params);
  630: 
  631: 	switch (oid)
  632: 	{
  633: 		case OID_PBE_MD5_DES_CBC:
  634: 			this->encr = ENCR_DES;
  635: 			this->data.pbes1.hash = HASH_MD5;
  636: 			break;
  637: 		case OID_PBE_SHA1_DES_CBC:
  638: 			this->encr = ENCR_DES;
  639: 			this->data.pbes1.hash = HASH_SHA1;
  640: 			break;
  641: 		case OID_PBE_SHA1_3DES_CBC:
  642: 			this->scheme = PKCS5_SCHEME_PKCS12;
  643: 			this->keylen = 24;
  644: 			this->encr = ENCR_3DES;
  645: 			this->data.pbes1.hash = HASH_SHA1;
  646: 			break;
  647: 		case OID_PBE_SHA1_RC2_CBC_40:
  648: 		case OID_PBE_SHA1_RC2_CBC_128:
  649: 			this->scheme = PKCS5_SCHEME_PKCS12;
  650: 			this->keylen = (oid == OID_PBE_SHA1_RC2_CBC_40) ? 5 : 16;
  651: 			this->encr = ENCR_RC2_CBC;
  652: 			this->data.pbes1.hash = HASH_SHA1;
  653: 			break;
  654: 		case OID_PBES2:
  655: 			this->scheme = PKCS5_SCHEME_PBES2;
  656: 			break;
  657: 		default:
  658: 			/* encryption scheme not supported */
  659: 			goto failure;
  660: 	}
  661: 
  662: 	switch (this->scheme)
  663: 	{
  664: 		case PKCS5_SCHEME_PBES1:
  665: 		case PKCS5_SCHEME_PKCS12:
  666: 			if (!parse_pbes1_params(this, params, level0))
  667: 			{
  668: 				goto failure;
  669: 			}
  670: 			break;
  671: 		case PKCS5_SCHEME_PBES2:
  672: 			if (!parse_pbes2_params(this, params, level0))
  673: 			{
  674: 				goto failure;
  675: 			}
  676: 			break;
  677: 	}
  678: 	return &this->public;
  679: 
  680: failure:
  681: 	destroy(this);
  682: 	return NULL;
  683: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>