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

📄 tasn_enc.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 2 页
字号:
/* tasn_enc.c *//* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. *//* ==================================================================== * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" *    nor may "OpenSSL" appear in their names without prior written *    permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com).  This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */#include <stddef.h>#include <string.h>#include "cryptlib.h"#include <openssl/asn1.h>#include <openssl/asn1t.h>#include <openssl/objects.h>static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,					const ASN1_ITEM *it,					int tag, int aclass);static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,					int skcontlen, const ASN1_ITEM *item,					int do_sort, int iclass);static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,					const ASN1_TEMPLATE *tt,					int tag, int aclass);static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,					const ASN1_ITEM *it, int flags);/* Top level i2d equivalents: the 'ndef' variant instructs the encoder * to use indefinite length constructed encoding, where appropriate */int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,						const ASN1_ITEM *it)	{	return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);	}int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)	{	return asn1_item_flags_i2d(val, out, it, 0);	}/* Encode an ASN1 item, this is use by the * standard 'i2d' function. 'out' points to  * a buffer to output the data to. * * The new i2d has one additional feature. If the output * buffer is NULL (i.e. *out == NULL) then a buffer is * allocated and populated with the encoding. */static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,					const ASN1_ITEM *it, int flags)	{	if (out && !*out)		{		unsigned char *p, *buf;		int len;		len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);		if (len <= 0)			return len;		buf = OPENSSL_malloc(len);		if (!buf)			return -1;		p = buf;		ASN1_item_ex_i2d(&val, &p, it, -1, flags);		*out = buf;		return len;		}	return ASN1_item_ex_i2d(&val, out, it, -1, flags);	}/* Encode an item, taking care of IMPLICIT tagging (if any). * This function performs the normal item handling: it can be * used in external types. */int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,			const ASN1_ITEM *it, int tag, int aclass)	{	const ASN1_TEMPLATE *tt = NULL;	unsigned char *p = NULL;	int i, seqcontlen, seqlen, ndef = 1;	const ASN1_COMPAT_FUNCS *cf;	const ASN1_EXTERN_FUNCS *ef;	const ASN1_AUX *aux = it->funcs;	ASN1_aux_cb *asn1_cb = 0;	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)		return 0;	if (aux && aux->asn1_cb)		 asn1_cb = aux->asn1_cb;	switch(it->itype)		{		case ASN1_ITYPE_PRIMITIVE:		if (it->templates)			return asn1_template_ex_i2d(pval, out, it->templates,								tag, aclass);		return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);		break;		case ASN1_ITYPE_MSTRING:		return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);		case ASN1_ITYPE_CHOICE:		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))				return 0;		i = asn1_get_choice_selector(pval, it);		if ((i >= 0) && (i < it->tcount))			{			ASN1_VALUE **pchval;			const ASN1_TEMPLATE *chtt;			chtt = it->templates + i;			pchval = asn1_get_field_ptr(pval, chtt);			return asn1_template_ex_i2d(pchval, out, chtt,								-1, aclass);			}		/* Fixme: error condition if selector out of range */		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))				return 0;		break;		case ASN1_ITYPE_EXTERN:		/* If new style i2d it does all the work */		ef = it->funcs;		return ef->asn1_ex_i2d(pval, out, it, tag, aclass);		case ASN1_ITYPE_COMPAT:		/* old style hackery... */		cf = it->funcs;		if (out)			p = *out;		i = cf->asn1_i2d(*pval, out);		/* Fixup for IMPLICIT tag: note this messes up for tags > 30,		 * but so did the old code. Tags > 30 are very rare anyway.		 */		if (out && (tag != -1))			*p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);		return i;				case ASN1_ITYPE_NDEF_SEQUENCE:		/* Use indefinite length constructed if requested */		if (aclass & ASN1_TFLG_NDEF) ndef = 2;		/* fall through */		case ASN1_ITYPE_SEQUENCE:		i = asn1_enc_restore(&seqcontlen, out, pval, it);		/* An error occurred */		if (i < 0)			return 0;		/* We have a valid cached encoding... */		if (i > 0)			return seqcontlen;		/* Otherwise carry on */		seqcontlen = 0;		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */		if (tag == -1)			{			tag = V_ASN1_SEQUENCE;			/* Retain any other flags in aclass */			aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)					| V_ASN1_UNIVERSAL;			}		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))				return 0;		/* First work out sequence content length */		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)			{			const ASN1_TEMPLATE *seqtt;			ASN1_VALUE **pseqval;			seqtt = asn1_do_adb(pval, tt, 1);			if (!seqtt)				return 0;			pseqval = asn1_get_field_ptr(pval, seqtt);			/* FIXME: check for errors in enhanced version */			seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,								-1, aclass);			}		seqlen = ASN1_object_size(ndef, seqcontlen, tag);		if (!out)			return seqlen;		/* Output SEQUENCE header */		ASN1_put_object(out, ndef, seqcontlen, tag, aclass);		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)			{			const ASN1_TEMPLATE *seqtt;			ASN1_VALUE **pseqval;			seqtt = asn1_do_adb(pval, tt, 1);			if (!seqtt)				return 0;			pseqval = asn1_get_field_ptr(pval, seqtt);			/* FIXME: check for errors in enhanced version */			asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);			}		if (ndef == 2)			ASN1_put_eoc(out);		if (asn1_cb  && !asn1_cb(ASN1_OP_I2D_POST, pval, it))				return 0;		return seqlen;		default:		return 0;		}	return 0;	}int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,							const ASN1_TEMPLATE *tt)	{	return asn1_template_ex_i2d(pval, out, tt, -1, 0);	}static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,				const ASN1_TEMPLATE *tt, int tag, int iclass)	{	int i, ret, flags, ttag, tclass, ndef;	flags = tt->flags;	/* Work out tag and class to use: tagging may come	 * either from the template or the arguments, not both	 * because this would create ambiguity. Additionally	 * the iclass argument may contain some additional flags	 * which should be noted and passed down to other levels.	 */	if (flags & ASN1_TFLG_TAG_MASK)		{		/* Error if argument and template tagging */		if (tag != -1)			/* FIXME: error code here */			return -1;		/* Get tagging from template */		ttag = tt->tag;		tclass = flags & ASN1_TFLG_TAG_CLASS;		}	else if (tag != -1)		{		/* No template tagging, get from arguments */		ttag = tag;		tclass = iclass & ASN1_TFLG_TAG_CLASS;		}	else		{		ttag = -1;		tclass = 0;		}	/* 	 * Remove any class mask from iflag.	 */	iclass &= ~ASN1_TFLG_TAG_CLASS;	/* At this point 'ttag' contains the outer tag to use,	 * 'tclass' is the class and iclass is any flags passed	 * to this function.	 */	/* if template and arguments require ndef, use it */	if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))		ndef = 2;	else ndef = 1;	if (flags & ASN1_TFLG_SK_MASK)		{		/* SET OF, SEQUENCE OF */		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;		int isset, sktag, skaclass;		int skcontlen, sklen;		ASN1_VALUE *skitem;		if (!*pval)			return 0;		if (flags & ASN1_TFLG_SET_OF)			{			isset = 1;			/* 2 means we reorder */			if (flags & ASN1_TFLG_SEQUENCE_OF)				isset = 2;			}		else isset = 0;		/* Work out inner tag value: if EXPLICIT		 * or no tagging use underlying type.		 */		if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG))			{			sktag = ttag;			skaclass = tclass;			}		else			{

⌨️ 快捷键说明

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