⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tasn_dec.c

📁 开源的ssl算法openssl,版本0.9.8H
💻 C
📖 第 1 页 / 共 3 页
字号:
				isopt = 0;			else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);			/* attempt to read in field, allowing each to be			 * OPTIONAL */			ret = asn1_template_ex_d2i(pseqval, &p, len,							seqtt, isopt, ctx);			if (!ret)				{				errtt = seqtt;				goto err;				}			else if (ret == -1)				{				/* OPTIONAL component absent.				 * Free and zero the field.				 */				ASN1_template_free(pseqval, seqtt);				continue;				}			/* Update length */			len -= p - q;			}		/* Check for EOC if expecting one */		if (seq_eoc && !asn1_check_eoc(&p, len))			{			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);			goto err;			}		/* Check all data read */		if (!seq_nolen && len)			{			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,					ASN1_R_SEQUENCE_LENGTH_MISMATCH);			goto err;			}		/* If we get here we've got no more data in the SEQUENCE,		 * however we may not have read all fields so check all		 * remaining are OPTIONAL and clear any that are.		 */		for (; i < it->tcount; tt++, i++)			{			const ASN1_TEMPLATE *seqtt;			seqtt = asn1_do_adb(pval, tt, 1);			if (!seqtt)				goto err;			if (seqtt->flags & ASN1_TFLG_OPTIONAL)				{				ASN1_VALUE **pseqval;				pseqval = asn1_get_field_ptr(pval, seqtt);				ASN1_template_free(pseqval, seqtt);				}			else				{				errtt = seqtt;				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,							ASN1_R_FIELD_MISSING);				goto err;				}			}		/* Save encoding */		if (!asn1_enc_save(pval, *in, p - *in, it))			goto auxerr;		*in = p;		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))				goto auxerr;		return 1;		default:		return 0;		}	auxerr:	ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);	err:	ASN1_item_ex_free(pval, it);	if (errtt)		ERR_add_error_data(4, "Field=", errtt->field_name,					", Type=", it->sname);	else		ERR_add_error_data(2, "Type=", it->sname);	return 0;	}/* Templates are handled with two separate functions. * One handles any EXPLICIT tag and the other handles the rest. */static int asn1_template_ex_d2i(ASN1_VALUE **val,				const unsigned char **in, long inlen,				const ASN1_TEMPLATE *tt, char opt,							ASN1_TLC *ctx)	{	int flags, aclass;	int ret;	long len;	const unsigned char *p, *q;	char exp_eoc;	if (!val)		return 0;	flags = tt->flags;	aclass = flags & ASN1_TFLG_TAG_CLASS;	p = *in;	/* Check if EXPLICIT tag expected */	if (flags & ASN1_TFLG_EXPTAG)		{		char cst;		/* Need to work out amount of data available to the inner		 * content and where it starts: so read in EXPLICIT header to		 * get the info.		 */		ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,					&p, inlen, tt->tag, aclass, opt, ctx);		q = p;		if (!ret)			{			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,					ERR_R_NESTED_ASN1_ERROR);			return 0;			}		else if (ret == -1)			return -1;		if (!cst)			{			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,					ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);			return 0;			}		/* We've found the field so it can't be OPTIONAL now */		ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);		if (!ret)			{			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,					ERR_R_NESTED_ASN1_ERROR);			return 0;			}		/* We read the field in OK so update length */		len -= p - q;		if (exp_eoc)			{			/* If NDEF we must have an EOC here */			if (!asn1_check_eoc(&p, len))				{				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,						ASN1_R_MISSING_EOC);				goto err;				}			}		else			{			/* Otherwise we must hit the EXPLICIT tag end or its			 * an error */			if (len)				{				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,					ASN1_R_EXPLICIT_LENGTH_MISMATCH);				goto err;				}			}		}		else 			return asn1_template_noexp_d2i(val, in, inlen,								tt, opt, ctx);	*in = p;	return 1;	err:	ASN1_template_free(val, tt);	*val = NULL;	return 0;	}static int asn1_template_noexp_d2i(ASN1_VALUE **val,				const unsigned char **in, long len,				const ASN1_TEMPLATE *tt, char opt,				ASN1_TLC *ctx)	{	int flags, aclass;	int ret;	const unsigned char *p, *q;	if (!val)		return 0;	flags = tt->flags;	aclass = flags & ASN1_TFLG_TAG_CLASS;	p = *in;	q = p;	if (flags & ASN1_TFLG_SK_MASK)		{		/* SET OF, SEQUENCE OF */		int sktag, skaclass;		char sk_eoc;		/* First work out expected inner tag value */		if (flags & ASN1_TFLG_IMPTAG)			{			sktag = tt->tag;			skaclass = aclass;			}		else			{			skaclass = V_ASN1_UNIVERSAL;			if (flags & ASN1_TFLG_SET_OF)				sktag = V_ASN1_SET;			else				sktag = V_ASN1_SEQUENCE;			}		/* Get the tag */		ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,					&p, len, sktag, skaclass, opt, ctx);		if (!ret)			{			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,						ERR_R_NESTED_ASN1_ERROR);			return 0;			}		else if (ret == -1)			return -1;		if (!*val)			*val = (ASN1_VALUE *)sk_new_null();		else			{			/* We've got a valid STACK: free up any items present */			STACK *sktmp = (STACK *)*val;			ASN1_VALUE *vtmp;			while(sk_num(sktmp) > 0)				{				vtmp = (ASN1_VALUE *)sk_pop(sktmp);				ASN1_item_ex_free(&vtmp,						ASN1_ITEM_ptr(tt->item));				}			}						if (!*val)			{			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,						ERR_R_MALLOC_FAILURE);			goto err;			}		/* Read as many items as we can */		while(len > 0)			{			ASN1_VALUE *skfield;			q = p;			/* See if EOC found */			if (asn1_check_eoc(&p, len))				{				if (!sk_eoc)					{					ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,							ASN1_R_UNEXPECTED_EOC);					goto err;					}				len -= p - q;				sk_eoc = 0;				break;				}			skfield = NULL;			if (!ASN1_item_ex_d2i(&skfield, &p, len,						ASN1_ITEM_ptr(tt->item),						-1, 0, 0, ctx))				{				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,					ERR_R_NESTED_ASN1_ERROR);				goto err;				}			len -= p - q;			if (!sk_push((STACK *)*val, (char *)skfield))				{				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,						ERR_R_MALLOC_FAILURE);				goto err;				}			}		if (sk_eoc)			{			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);			goto err;			}		}	else if (flags & ASN1_TFLG_IMPTAG)		{		/* IMPLICIT tagging */		ret = ASN1_item_ex_d2i(val, &p, len,			ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);		if (!ret)			{			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,						ERR_R_NESTED_ASN1_ERROR);			goto err;			}		else if (ret == -1)			return -1;		}	else		{		/* Nothing special */		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),							-1, 0, opt, ctx);		if (!ret)			{			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,					ERR_R_NESTED_ASN1_ERROR);			goto err;			}		else if (ret == -1)			return -1;		}	*in = p;	return 1;	err:	ASN1_template_free(val, tt);	*val = NULL;	return 0;	}static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,				const unsigned char **in, long inlen, 				const ASN1_ITEM *it,				int tag, int aclass, char opt, ASN1_TLC *ctx)	{	int ret = 0, utype;	long plen;	char cst, inf, free_cont = 0;	const unsigned char *p;	BUF_MEM buf;	const unsigned char *cont = NULL;	long len; 	if (!pval)		{		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);		return 0; /* Should never happen */		}	if (it->itype == ASN1_ITYPE_MSTRING)		{		utype = tag;		tag = -1;		}	else		utype = it->utype;	if (utype == V_ASN1_ANY)		{		/* If type is ANY need to figure out type from tag */		unsigned char oclass;		if (tag >= 0)			{			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,					ASN1_R_ILLEGAL_TAGGED_ANY);			return 0;			}		if (opt)			{			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,					ASN1_R_ILLEGAL_OPTIONAL_ANY);			return 0;			}		p = *in;		ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,					&p, inlen, -1, 0, 0, ctx);		if (!ret)			{			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,					ERR_R_NESTED_ASN1_ERROR);			return 0;			}		if (oclass != V_ASN1_UNIVERSAL)			utype = V_ASN1_OTHER;		}	if (tag == -1)		{		tag = utype;		aclass = V_ASN1_UNIVERSAL;		}	p = *in;	/* Check header */	ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,				&p, inlen, tag, aclass, opt, ctx);	if (!ret)		{		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);		return 0;		}	else if (ret == -1)		return -1;        ret = 0;	/* SEQUENCE, SET and "OTHER" are left in encoded form */	if ((utype == V_ASN1_SEQUENCE)		|| (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER))		{		/* Clear context cache for type OTHER because the auto clear		 * when we have a exact match wont work		 */		if (utype == V_ASN1_OTHER)			{			asn1_tlc_clear(ctx);			}		/* SEQUENCE and SET must be constructed */		else if (!cst)			{			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,				ASN1_R_TYPE_NOT_CONSTRUCTED);			return 0;			}		cont = *in;		/* If indefinite length constructed find the real end */		if (inf)			{			if (!asn1_find_end(&p, plen, inf))				 goto err;			len = p - cont;			}		else			{			len = p - cont + plen;			p += plen;			buf.data = NULL;			}		}	else if (cst)		{		buf.length = 0;		buf.max = 0;		buf.data = NULL;		/* Should really check the internal tags are correct but		 * some things may get this wrong. The relevant specs		 * say that constructed string types should be OCTET STRINGs		 * internally irrespective of the type. So instead just check		 * for UNIVERSAL class and ignore the tag.		 */		if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL))			{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -