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

📄 asn1_gen.c

📁 开源的ssl算法openssl,版本0.9.8H
💻 C
📖 第 1 页 / 共 2 页
字号:
/* asn1_gen.c *//* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL * project 2002. *//* ==================================================================== * Copyright (c) 2002 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 "cryptlib.h"#include <openssl/asn1.h>#include <openssl/x509v3.h>#define ASN1_GEN_FLAG		0x10000#define ASN1_GEN_FLAG_IMP	(ASN1_GEN_FLAG|1)#define ASN1_GEN_FLAG_EXP	(ASN1_GEN_FLAG|2)#define ASN1_GEN_FLAG_TAG	(ASN1_GEN_FLAG|3)#define ASN1_GEN_FLAG_BITWRAP	(ASN1_GEN_FLAG|4)#define ASN1_GEN_FLAG_OCTWRAP	(ASN1_GEN_FLAG|5)#define ASN1_GEN_FLAG_SEQWRAP	(ASN1_GEN_FLAG|6)#define ASN1_GEN_FLAG_SETWRAP	(ASN1_GEN_FLAG|7)#define ASN1_GEN_FLAG_FORMAT	(ASN1_GEN_FLAG|8)#define ASN1_GEN_STR(str,val)	{str, sizeof(str) - 1, val}#define ASN1_FLAG_EXP_MAX	20/* Input formats *//* ASCII: default */#define ASN1_GEN_FORMAT_ASCII	1/* UTF8 */#define ASN1_GEN_FORMAT_UTF8	2/* Hex */#define ASN1_GEN_FORMAT_HEX	3/* List of bits */#define ASN1_GEN_FORMAT_BITLIST	4struct tag_name_st	{	const char *strnam;	int len;	int tag;	};typedef struct	{	int exp_tag;	int exp_class;	int exp_constructed;	int exp_pad;	long exp_len;	} tag_exp_type;typedef struct	{	int imp_tag;	int imp_class;	int utype;	int format;	const char *str;	tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];	int exp_count;	} tag_exp_arg;static int bitstr_cb(const char *elem, int len, void *bitstr);static int asn1_cb(const char *elem, int len, void *bitstr);static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok);static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);static int asn1_str2tag(const char *tagstr, int len);ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)	{	X509V3_CTX cnf;	if (!nconf)		return ASN1_generate_v3(str, NULL);	X509V3_set_nconf(&cnf, nconf);	return ASN1_generate_v3(str, &cnf);	}ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)	{	ASN1_TYPE *ret;	tag_exp_arg asn1_tags;	tag_exp_type *etmp;	int i, len;	unsigned char *orig_der = NULL, *new_der = NULL;	const unsigned char *cpy_start;	unsigned char *p;	const unsigned char *cp;	int cpy_len;	long hdr_len;	int hdr_constructed = 0, hdr_tag, hdr_class;	int r;	asn1_tags.imp_tag = -1;	asn1_tags.imp_class = -1;	asn1_tags.format = ASN1_GEN_FORMAT_ASCII;	asn1_tags.exp_count = 0;	if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)		return NULL;	if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET))		{		if (!cnf)			{			ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);			return NULL;			}		ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);		}	else		ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);	if (!ret)		return NULL;	/* If no tagging return base type */	if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))		return ret;	/* Generate the encoding */	cpy_len = i2d_ASN1_TYPE(ret, &orig_der);	ASN1_TYPE_free(ret);	ret = NULL;	/* Set point to start copying for modified encoding */	cpy_start = orig_der;	/* Do we need IMPLICIT tagging? */	if (asn1_tags.imp_tag != -1)		{		/* If IMPLICIT we will replace the underlying tag */		/* Skip existing tag+len */		r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);		if (r & 0x80)			goto err;		/* Update copy length */		cpy_len -= cpy_start - orig_der;		/* For IMPLICIT tagging the length should match the		 * original length and constructed flag should be		 * consistent.		 */		if (r & 0x1)			{			/* Indefinite length constructed */			hdr_constructed = 2;			hdr_len = 0;			}		else			/* Just retain constructed flag */			hdr_constructed = r & V_ASN1_CONSTRUCTED;		/* Work out new length with IMPLICIT tag: ignore constructed		 * because it will mess up if indefinite length		 */		len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);		}	else		len = cpy_len;	/* Work out length in any EXPLICIT, starting from end */	for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--)		{		/* Content length: number of content octets + any padding */		len += etmp->exp_pad;		etmp->exp_len = len;		/* Total object length: length including new header */		len = ASN1_object_size(0, len, etmp->exp_tag);		}	/* Allocate buffer for new encoding */	new_der = OPENSSL_malloc(len);	/* Generate tagged encoding */	p = new_der;	/* Output explicit tags first */	for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++)		{		ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,					etmp->exp_tag, etmp->exp_class);		if (etmp->exp_pad)			*p++ = 0;		}	/* If IMPLICIT, output tag */	if (asn1_tags.imp_tag != -1)		ASN1_put_object(&p, hdr_constructed, hdr_len,					asn1_tags.imp_tag, asn1_tags.imp_class);	/* Copy across original encoding */	memcpy(p, cpy_start, cpy_len);	cp = new_der;	/* Obtain new ASN1_TYPE structure */	ret = d2i_ASN1_TYPE(NULL, &cp, len);	err:	if (orig_der)		OPENSSL_free(orig_der);	if (new_der)		OPENSSL_free(new_der);	return ret;	}static int asn1_cb(const char *elem, int len, void *bitstr)	{	tag_exp_arg *arg = bitstr;	int i;	int utype;	int vlen = 0;	const char *p, *vstart = NULL;	int tmp_tag, tmp_class;	for(i = 0, p = elem; i < len; p++, i++)		{		/* Look for the ':' in name value pairs */		if (*p == ':')			{			vstart = p + 1;			vlen = len - (vstart - elem);			len = p - elem;			break;			}		}	utype = asn1_str2tag(elem, len);	if (utype == -1)		{		ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);		ERR_add_error_data(2, "tag=", elem);		return -1;		}	/* If this is not a modifier mark end of string and exit */	if (!(utype & ASN1_GEN_FLAG))		{		arg->utype = utype;		arg->str = vstart;		/* If no value and not end of string, error */		if (!vstart && elem[len])			{			ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);			return -1;			}		return 0;		}	switch(utype)		{		case ASN1_GEN_FLAG_IMP:		/* Check for illegal multiple IMPLICIT tagging */		if (arg->imp_tag != -1)			{			ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);			return -1;			}		if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))			return -1;		break;		case ASN1_GEN_FLAG_EXP:		if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))			return -1;		if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))			return -1;		break;		case ASN1_GEN_FLAG_SEQWRAP:		if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))			return -1;		break;		case ASN1_GEN_FLAG_SETWRAP:		if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))			return -1;		break;		case ASN1_GEN_FLAG_BITWRAP:		if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))			return -1;		break;		case ASN1_GEN_FLAG_OCTWRAP:		if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))			return -1;		break;		case ASN1_GEN_FLAG_FORMAT:		if (!strncmp(vstart, "ASCII", 5))			arg->format = ASN1_GEN_FORMAT_ASCII;		else if (!strncmp(vstart, "UTF8", 4))			arg->format = ASN1_GEN_FORMAT_UTF8;		else if (!strncmp(vstart, "HEX", 3))			arg->format = ASN1_GEN_FORMAT_HEX;		else if (!strncmp(vstart, "BITLIST", 3))			arg->format = ASN1_GEN_FORMAT_BITLIST;		else			{			ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT);			return -1;			}		break;		}	return 1;	}static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)	{	char erch[2];	long tag_num;	char *eptr;	if (!vstart)		return 0;	tag_num = strtoul(vstart, &eptr, 10);	/* Check we haven't gone past max length: should be impossible */	if (eptr && *eptr && (eptr > vstart + vlen))		return 0;	if (tag_num < 0)		{		ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);		return 0;		}	*ptag = tag_num;	/* If we have non numeric characters, parse them */	if (eptr)		vlen -= eptr - vstart;	else 		vlen = 0;	if (vlen)		{		switch (*eptr)			{			case 'U':			*pclass = V_ASN1_UNIVERSAL;			break;			case 'A':			*pclass = V_ASN1_APPLICATION;			break;			case 'P':			*pclass = V_ASN1_PRIVATE;			break;			case 'C':			*pclass = V_ASN1_CONTEXT_SPECIFIC;			break;			default:			erch[0] = *eptr;			erch[1] = 0;			ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);			ERR_add_error_data(2, "Char=", erch);

⌨️ 快捷键说明

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