--- Convert-BER-XS/XS.xs 2019/04/19 16:19:36 1.1 +++ Convert-BER-XS/XS.xs 2019/04/19 16:49:02 1.2 @@ -12,7 +12,12 @@ ASN_OCTET_STRING = 0x04, ASN_NULL = 0x05, ASN_OBJECT_IDENTIFIER = 0x06, + ASN_REAL = 0x09, //X + ASN_ENUMERATED = 0x0a, //X ASN_SEQUENCE = 0x10, + ASN_SET = 0x11, //X + ASN_UTC_TIME = 0x17, //X + ASN_GENERAL_TIME = 0x18, //X ASN_TAG_BER = 0x1f, ASN_TAG_MASK = 0x1f, @@ -29,7 +34,7 @@ ASN_CLASS_MASK = 0xc0, ASN_CLASS_SHIFT = 6, - // ASN_APPLICATION + // ASN_APPLICATION SNMP ASN_IPADDRESS = 0x00, ASN_COUNTER32 = 0x01, ASN_UNSIGNED32 = 0x02, @@ -88,8 +93,11 @@ return 1; } +// get_* functions fetch something from the buffer +// decode_* functions use get_* fun ctions to decode ber values + static U8 * -getn (int count, const U8 *errres) +get_n (int count, const U8 *errres) { if (!need (count)) return (U8 *)errres; @@ -103,7 +111,7 @@ } static U8 -get8 (void) +get_u8 (void) { if (rem <= 0) { @@ -116,13 +124,13 @@ } static U32 -getb (void) +get_ber (void) { U32 res = 0; for (;;) { - U8 c = get8 (); + U8 c = get_u8 (); res = (res << 7) | (c & 0x7f); if (!(c & 0x80)) @@ -131,9 +139,9 @@ } static U32 -process_length (void) +get_length (void) { - U32 res = get8 (); + U32 res = get_u8 (); if (res & 0x80) { @@ -150,10 +158,10 @@ error ("ASN.1 length too long"); return 0; - case 4: res = (res << 8) | get8 (); - case 3: res = (res << 8) | get8 (); - case 2: res = (res << 8) | get8 (); - case 1: res = (res << 8) | get8 (); + case 4: res = (res << 8) | get_u8 (); + case 3: res = (res << 8) | get_u8 (); + case 2: res = (res << 8) | get_u8 (); + case 1: res = (res << 8) | get_u8 (); } } @@ -161,9 +169,9 @@ } static U32 -process_integer32 (void) +get_integer32 (void) { - U32 length = process_length (); + U32 length = get_length (); if (length <= 0) { @@ -171,7 +179,7 @@ return 0; } - U8 *data = getn (length, 0); + U8 *data = get_n (length, 0); if (!data) return 0; @@ -191,23 +199,23 @@ } static SV * -process_integer32_sv (void) +decode_integer32 (void) { - return newSViv ((I32)process_integer32 ()); + return newSViv ((I32)get_integer32 ()); } static SV * -process_unsigned32_sv (void) +decode_unsigned32 (void) { - return newSVuv ((U32)process_integer32 ()); + return newSVuv ((U32)get_integer32 ()); } #if IVSIZE >= 8 static U64TYPE -process_integer64 (void) +get_integer64 (void) { - U32 length = process_length (); + U32 length = get_length (); if (length <= 0) { @@ -215,7 +223,7 @@ return 0; } - U8 *data = getn (length, 0); + U8 *data = get_n (length, 0); if (!data) return 0; @@ -235,25 +243,25 @@ } static SV * -process_integer64_sv (void) +decode_integer64 (void) { - return newSViv ((I64TYPE)process_integer64 ()); + return newSViv ((I64TYPE)get_integer64 ()); } static SV * -process_unsigned64_sv (void) +decode_unsigned64 (void) { - return newSVuv ((U64TYPE)process_integer64 ()); + return newSVuv ((U64TYPE)get_integer64 ()); } #endif static SV * -process_octet_string_sv (void) +decode_octet_string (void) { - U32 length = process_length (); + U32 length = get_length (); - U8 *data = getn (length, 0); + U8 *data = get_n (length, 0); if (!data) { error ("OCTET STRING too long"); @@ -263,6 +271,7 @@ return newSVpvn (data, length); } +// gelper for decode_object_identifier static char * write_uv (char *buf, U32 u) { @@ -293,9 +302,9 @@ } static SV * -process_object_identifier_sv (void) +decode_object_identifier (void) { - U32 length = process_length (); + U32 length = get_length (); if (length <= 0) { @@ -304,7 +313,7 @@ } U8 *end = cur + length; - U32 w = getb (); + U32 w = get_ber (); static char oid[MAX_OID_STRLEN]; // must be static char *app = oid; @@ -316,7 +325,7 @@ // we assume an oid component is never > 64 bytes while (cur < end && oid + sizeof (oid) - app > 64) { - w = getb (); + w = get_ber (); *app++ = '.'; app = write_uv (app, w); } @@ -325,9 +334,9 @@ } static SV * -ber_decode () +decode_ber () { - int identifier = get8 (); + int identifier = get_u8 (); SV *res; @@ -336,19 +345,19 @@ int tag = identifier & ASN_TAG_MASK; if (tag == ASN_TAG_BER) - tag = getb (); + tag = get_ber (); if (tag == ASN_TAG_BER) - tag = getb (); + tag = get_ber (); if (constructed) { - U32 len = process_length (); + U32 len = get_length (); U32 seqend = (cur - buf) + len; AV *av = (AV *)sv_2mortal ((SV *)newAV ()); while (cur < buf + seqend) - av_push (av, ber_decode ()); + av_push (av, decode_ber ()); if (cur > buf + seqend) croak ("constructed type %02x overflow (%x %x)\n", identifier, cur - buf, seqend); @@ -363,33 +372,33 @@ break; case ASN_OBJECT_IDENTIFIER: - res = process_object_identifier_sv (); + res = decode_object_identifier (); break; case ASN_INTEGER32: - res = process_integer32_sv (); + res = decode_integer32 (); break; case ASN_APPLICATION | ASN_UNSIGNED32: case ASN_APPLICATION | ASN_COUNTER32: case ASN_APPLICATION | ASN_TIMETICKS: - res = process_unsigned32_sv (); + res = decode_unsigned32 (); break; #if 0 // handled by default case case ASN_OCTET_STRING: case ASN_APPLICATION | ASN_IPADDRESS: case ASN_APPLICATION | ASN_OPAQUE: - res = process_octet_string_sv (); + res = decode_octet_string (); break; #endif case ASN_APPLICATION | ASN_COUNTER64: - res = process_integer64_sv (); + res = decode_integer64 (); break; default: - res = process_octet_string_sv (); + res = decode_octet_string (); break; } @@ -456,7 +465,7 @@ cur = buf; rem = len; - RETVAL = ber_decode (); + RETVAL = decode_ber (); } OUTPUT: RETVAL