per: Implement UTF8String properly

UTF8String is not a known-multiplier character string, since the
characters are variable width. That means that a size constraint
in characters doesn't correspond to a fixed number of octets, and
thus that constraints are never PER-visible. (X.691 27.6) That
includes size constraints, extensions, permitted alphabets, etc.
The length determinant is thus the unconstrained type, and always
at least an entire octet instead of ever taking up a smaller
number of bits.

Extract the string as UTF-8 after aligning as necessary, which
will deal with illegal encodings.

Fix #18600.
This commit is contained in:
John Thacker 2022-11-08 07:01:53 -05:00
parent c2b59567d3
commit 526ccef5f4
1 changed files with 36 additions and 3 deletions

View File

@ -908,10 +908,43 @@ dissect_per_BMPString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tre
return offset;
}
guint32
dissect_per_UTF8String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_)
dissect_per_UTF8String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len _U_, int max_len _U_, gboolean has_extension _U_)
{
offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree,
hf_index, min_len, max_len, has_extension, 0, 255, NULL, 256, NULL);
tvbuff_t *val_tvb;
guint32 length;
/* UTF8String is not a known-multiplier character string (UTF8
* characters are variable width.) Hence subclause 27.6 applies,
* and "constraints are never PER-visible, and the type can never
* be extensible for PER encoding."
*/
/* 27.6.3 unconstrained length determinant with "n" in octets */
offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_octet_string_length, &length, NULL);
if(length){
/* Unnecessary because the length determinant is aligned. */
if(actx->aligned) {
BYTE_ALIGN_OFFSET(offset);
}
val_tvb = tvb_new_octet_aligned(tvb, offset, length * 8);
/* Add new data source if the offset was unaligned */
if ((offset & 7) != 0) {
add_new_data_source(actx->pinfo, val_tvb, "Unaligned UTF8String");
}
proto_tree_add_item(tree, hf_index, val_tvb, 0, length, ENC_UTF_8);
} else {
/* tvb_new_octet_aligned doesn't like zero length.
* length zero indicates a present but empty string, so add it
*/
proto_tree_add_item(tree, hf_index, tvb, (offset-1)>>3, length, ENC_UTF_8);
}
offset+=(length<<3);
return offset;
}