mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
163 lines
6.3 KiB
V
163 lines
6.3 KiB
V
// Copyright (c) 2022, 2024 blackshirt. All rights reserved.
|
|
// Use of this source code is governed by a MIT License
|
|
// that can be found in the LICENSE file.
|
|
module asn1
|
|
|
|
struct TagCreation {
|
|
class TagClass
|
|
constructed bool
|
|
number int
|
|
err IError
|
|
}
|
|
|
|
fn test_tag_new_constructor() {
|
|
tags := [
|
|
TagCreation{.universal, false, 1, none},
|
|
TagCreation{.universal, true, 1, none},
|
|
// sequence should be constructed set
|
|
TagCreation{.universal, true, 16, none},
|
|
TagCreation{.universal, false, 16, error('For SEQUENCE(OF) or SET(OF) type, should be in constructed form')},
|
|
// set
|
|
TagCreation{.universal, true, 17, none},
|
|
TagCreation{.universal, false, 17, error('For SEQUENCE(OF) or SET(OF) type, should be in constructed form')},
|
|
//
|
|
TagCreation{.universal, false, 28, none},
|
|
TagCreation{.universal, false, 0x1f, none}, // 31
|
|
TagCreation{.universal, false, 0x7f, none},
|
|
TagCreation{.universal, false, 255, none}, // 0xff
|
|
TagCreation{.universal, true, 255, none}, // 0xff
|
|
TagCreation{.universal, true, 16380, error('Not a valid tag number for universal class=16380')},
|
|
// Context Specific should be in constructed form
|
|
TagCreation{.context_specific, true, 128, none}, // 0x80
|
|
TagCreation{.context_specific, false, 128, error('Context Specific should be in constructed form')}, // 0x80
|
|
// Others was as is
|
|
TagCreation{.private, false, 256, none},
|
|
TagCreation{.private, true, 16383, none},
|
|
TagCreation{.private, true, 16500, error('Unallowed tag number, 16500 exceed limit')},
|
|
TagCreation{.application, false, 16000, none},
|
|
TagCreation{.application, false, 16384, error('Unallowed tag number, 16384 exceed limit')},
|
|
TagCreation{.application, true, 65535, error('Unallowed tag number, 65535 exceed limit')},
|
|
]
|
|
for i, c in tags {
|
|
// creates tag with constructed bit set
|
|
t := Tag.new(c.class, c.constructed, c.number) or {
|
|
assert err == c.err
|
|
continue
|
|
}
|
|
assert t.tag_class() == c.class
|
|
assert t.is_constructed() == c.constructed
|
|
assert t.tag_number() == c.number
|
|
}
|
|
}
|
|
|
|
struct TagLengthTest {
|
|
class TagClass
|
|
number int
|
|
explength int
|
|
err IError
|
|
}
|
|
|
|
fn test_class_tag_length_handling() ! {
|
|
tags := [
|
|
TagLengthTest{.universal, 0, 1, none},
|
|
TagLengthTest{.universal, 1, 1, none},
|
|
TagLengthTest{.universal, 28, 1, none},
|
|
TagLengthTest{.universal, 0x1f, 2, none}, // 31
|
|
TagLengthTest{.universal, 0x7f, 2, none},
|
|
TagLengthTest{.context_specific, 128, 3, none}, // 0x80
|
|
TagLengthTest{.universal, 255, 3, none}, // 0xff
|
|
TagLengthTest{.private, 256, 3, error('Not a valid tag number for universal class=256')},
|
|
TagLengthTest{.universal, 16380, 3, error('Not a valid tag number for universal class=16380')},
|
|
TagLengthTest{.private, 16383, 3, none},
|
|
TagLengthTest{.application, 16384, 4, error('Unallowed tag number, 16384 exceed limit')},
|
|
TagLengthTest{.application, 65535, 4, error('Unallowed tag number, 65535 exceed limit')},
|
|
]
|
|
|
|
for i, c in tags {
|
|
// creates tag with constructed bit set
|
|
t := Tag.new(c.class, true, c.number) or {
|
|
assert err == c.err
|
|
continue
|
|
}
|
|
n := t.tag_size()
|
|
assert n == c.explength
|
|
}
|
|
}
|
|
|
|
struct TagDecodeTest {
|
|
bytes []u8
|
|
class TagClass
|
|
constructed bool
|
|
number int
|
|
lastpos int
|
|
err IError
|
|
}
|
|
|
|
fn test_tag_decode() ! {
|
|
data := [
|
|
// 0b1000_000 telss its class is .context_specific, but constructed bit was not set
|
|
TagDecodeTest{[u8(0x80), 0x01], .context_specific, false, 0, 1, none},
|
|
TagDecodeTest{[u8(0xa0), 0x01], .context_specific, true, 0, 1, none}, //{2, 0, 1, true}},
|
|
TagDecodeTest{[u8(0x02), 0x00], .universal, false, 2, 1, none},
|
|
TagDecodeTest{[u8(0xfe), 0x00], .private, true, 30, 1, none},
|
|
TagDecodeTest{[u8(0x1f), 0x1f, 0x00], .universal, false, 31, 2, none}, // high tag form
|
|
TagDecodeTest{[u8(0x1f), 0x81, 0x00, 0x00], .universal, false, 128, 3, none},
|
|
TagDecodeTest{[u8(0x1f), 0x81, 0x80, 0x01, 0x00], .universal, false, 16385, 4, error('Tag number: base 128 integer too large')}, // 1x128^2 + 0x128^1 + 1x128*0
|
|
TagDecodeTest{[u8(0x00), 0x81, 0x80], .universal, false, 0, 1, none},
|
|
TagDecodeTest{[u8(0x00), 0x83, 0x01, 0x00], .universal, false, 0, 1, none},
|
|
TagDecodeTest{[u8(0x1f), 0x85], .universal, false, 0, 1, error('Tag: truncated base 128 integer')},
|
|
TagDecodeTest{[u8(0x1f), 0x85, 0x81], .universal, false, 0, 0, error('Tag: truncated base 128 integer')},
|
|
TagDecodeTest{[u8(0x30), 0x80], .universal, true, 0x10, 1, none},
|
|
TagDecodeTest{[u8(0xa0), 0x82, 0x00, 0xff], .context_specific, true, 0, 1, none},
|
|
]
|
|
|
|
for i, c in data {
|
|
// dump(i)
|
|
tag, pos := Tag.decode(c.bytes) or {
|
|
assert err == c.err
|
|
continue
|
|
}
|
|
assert tag.class == c.class
|
|
assert tag.constructed == c.constructed
|
|
assert tag.number == c.number
|
|
assert pos == c.lastpos
|
|
}
|
|
}
|
|
|
|
struct TagNumberTest {
|
|
num int
|
|
class TagClass
|
|
constructed bool
|
|
exp []u8
|
|
err IError
|
|
}
|
|
|
|
fn test_serialize_tag() ! {
|
|
data := [
|
|
TagNumberTest{0, .universal, false, [u8(0x00)], none},
|
|
TagNumberTest{32, .universal, false, [u8(0x1f), 0x20], none}, // multibyte tag: 0x1f 0x20
|
|
TagNumberTest{255, .universal, false, [u8(0x1f), 0x81, 0x7f], none}, // multibyte tag: 0x1f 0x81 0x7f
|
|
TagNumberTest{0, .universal, true, [u8(0x20)], none}, // bits 6 set, 0010 0000 == 32
|
|
TagNumberTest{1, .universal, true, [u8(0x21)], none}, // bits 6 set, 0010 0001 == 31
|
|
TagNumberTest{32, .universal, true, [u8(0x3f), 0x20], none}, // multibyte tag: 00111111 0x20
|
|
TagNumberTest{32, .application, true, [u8(0x7f), 0x20], none}, // multibyte tag: 127 (01111111) 0x20
|
|
TagNumberTest{32, .context_specific, true, [u8(0xbf), 0x20], none}, // multibyte tag: 197 (10111111) 0x20
|
|
TagNumberTest{32, .private, true, [u8(0xff), 0x20], none}, // multibyte tag: 255 (11111111) 0x20
|
|
TagNumberTest{255, .context_specific, true, [u8(0xbf), 0x81, 0x7f], none}, // multibyte tag: 0xbf 0x81 0x7f
|
|
// private class 0xdf = 0b1101_1111
|
|
TagNumberTest{16383, .private, false, [u8(0xdf), 0xff, 0x7f], none}, // multibyte tag: 0x1f 0xff 0x7f
|
|
// overflow max_tag_value
|
|
TagNumberTest{16385, .context_specific, true, [u8(0x1f), 0xff, 0x7f], error('Unallowed tag number, 16385 exceed limit')}, // multibyte tag: 0x1f 0xff 0x7f
|
|
]
|
|
|
|
for i, c in data {
|
|
mut dst := []u8{}
|
|
tag := Tag.new(c.class, c.constructed, c.num) or {
|
|
assert err == c.err
|
|
continue
|
|
}
|
|
tag.encode(mut dst)!
|
|
assert dst == c.exp
|
|
}
|
|
}
|