asn1.cpp
来自「JdonFramework need above jdk 1.4.0 This」· C++ 代码 · 共 2,107 行 · 第 1/5 页
CPP
2,107 行
return NULL; // fixed memcpy((unsigned char *)data, string, strlength); *datalength -= strlength; return data + strlength;}/* * asn_parse_header - interprets the ID and length of the current 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 * in this object following the id and length. * * Returns a pointer to the first byte of the contents of this object. * Returns NULL on any error. */unsigned char *asn_parse_header( unsigned char *data, int *datalength, unsigned char *type){ unsigned char *bufp = data; register int header_len; unsigned long asn_length; /* this only works on data types < 30, i.e. no extension octets */ if (IS_EXTENSION_ID(*bufp)){ ASNERROR("can't process ID >= 30"); return NULL; } *type = *bufp; bufp = asn_parse_length(bufp + 1, &asn_length); if (bufp == NULL) return NULL; header_len = SAFE_INT_CAST(bufp - data); if ((unsigned long)(header_len + asn_length) > (unsigned long)*datalength){ ASNERROR("asn length too long"); return NULL; } *datalength = (int)asn_length; return bufp;}/* * asn_build_header - builds an ASN header for an object with the ID and * length specified. * On entry, datalength is input as the number of valid bytes following * "data". On exit, it is returned as the number of valid bytes * in this object following the id and length. * * This only works on data types < 30, i.e. no extension octets. * The maximum length is 0xFFFF; * * Returns a pointer to the first byte of the contents of this object. * Returns NULL on any error. */unsigned char * asn_build_header( unsigned char *data, int *datalength, unsigned char type, int length){ if (*datalength < 1) return NULL; *data++ = type; (*datalength)--; return asn_build_length(data, datalength, length);}/* * asn_build_sequence - builds an ASN header for a sequence with the ID and * length specified. * * This only works on data types < 30, i.e. no extension octets. * * Returns a pointer to the first byte of the contents of this object. * Returns NULL on any error. */unsigned char * asn_build_sequence( unsigned char *data, int *datalength, unsigned char type, int length){ unsigned char * data_with_length; if( *datalength < 2 ) /* need at least two octets for a sequence */ { ASNERROR( "build_sequence" ); return NULL; } *data++ = type; (*datalength)--; data_with_length = asn_build_length( data, datalength, length ); if( data_with_length == NULL ) { (*datalength)++; /* correct datalength to emulate old behavior of build_sequence */ return NULL; } return data_with_length;}/* * asn_parse_length - interprets the length of the current object. * On exit, length contains the value of this length field. * * Returns a pointer to the first byte after this length * field (aka: the start of the data field). * Returns NULL on any error. */unsigned char * asn_parse_length( unsigned char *data, unsigned long *length){ unsigned char lengthbyte = *data; *length = 0; if (lengthbyte & ASN_LONG_LEN){ lengthbyte &= ~ASN_LONG_LEN; /* turn MSb off */ if (lengthbyte == 0){ ASNERROR("We don't support indefinite lengths"); return NULL; } if (lengthbyte > sizeof(int)){ ASNERROR("we can't support data lengths that long"); return NULL; } // fixed memcpy((char *)length, (char *)data + 1, (int)lengthbyte); *length = ntohl(*length); // ntohl even on ALPHA (DEC/COMPAQ) 64bit platforms works on 32bit int, // whereas long is 64bit - therefore:#ifdef __osf__ *length >>= (8 * ((sizeof(int)) - lengthbyte));#else *length >>= (8 * ((sizeof(long)) - lengthbyte));#endif // check for length greater than 2^31 if (*length > 0x80000000ul) { ASNERROR("SNMP does not support data lengths > 2^31"); return NULL; } return data + lengthbyte + 1; } else { /* short asnlength */ *length = (long)lengthbyte; return data + 1; }}unsigned char *asn_build_length( unsigned char *data, int *datalength, int length){ unsigned char *start_data = data; /* no indefinite lengths sent */ if (length < 0x80){ if (*datalength < 1){ ASNERROR("build_length"); return NULL; } *data++ = (unsigned char)length; } else if (length <= 0xFF){ if (*datalength < 2){ ASNERROR("build_length"); return NULL; } *data++ = (unsigned char)(0x01 | ASN_LONG_LEN); *data++ = (unsigned char)length; } else if (length <= 0xFFFF) { /* 0xFF < length <= 0xFFFF */ if (*datalength < 3){ ASNERROR("build_length"); return NULL; } *data++ = (unsigned char)(0x02 | ASN_LONG_LEN); *data++ = (unsigned char)((length >> 8) & 0xFF); *data++ = (unsigned char)(length & 0xFF); } else if (length <= 0xFFFFFF) { /* 0xFF < length <= 0xFFFF */ if (*datalength < 4){ ASNERROR("build_length"); return NULL; } *data++ = (unsigned char)(0x03 | ASN_LONG_LEN); *data++ = (unsigned char)((length >> 16) & 0xFF); *data++ = (unsigned char)((length >> 8) & 0xFF); *data++ = (unsigned char)(length & 0xFF); } else { if (*datalength < 5){ ASNERROR("build_length"); return NULL; } *data++ = (unsigned char)(0x04 | ASN_LONG_LEN); *data++ = (unsigned char)((length >> 24) & 0xFF); *data++ = (unsigned char)((length >> 16) & 0xFF); *data++ = (unsigned char)((length >> 8) & 0xFF); *data++ = (unsigned char)(length & 0xFF); } *datalength -= SAFE_INT_CAST(data - start_data); return data;}/* * asn_parse_objid - pulls an object indentifier out of an ASN object identifier 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. * * "objid" is filled with the object identifier. * * 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. */unsigned char *asn_parse_objid( unsigned char *data, int *datalength, unsigned char *type, oid *objid, int *objidlength){ /* * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}* * subidentifier ::= {leadingbyte}* lastbyte * leadingbyte ::= 1 7bitvalue * lastbyte ::= 0 7bitvalue */ unsigned char *bufp = data; oid *oidp = objid + 1; unsigned long subidentifier; long length; unsigned long asn_length; *type = *bufp++; if (*type != 0x06) { ASNERROR("Wrong Type. Not an oid"); return NULL; } bufp = asn_parse_length(bufp, &asn_length); if (bufp == NULL) return NULL; if ((asn_length + (bufp - data)) > (unsigned long)(*datalength)){ ASNERROR("overflow of message"); return NULL; } *datalength -= (int)asn_length + SAFE_INT_CAST(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) + (*(unsigned char *)bufp & ~ASN_BIT8); length--; } while (*(unsigned char *)bufp++ & ASN_BIT8); /* last byte has high bit clear */ if (subidentifier > (unsigned long)MAX_SUBID){ ASNERROR("subidentifier too long"); 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 = (unsigned long)objid[1]; if (subidentifier == 0x2B){ objid[0] = 1; objid[1] = 3; } else { objid[1] = (unsigned char)(subidentifier % 40); objid[0] = (unsigned 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. */unsigned char *asn_build_objid( unsigned char *data, int *datalength, unsigned char type, oid *objid, int objidlength){ /* * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}* * subidentifier ::= {leadingbyte}* lastbyte * leadingbyte ::= 1 7bitvalue * lastbyte ::= 0 7bitvalue */ // F.Fock correct buffer size must be 5*8bit*MAX_OID_LEN unsigned char buf[MAX_OID_LEN*5]; unsigned char *bp = buf; oid *op = objid; int asnlength; unsigned long subid, mask, testmask; int bits, testbits; if (objidlength < 2){ *bp++ = 0; objidlength = 0; } else { *bp++ = (unsigned char) (op[1] + (op[0] * 40)); objidlength -= 2; op += 2; } while(objidlength-- > 0){ subid = *op++; if (subid < 127){ /* off by one? */ *bp++ = (unsigned char )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++ = (unsigned char)(((subid & mask) >> bits) | ASN_BIT8); } *bp++ = (unsigned char)(subid & mask); } } asnlength = SAFE_INT_CAST(bp - buf); data = asn_build_header(data, datalength, type, asnlength); if (data == NULL) return NULL; if (*datalength < asnlength) return NULL; // fixed memcpy((char *)data, (char *)buf, asnlength); *datalength -= asnlength; return data + asnlength;}/* * 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. */unsigned char *asn_parse_null(unsigned char *data, int *datalength, unsigned char *type){ /* * ASN.1 null ::= 0x05 0x00 */ unsigned char *bufp = data; unsigned long asn_length; *type = *bufp++; if (*type != 0x05) { ASNERROR("Wrong Type. Not a null"); return NULL; } bufp = asn_parse_length(bufp, &asn_length); if (bufp == NULL) return NULL; if (asn_length != 0){ ASNERROR("Malformed NULL"); return NULL; } *datalength -= SAFE_INT_CAST(bufp - data); 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. */unsigned char *asn_build_null( unsigned char *data, int *datalength, unsigned 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.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?