v2 / vlib / x / encoding / asn1 / public_api_test.v
80 lines · 63 sloc · 2.3 KB · fdc49dc51a0d7e83abd5b383afaaab3f2793f2cf
Raw
1import x.encoding.asn1
2
3// This example test taken from https://en.wikipedia.org/wiki/ASN.1#Example_encoded_in_DER
4// for testing public api of the `x.encoding.asn1` module.
5
6// FooQuestion ::= SEQUENCE {
7// trackingNumber INTEGER(0..199),
8// question IA5String
9// }
10
11// Instance of FooQuestion
12// myQuestion FooQuestion ::= {
13// trackingNumber 5,
14// question "Anybody there?"
15// }
16
17// Below is the data structure shown above as myQuestion encoded in DER format
18// (all numbers are in hexadecimal):
19// 30 13 02 01 05 16 0e 41 6e 79 62 6f 64 79 20 74 68 65 72 65 3f
20
21// Above schema can be represented in v struct,
22struct FooQuestion {
23 tracking_number asn1.Integer
24 question asn1.IA5String
25}
26
27// To be supported as an Element by this module, your FooQuestion should fullfills
28// required method of Element interface by providing `tag()` and `payload()` methods.
29fn (foo FooQuestion) tag() asn1.Tag {
30 return asn1.default_sequence_tag
31}
32
33fn (foo FooQuestion) payload() ![]u8 {
34 mut out := []u8{}
35
36 out << asn1.encode(foo.tracking_number)!
37 out << asn1.encode(foo.question)!
38
39 return out
40}
41
42// FooQuestion.decode is a routine decoder from bytes into FooQuestion.
43fn FooQuestion.decode(bytes []u8) !FooQuestion {
44 // decode the bytes, and check for sequence tag
45 elem := asn1.decode(bytes)!
46 assert elem.tag().equal(asn1.default_sequence_tag)
47
48 // turn into Sequence
49 seq := elem.into_object[asn1.Sequence]()!
50 // get the fields, ie, arrays of Element
51 fields := seq.fields()
52
53 // turns the every sequence's fields into desired object
54 trk_num := fields[0].into_object[asn1.Integer]()!
55 question := fields[1].into_object[asn1.IA5String]()!
56
57 foo := FooQuestion{
58 tracking_number: trk_num
59 question: question
60 }
61 return foo
62}
63
64fn test_asn1_public_api_usage() ! {
65 expected_foo := [u8(0x30), 0x13, 0x02, 0x01, 0x05, 0x16, 0x0e, 0x41, 0x6e, 0x79, 0x62, 0x6f,
66 0x64, 0x79, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x3f]
67
68 foo_question := FooQuestion{
69 tracking_number: asn1.Integer.from_int(5)
70 question: asn1.IA5String.new('Anybody there?')!
71 }
72
73 foo_encoded := asn1.encode(foo_question)!
74 assert foo_encoded == expected_foo
75
76 // decode back
77 foo_decoded := FooQuestion.decode(expected_foo)!
78 assert foo_decoded.tracking_number.as_i64()! == 5
79 assert foo_decoded.question.value == 'Anybody there?'
80}
81