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

📄 asn1.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	do {	/* shift and add in low order 7 bits */	    subidentifier = (subidentifier << 7) + (*(u_char *)bufp & ~ASN_BIT8);	    length--;	} while (*(u_char *)bufp++ & ASN_BIT8);	/* last byte has high bit clear *//*?? note, this test will never be true, since the largest value     of subidentifier is the value of MAX_SUBID! */	if (subidentifier > (u_long)MAX_SUBID){	    ERROR_MSG("subidentifier too large");	    return NULL;	}	*oidp++ = (oid)subidentifier;    }    /*     * The first two subidentifiers are encoded into the first component     * with the value (X * 40) + Y, where:     *	X is the value of the first subidentifier.     *  Y is the value of the second subidentifier.     */    subidentifier = (u_long)objid[1];    if (subidentifier == 0x2B){	objid[0] = 1;	objid[1] = 3;    } else {        if (subidentifier < 40) {            objid[0] = 0;	    objid[1] = subidentifier;        } else if (subidentifier < 80) {            objid[0] = 1;            objid[1] = subidentifier - 40;        } else if (subidentifier < 120) {            objid[0] = 2;            objid[1] = subidentifier - 80;        } else {	    objid[1] = (subidentifier % 40);	    objid[0] = ((subidentifier - objid[1]) / 40);        }    }    *objidlength = (int)(oidp - objid);    DEBUGMSG(("dump_recv", "  ASN ObjID: "));    DEBUGMSGOID(("dump_recv", objid, *objidlength));    DEBUGMSG(("dump_recv", "\n"));    return bufp;}/* * asn_build_objid - Builds an ASN object identifier object containing the * input string. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error.  u_char * asn_build_objid(      u_char     *data         IN - pointer to start of object      int        *datalength   IN/OUT - number of valid bytes left in buffer      int        type         IN - asn type of object      oid        *objid        IN - pointer to start of input buffer      int         objidlength  IN - number of sub-id's in objid */u_char *asn_build_objid(u_char *data,		size_t *datalength,		u_char type,		oid *objid,		size_t objidlength){/* * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}* * subidentifier ::= {leadingbyte}* lastbyte * leadingbyte ::= 1 7bitvalue * lastbyte ::= 0 7bitvalue */    size_t asnlength;    register oid *op = objid;    u_char objid_size[MAX_OID_LEN];    register u_long objid_val;    u_long first_objid_val;    register int i;    /* check if there are at least 2 sub-identifiers */    if (objidlength == 0){        /* there are not, so make OID have two with value of zero */        objid_val = 0;	objidlength = 2;    } else if (objidlength == 1){        /* encode the first value */	objid_val = (op[0] * 40);	objidlength = 2;	op++;    } else {        /* combine the first two values */	if ( op[1] > 40 ) {	    ERROR_MSG("build objid: bad second subidentifier");	    return NULL;	}	objid_val = (op[0] * 40) + op[1];	op += 2;    }    first_objid_val = objid_val;    /* calculate the number of bytes needed to store the encoded value */    for (i = 1, asnlength = 0;;) {        if (objid_val < (unsigned)0x80) {            objid_size[i] = 1;            asnlength += 1;        } else if (objid_val < (unsigned)0x4000) {            objid_size[i] = 2;            asnlength += 2;        } else if (objid_val < (unsigned)0x200000) {            objid_size[i] = 3;            asnlength += 3;        } else if (objid_val < (unsigned)0x10000000) {            objid_size[i] = 4;            asnlength += 4;        } else {            objid_size[i] = 5;            asnlength += 5;        }        i++;        if (i >= (int)objidlength)            break;        objid_val = *op++;    }     /* store the ASN.1 tag and length */    data = asn_build_header(data, datalength, type, asnlength);    if (_asn_build_header_check("build objid", data, *datalength, asnlength))	return NULL;    /* store the encoded OID value */    for (i = 1, objid_val = first_objid_val, op = objid+2;				i < (int)objidlength;                i++) {      if (i != 1) objid_val = *op++;        switch (objid_size[i]) {        case 1:            *data++ = (u_char)objid_val;            break;        case 2:            *data++ = (u_char)((objid_val>>7) | 0x80);            *data++ = (u_char)(objid_val & 0x07f);            break;        case 3:            *data++ = (u_char)((objid_val>>14) | 0x80);            *data++ = (u_char)((objid_val>>7 & 0x7f) | 0x80);            *data++ = (u_char)(objid_val & 0x07f);            break;        case 4:            *data++ = (u_char)((objid_val>>21) | 0x80);            *data++ = (u_char)((objid_val>>14 & 0x7f) | 0x80);            *data++ = (u_char)((objid_val>>7 & 0x7f) | 0x80);            *data++ = (u_char)(objid_val & 0x07f);            break;        case 5:            *data++ = (u_char)((objid_val>>28) | 0x80);            *data++ = (u_char)((objid_val>>21 & 0x7f) | 0x80);            *data++ = (u_char)((objid_val>>14 & 0x7f) | 0x80);            *data++ = (u_char)((objid_val>>7 & 0x7f) | 0x80);            *data++ = (u_char)(objid_val & 0x07f);            break;        }    }    /* return the length and data ptr */    *datalength -= asnlength;    return data;}/* * asn_parse_null - Interprets an ASN null type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error.  u_char * asn_parse_null(      u_char     *data         IN - pointer to start of object      int        *datalength   IN/OUT - number of valid bytes left in buffer      u_char     *type         OUT - asn type of object */u_char *asn_parse_null(u_char *data,	       size_t *datalength,	       u_char *type){/* * ASN.1 null ::= 0x05 0x00 */    register u_char   *bufp = data;    u_long	    asn_length;    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (bufp == NULL){	ERROR_MSG("parse null: bad length");	return NULL;    }    if (asn_length != 0){	ERROR_MSG("parse null: malformed ASN.1 null");	return NULL;    }    *datalength -= (bufp - data);    DEBUGDUMPSETUP("dump_recv", data, bufp - data);    DEBUGMSG(("dump_recv", "  ASN NULL\n"));    return bufp + asn_length;}/* * asn_build_null - Builds an ASN null object. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error.  u_char * asn_build_null(      u_char     *data         IN - pointer to start of object      int        *datalength   IN/OUT - number of valid bytes left in buffer      u_char      type         IN - asn type of object */u_char *asn_build_null(u_char *data,	       size_t *datalength,	       u_char type){/* * ASN.1 null ::= 0x05 0x00 */    return asn_build_header(data, datalength, type, 0);}/* * asn_parse_bitstring - pulls a bitstring out of an ASN bitstring type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  "string" is filled with the bit string. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error.  u_char * asn_parse_bitstring(      u_char     *data         IN - pointer to start of object      size_t     *datalength   IN/OUT - number of valid bytes left in buffer      u_char     *type         OUT - asn type of object      u_char     *string       IN/OUT - pointer to start of output buffer      size_t     *strlength    IN/OUT - size of output buffer */u_char *asn_parse_bitstring(u_char *data,		    size_t *datalength,		    u_char *type,		    u_char *string,		    size_t *strlength){/* * bitstring ::= 0x03 asnlength unused {byte}* */    static const char *errpre = "parse bitstring";    register u_char *bufp = data;    u_long	    asn_length;    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (_asn_parse_length_check(errpre, bufp, data,               asn_length, *datalength))	return NULL;    if ((size_t)asn_length > *strlength){	_asn_length_err(errpre, (size_t)asn_length, *strlength);	return NULL;    }    if (_asn_bitstring_check(errpre, asn_length, *bufp))	return NULL;    DEBUGDUMPSETUP("dump_recv", data, bufp - data);    DEBUGMSG(("dump_recv", "  ASN Bitstring: "));    DEBUGMSGHEX(("dump_recv", data, asn_length));    memmove(string, bufp, asn_length);    *strlength = (int)asn_length;    *datalength -= (int)asn_length + (bufp - data);    return bufp + asn_length;}/* * asn_build_bitstring - Builds an ASN bit string object containing the * input string. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error.  u_char * asn_build_bitstring(      u_char     *data         IN - pointer to start of object      int        *datalength   IN/OUT - number of valid bytes left in buffer      u_char      type         IN - asn type of object      u_char     *string       IN - pointer to start of input buffer      int         strlength    IN - size of input buffer */u_char *asn_build_bitstring(u_char *data,		    size_t *datalength,		    u_char type,		    u_char *string,		    size_t strlength){/* * ASN.1 bit string ::= 0x03 asnlength unused {byte}* */    static const char *errpre = "build bitstring";    if (_asn_bitstring_check(errpre, strlength, *string))	return NULL;    data = asn_build_header(data, datalength, type, strlength);    if (_asn_build_header_check(errpre,data,*datalength,strlength))	return NULL;    memmove(data, string, strlength);    *datalength -= strlength;    return data + strlength;}/* * asn_parse_unsigned_int64 - pulls a 64 bit unsigned long out of an ASN int * type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error.  u_char * asn_parse_unsigned_int64(      u_char     *data         IN - pointer to start of object      int        *datalength   IN/OUT - number of valid bytes left in buffer      u_char     *type         OUT - asn type of object      struct counter64 *cp     IN/OUT - pointer to counter struct      int         countersize  IN - size of output buffer */u_char *asn_parse_unsigned_int64(u_char *data,			 size_t *datalength,			 u_char *type, 			 struct counter64 *cp,			 size_t countersize){/* * ASN.1 integer ::= 0x02 asnlength byte {byte}* */    static const char *errpre = "parse uint64";    const int uint64sizelimit = (4 * 2) + 1;    register u_char *bufp = data;    u_long	    asn_length;    register u_long low = 0, high = 0;        if (countersize != sizeof(struct counter64)){	_asn_size_err(errpre, countersize, sizeof(struct counter64));	return NULL;    }    *type = *bufp++;    bufp = asn_parse_length(bufp, &asn_length);    if (_asn_parse_length_check(errpre, bufp, data, asn_length, *datalength))        return NULL;    DEBUGDUMPSETUP("dump_recv", data, bufp - data);#ifdef OPAQUE_SPECIAL_TYPES/* 64 bit counters as opaque */    if ((*type == ASN_OPAQUE) &&            (asn_length <= ASN_OPAQUE_COUNTER64_MX_BER_LEN) &&	    (*bufp == ASN_OPAQUE_TAG1) &&	    ((*(bufp+1) == ASN_OPAQUE_COUNTER64) ||             (*(bufp+1) == ASN_OPAQUE_U64))) {        DEBUGMSG(("dump_recv", "Opaque %.2x %.2x: ", *bufp, *(bufp+1)));	/* change type to Counter64 or U64 */        *type = *(bufp+1);        /* value is encoded as special format */	bufp = asn_parse_length(bufp + 2, &asn_length);	if (_asn_parse_length_check("parse opaque uint64", bufp, data,                  asn_length, *datalength))        return NULL;    }#endif /* OPAQUE_SPECIAL_TYPES */    if (((int)asn_length > uint64sizelimit) ||	(((int)asn_length == uint64sizelimit) && *bufp != 0x00)){	_asn_length_err(errpre, (size_t)asn_length, uint64sizelimit);	return NULL;    }    *datalength -= (int)asn_length + (bufp - data);    if (*bufp & 0x80){	low = ~low; /* integer is negative */	high = ~high;    }    while(asn_length--){	high = (high << 8) | ((low & 0xFF000000) >> 24);	low = (low << 8) | *bufp++;    }    cp->low = low;    cp->high = high;    DEBUGIF("dump_recv") {      char i64buf[I64CHARSZ+1];      printU64(i64buf, cp);    }    return bufp;}/* * asn_build_unsigned_int64 - builds an ASN object containing a 64 bit integer. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error.  u_char * asn_build_unsigned_int64(      u_char     *data         IN - pointer to start of output buffer      size_t     *datalength   IN/OUT - number of valid bytes left in buffer      u_char      type         IN  - asn type of object      struct counter64 *cp     IN - pointer to counter struct      size_t      countersize  IN - size of input buffer */u_char *asn_build_unsigned_int64(u_char *data,			 size_t *datalength,			 u_char type,			 struct counter64 *cp,			 size_t countersize){/* * ASN.1 integer ::= 0x02 asnlength byte {byte}* */    register u_long low, high;    register u_long mask, mask2;    int add_null_byte = 0;    size_t intsize;  if (countersize != sizeof(struct counter64)){    _asn_size_err("build uint64", countersize, sizeof(struct counter64));    return NULL;  }    intsize = 8;    low = cp->low;    high = cp->high;    mask = ((u_long) 0xFF) << (8 * (sizeof(long) - 1));    /* mask is 0xFF000000 on a big-endian machine */    if ((u_char)((high & mask) >> (8 * (sizeof(long) - 1))) & 0x80){	/* if MSB is set */	add_null_byte = 1;	intsize++;    } else {	/*	 * Truncate "unnecessary" bytes off of the most significant end of this 2's	 * complement integer.	 * There should be no sequence of 9 consecutive 1's or 0's at the most	 * significant end of the integer.

⌨️ 快捷键说明

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