Added an option to try decoding unknown primitives as BER encoded data.

svn path=/trunk/; revision=31740
This commit is contained in:
Stig Bjørlykke 2010-01-30 17:44:45 +00:00
parent 469b2966f6
commit 8f5c4683ea
1 changed files with 57 additions and 24 deletions

View File

@ -92,6 +92,7 @@ static gint hf_ber_unknown_OID = -1;
static gint hf_ber_unknown_BOOLEAN = -1; static gint hf_ber_unknown_BOOLEAN = -1;
static gint hf_ber_unknown_OCTETSTRING = -1; static gint hf_ber_unknown_OCTETSTRING = -1;
static gint hf_ber_unknown_BER_OCTETSTRING = -1; static gint hf_ber_unknown_BER_OCTETSTRING = -1;
static gint hf_ber_unknown_BER_primitive = -1;
static gint hf_ber_unknown_GraphicString = -1; static gint hf_ber_unknown_GraphicString = -1;
static gint hf_ber_unknown_NumericString = -1; static gint hf_ber_unknown_NumericString = -1;
static gint hf_ber_unknown_PrintableString = -1; static gint hf_ber_unknown_PrintableString = -1;
@ -119,6 +120,7 @@ static gint hf_ber_octet_aligned = -1; /* OCTET_STRING */
static gint hf_ber_arbitrary = -1; /* BIT_STRING */ static gint hf_ber_arbitrary = -1; /* BIT_STRING */
static gint ett_ber_octet_string = -1; static gint ett_ber_octet_string = -1;
static gint ett_ber_primitive = -1;
static gint ett_ber_unknown = -1; static gint ett_ber_unknown = -1;
static gint ett_ber_SEQUENCE = -1; static gint ett_ber_SEQUENCE = -1;
static gint ett_ber_EXTERNAL = -1; static gint ett_ber_EXTERNAL = -1;
@ -126,6 +128,7 @@ static gint ett_ber_T_encoding = -1;
static gboolean show_internal_ber_fields = FALSE; static gboolean show_internal_ber_fields = FALSE;
static gboolean decode_octetstring_as_ber = FALSE; static gboolean decode_octetstring_as_ber = FALSE;
static gboolean decode_primitive_as_ber = FALSE;
static gboolean decode_unexpected = FALSE; static gboolean decode_unexpected = FALSE;
static gchar *decode_as_syntax = NULL; static gchar *decode_as_syntax = NULL;
@ -425,7 +428,7 @@ int dissect_unknown_ber(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tre
proto_tree *next_tree=NULL; proto_tree *next_tree=NULL;
guint8 c; guint8 c;
guint32 i; guint32 i;
gboolean is_printable; gboolean is_printable, is_decoded_as;
proto_item *pi, *cause; proto_item *pi, *cause;
asn1_ctx_t asn1_ctx; asn1_ctx_t asn1_ctx;
@ -474,6 +477,7 @@ int dissect_unknown_ber(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tre
offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_GraphicString, NULL); offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_GraphicString, NULL);
break; break;
case BER_UNI_TAG_OCTETSTRING: case BER_UNI_TAG_OCTETSTRING:
is_decoded_as = FALSE;
if (decode_octetstring_as_ber) { if (decode_octetstring_as_ber) {
int ber_offset; int ber_offset;
guint32 ber_len; guint32 ber_len;
@ -483,6 +487,7 @@ int dissect_unknown_ber(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tre
/* Decoded a constructed ASN.1 tag with a length indicating this /* Decoded a constructed ASN.1 tag with a length indicating this
* could be BER encoded data. Try dissecting as unknown BER. * could be BER encoded data. Try dissecting as unknown BER.
*/ */
is_decoded_as = TRUE;
if (show_internal_ber_fields) { if (show_internal_ber_fields) {
offset = dissect_ber_identifier(pinfo, tree, tvb, start_offset, NULL, NULL, NULL); offset = dissect_ber_identifier(pinfo, tree, tvb, start_offset, NULL, NULL, NULL);
offset = dissect_ber_length(pinfo, tree, tvb, offset, NULL, NULL); offset = dissect_ber_length(pinfo, tree, tvb, offset, NULL, NULL);
@ -490,10 +495,9 @@ int dissect_unknown_ber(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tre
item = proto_tree_add_item(tree, hf_ber_unknown_BER_OCTETSTRING, tvb, offset, len, FALSE); item = proto_tree_add_item(tree, hf_ber_unknown_BER_OCTETSTRING, tvb, offset, len, FALSE);
next_tree = proto_item_add_subtree(item, ett_ber_octet_string); next_tree = proto_item_add_subtree(item, ett_ber_octet_string);
offset = dissect_unknown_ber(pinfo, tvb, offset, next_tree); offset = dissect_unknown_ber(pinfo, tvb, offset, next_tree);
} else {
offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OCTETSTRING, NULL);
} }
} else { }
if (!is_decoded_as) {
offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OCTETSTRING, NULL); offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, start_offset, hf_ber_unknown_OCTETSTRING, NULL);
} }
break; break;
@ -552,35 +556,55 @@ int dissect_unknown_ber(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tre
case BER_CLASS_CON: case BER_CLASS_CON:
case BER_CLASS_PRI: case BER_CLASS_PRI:
default: default:
/* we can't dissect this directly as it is specific */
/* we dissect again if show_internal_ber_fields is set */ /* we dissect again if show_internal_ber_fields is set */
if(show_internal_ber_fields) { if(show_internal_ber_fields) {
offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &class, &pc, &tag); offset=dissect_ber_identifier(pinfo, tree, tvb, start_offset, &class, &pc, &tag);
offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL);
} }
pi = proto_tree_add_text(tree, tvb, offset, len, "[%s %d] ", val_to_str(class,ber_class_codes,"Unknown"), tag); /* we can't dissect this directly as it is specific */
/* we may want to do better and show the bytes */ pi = proto_tree_add_none_format(tree, hf_ber_unknown_BER_primitive, tvb, offset, len,
is_printable = TRUE; "[%s %d] ", val_to_str(class,ber_class_codes,"Unknown"), tag);
for(i=0;i<len;i++){
c = tvb_get_guint8(tvb, offset+i);
if(is_printable && !g_ascii_isprint(c)) is_decoded_as = FALSE;
is_printable=FALSE; if (decode_primitive_as_ber) {
int ber_offset;
proto_item_append_text(pi,"%02x",c); guint32 ber_len;
} ber_offset = get_ber_identifier(tvb, offset, NULL, &pc, NULL);
ber_offset = get_ber_length(tvb, ber_offset, &ber_len, NULL);
if(is_printable) { /* give a nicer representation if it looks like a string */ if (pc && (ber_len > 0) && (ber_len + (ber_offset - offset) == len)) {
proto_item_append_text(pi," ("); /* Decoded a constructed ASN.1 tag with a length indicating this
for(i=0;i<len;i++){ * could be BER encoded data. Try dissecting as unknown BER.
proto_item_append_text(pi,"%c",tvb_get_guint8(tvb, offset+i)); */
is_decoded_as = TRUE;
proto_item_append_text (pi, "[BER encoded]");
next_tree = proto_item_add_subtree(pi, ett_ber_primitive);
offset = dissect_unknown_ber(pinfo, tvb, offset, next_tree);
} }
proto_item_append_text(pi,")");
} }
offset += len; if (!is_decoded_as && len) {
/* we may want to do better and show the bytes */
is_printable = TRUE;
for(i=0;i<len;i++){
c = tvb_get_guint8(tvb, offset+i);
if(is_printable && !g_ascii_isprint(c))
is_printable=FALSE;
proto_item_append_text(pi,"%02x",c);
}
if(is_printable) { /* give a nicer representation if it looks like a string */
proto_item_append_text(pi," (");
for(i=0;i<len;i++){
proto_item_append_text(pi,"%c",tvb_get_guint8(tvb, offset+i));
}
proto_item_append_text(pi,")");
}
offset += len;
}
break; break;
} }
break; break;
@ -4372,6 +4396,9 @@ proto_register_ber(void)
{ &hf_ber_unknown_BER_OCTETSTRING, { { &hf_ber_unknown_BER_OCTETSTRING, {
"OCTETSTRING [BER encoded]", "ber.unknown.OCTETSTRING", FT_NONE, BASE_NONE, "OCTETSTRING [BER encoded]", "ber.unknown.OCTETSTRING", FT_NONE, BASE_NONE,
NULL, 0, "This is an BER encoded OCTETSTRING", HFILL }}, NULL, 0, "This is an BER encoded OCTETSTRING", HFILL }},
{ &hf_ber_unknown_BER_primitive, {
"Primitive [BER encoded]", "ber.unknown.primitive", FT_NONE, BASE_NONE,
NULL, 0, "This is a BER encoded Primitive", HFILL }},
{ &hf_ber_unknown_OID, { { &hf_ber_unknown_OID, {
"OID", "ber.unknown.OID", FT_OID, BASE_NONE, "OID", "ber.unknown.OID", FT_OID, BASE_NONE,
NULL, 0, "This is an unknown Object Identifier", HFILL }}, NULL, 0, "This is an unknown Object Identifier", HFILL }},
@ -4465,6 +4492,7 @@ proto_register_ber(void)
static gint *ett[] = { static gint *ett[] = {
&ett_ber_octet_string, &ett_ber_octet_string,
&ett_ber_primitive,
&ett_ber_unknown, &ett_ber_unknown,
&ett_ber_SEQUENCE, &ett_ber_SEQUENCE,
&ett_ber_EXTERNAL, &ett_ber_EXTERNAL,
@ -4473,10 +4501,11 @@ proto_register_ber(void)
module_t *ber_module; module_t *ber_module;
proto_ber = proto_register_protocol("Basic Encoding Rules (ASN.1 X.690)", "BER", "ber"); proto_ber = proto_register_protocol("Basic Encoding Rules (ASN.1 X.690)", "BER", "ber");
register_dissector ("ber", dissect_ber, proto_ber);
proto_register_field_array(proto_ber, hf, array_length(hf)); proto_register_field_array(proto_ber, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett)); proto_register_subtree_array(ett, array_length(ett));
proto_set_cant_toggle(proto_ber); proto_set_cant_toggle(proto_ber);
/* Register preferences */ /* Register preferences */
ber_module = prefs_register_protocol(proto_ber, NULL); ber_module = prefs_register_protocol(proto_ber, NULL);
@ -4492,6 +4521,10 @@ proto_register_ber(void)
"Decode OCTET STRING as BER encoded data", "Decode OCTET STRING as BER encoded data",
"Whether the dissector should try decoding OCTET STRINGs as" "Whether the dissector should try decoding OCTET STRINGs as"
" constructed ASN.1 BER encoded data", &decode_octetstring_as_ber); " constructed ASN.1 BER encoded data", &decode_octetstring_as_ber);
prefs_register_bool_preference(ber_module, "decode_primitive",
"Decode Primitive as BER encoded data",
"Whether the dissector should try decoding unknown primitive as"
" constructed ASN.1 BER encoded data", &decode_primitive_as_ber);
ber_oid_dissector_table = register_dissector_table("ber.oid", "BER OID Dissectors", FT_STRING, BASE_NONE); ber_oid_dissector_table = register_dissector_table("ber.oid", "BER OID Dissectors", FT_STRING, BASE_NONE);
ber_syntax_dissector_table = register_dissector_table("ber.syntax", "BER Syntax Dissectors", FT_STRING, BASE_NONE); ber_syntax_dissector_table = register_dissector_table("ber.syntax", "BER Syntax Dissectors", FT_STRING, BASE_NONE);