📄 asn1.c
字号:
/* oid *objid; IN/OUT - pointer to start of output buffer */ /* int *objidlength; IN/OUT - number of sub-id's in objid */{ /* * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}* * subidentifier ::= {leadingbyte}* lastbyte * leadingbyte ::= 1 7bitvalue * lastbyte ::= 0 7bitvalue */ u_char *bufp = data; oid *oidp = objid + 1; u_int subidentifier; int length; u_int asn_length; *type = *bufp++; bufp = asn_parse_length(bufp, &asn_length); if (bufp == NULL) return (NULL); if (asn_length + (bufp - data) > *datalength) { snmp_set_api_error(SNMPERR_ASN_DECODE); return (NULL); } *datalength -= (int) asn_length + (bufp - data); /* Handle invalid object identifier encodings of the form 06 00 robustly */ if (asn_length == 0) objid[0] = objid[1] = 0; length = asn_length; (*objidlength)--; /* account for expansion of first byte */ while (length > 0 && (*objidlength)-- > 0) { subidentifier = 0; do { /* shift and add in low order 7 bits */ subidentifier = (subidentifier << 7) + (*(u_char *) bufp & ~ASN_BIT8); length--; } while (*(u_char *) bufp++ & ASN_BIT8); /* while last byte has high bit clear */ if (subidentifier > (u_int) MAX_SUBID) { snmp_set_api_error(SNMPERR_ASN_DECODE); 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_int) objid[1]; if (subidentifier == 0x2B) { objid[0] = 1; objid[1] = 3; } else { objid[1] = (u_char) (subidentifier % 40); objid[0] = (u_char) ((subidentifier - objid[1]) / 40); } *objidlength = (int) (oidp - objid); 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, int *datalength, u_char type, oid * objid, int objidlength) /* u_char *data; IN - pointer to start of object */ /* int *datalength; IN/OUT - # of valid bytes left in buf */ /* u_char 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 */{ /* * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}* * subidentifier ::= {leadingbyte}* lastbyte * leadingbyte ::= 1 7bitvalue * lastbyte ::= 0 7bitvalue */ u_char buf[MAX_OID_LEN]; u_char *bp = buf; oid *op = objid; int asnlength; u_int subid, mask, testmask; int bits, testbits; if (objidlength < 2) { *bp++ = 0; objidlength = 0; } else { *bp++ = op[1] + (op[0] * 40); objidlength -= 2; op += 2; } while (objidlength-- > 0) { subid = *op++; if (subid < 127) { /* off by one? */ *bp++ = subid; } else { mask = 0x7F; /* handle subid == 0 case */ bits = 0; /* testmask *MUST* !!!! be of an unsigned type */ for (testmask = 0x7F, testbits = 0; testmask != 0; testmask <<= 7, testbits += 7) { if (subid & testmask) { /* if any bits set */ mask = testmask; bits = testbits; } } /* mask can't be zero here */ for (; mask != 0x7F; mask >>= 7, bits -= 7) { /* fix a mask that got truncated above */ if (mask == 0x1E00000) mask = 0xFE00000; *bp++ = (u_char) (((subid & mask) >> bits) | ASN_BIT8); } *bp++ = (u_char) (subid & mask); } } asnlength = bp - buf; data = asn_build_header_with_truth(data, datalength, type, asnlength, 1); if (data == NULL) return (NULL); if (*datalength < asnlength) { snmp_set_api_error(SNMPERR_ASN_DECODE); return (NULL); } xmemcpy((char *) data, (char *) buf, asnlength); *datalength -= asnlength; return (data + asnlength);}#if 0/* * 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, int *datalength, u_char * type) /* u_char *data; IN - pointer to start of object */ /* int *datalength; IN/OUT - # of valid bytes left in buf */ /* u_char *type; OUT - ASN type of object */{ /* * ASN.1 null ::= 0x05 0x00 */ u_char *bufp = data; u_int asn_length; *type = *bufp++; bufp = asn_parse_length(bufp, &asn_length); if (bufp == NULL) return (NULL); if (asn_length != 0) { snmp_set_api_error(SNMPERR_ASN_DECODE); return (NULL); } *datalength -= (bufp - data); return (bufp + asn_length);}#endif/* * 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, int *datalength, u_char type) /* u_char *data; IN - pointer to start of object */ /* int *datalength; IN/OUT - # of valid bytes left in buf */ /* u_char type; IN - ASN type of object */{ /* * ASN.1 null ::= 0x05 0x00 */ return (asn_build_header_with_truth(data, datalength, type, 0, 1));}#if 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, int *datalength, u_char * type, u_char * string, int *strlength) /* u_char *data; IN - pointer to start of object */ /* int *datalength; IN/OUT - # of valid bytes left in buf */ /* u_char *type; OUT - asn type of object */ /* u_char *string; IN/OUT - pointer to start of output buf */ /* int *strlength; IN/OUT - size of output buffer */{ /* * bitstring ::= 0x03 asnlength unused {byte}* */ u_char *bufp = data; u_int asn_length; *type = *bufp++; bufp = asn_parse_length(bufp, &asn_length); if (bufp == NULL) return (NULL); if (asn_length + (bufp - data) > *datalength) { snmp_set_api_error(SNMPERR_ASN_DECODE); return (NULL); } if (asn_length > *strlength) { snmp_set_api_error(SNMPERR_ASN_DECODE); return (NULL); } if (asn_length < 1) { snmp_set_api_error(SNMPERR_ASN_DECODE); return (NULL); } if ((int) (*(char *) bufp) < 0 || (int) (*bufp) > 7) { snmp_set_api_error(SNMPERR_ASN_DECODE); return (NULL); } xmemcpy((char *) string, (char *) bufp, (int) 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, int *datalength, u_char type, u_char * string, int strlength) /* u_char *data; IN - pointer to start of object */ /* int *datalength; IN/OUT - # of valid bytes left in buf */ /* u_char type; IN - ASN type of string */ /* u_char *string; IN - pointer to start of input buffer */ /* int strlength; IN - size of input buffer */{ /* * ASN.1 bit string ::= 0x03 asnlength unused {byte}* */ if ((strlength < 1) || ((*(char *) string) < 0) || ((*string) > 7)) { snmp_set_api_error(SNMPERR_ASN_ENCODE); return (NULL); } data = asn_build_header_with_truth(data, datalength, type, strlength, 1); if (data == NULL) return (NULL); if (*datalength < strlength) { snmp_set_api_error(SNMPERR_ASN_ENCODE); return (NULL); } xmemcpy((char *) data, (char *) string, strlength); *datalength -= strlength; return (data + strlength);}#endif/* * To do: Write an asn_parse_exception function to go with the new * asn_build_exception function below so that the exceptional values can * be handled in input packets aswell as output ones. *//* * asn_build_exception - Builds an ASN exception 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. * * ASN.1 variable exception ::= 0x8i 0x00, where 'i' is one of these * exception identifiers: * 0 -- noSuchObject * 1 -- noSuchInstance * 2 -- endOfMibView */u_char *asn_build_exception(u_char * data, int *datalength, u_char type) /* u_char *data; IN - pointer to start of object */ /* int *datalength; IN/OUT - # of valid bytes left in buf */ /* u_char type; IN - ASN type of object */{ return (asn_build_header_with_truth(data, datalength, type, 0, 1));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -