blob: 03b1fc9e7a168014545c7a2f26a4b25d4cd2e0f3 [file] [log] [blame]
vlme18adea2004-06-03 03:49:45 +00001#LyX 1.3 created this file. For more info see http://www.lyx.org/
2\lyxformat 221
3\textclass book
4\language english
5\inputencoding latin1
6\fontscheme ae
7\graphics default
8\paperfontsize default
9\spacing single
10\papersize Default
11\paperpackage a4
12\use_geometry 0
13\use_amsmath 0
14\use_natbib 0
15\use_numerical_citations 0
16\paperorientation portrait
17\secnumdepth 3
18\tocdepth 3
19\paragraph_separation indent
20\defskip medskip
21\quotes_language swedish
22\quotes_times 2
23\papercolumns 1
24\papersides 1
25\paperpagestyle default
26
27\layout Title
28
vlmcaba97b2004-08-07 05:00:07 +000029Using the Free ASN.1 Compiler
vlme18adea2004-06-03 03:49:45 +000030\layout Author
31
32Lev Walkin <
33\begin_inset LatexCommand \url{vlm@lionet.info}
34
35\end_inset
36
37>
38\layout Standard
39
40
41\begin_inset LatexCommand \tableofcontents{}
42
43\end_inset
44
45
vlmcaba97b2004-08-07 05:00:07 +000046\layout Part
47
48ASN.1 Basics
vlme18adea2004-06-03 03:49:45 +000049\layout Chapter
50
vlmcaba97b2004-08-07 05:00:07 +000051Abstract Syntax Notation: ASN.1
vlme18adea2004-06-03 03:49:45 +000052\layout Standard
53
54
55\emph on
56This chapter defines some basic ASN.1 concepts and describes several most
57 widely used types.
58 It is by no means an authoritative or complete reference.
59 For more complete ASN.1 description, please refer to Olivier Dubuisson's
60 book
61\begin_inset LatexCommand \cite{Dub00}
62
63\end_inset
64
vlmcaba97b2004-08-07 05:00:07 +000065 or the ASN.1 body of standards itself
vlme18adea2004-06-03 03:49:45 +000066\begin_inset LatexCommand \cite{ITU-T/ASN.1}
67
68\end_inset
69
70.
71\layout Standard
72
73The Abstract Syntax Notation One is used to formally describe the semantics
74 of data transmitted across the network.
75 Two communicating parties may have different formats of their native data
76 types (i.e.
77 number of bits in the integer type), thus it is important to have a way
78 to describe the data in a manner which is independent from the particular
79 machine's representation.
80 The ASN.1 specifications is used to achieve one or more of the following:
81\layout Itemize
82
83The specification expressed in the ASN.1 notation is a formal and precise
84 way to communicate the data semantics to human readers;
85\layout Itemize
86
87The ASN.1 specifications may be used as input for automatic compilers which
88 produce the code for some target language (C, C++, Java, etc) to encode
89 and decode the data according to some encoding rules (which are also defined
90 by the ASN.1 standard).
91\layout Standard
92
93Consider the following example:
94\layout LyX-Code
95
96Rectangle ::= SEQUENCE {
97\layout LyX-Code
98
99 height INTEGER,
100\layout LyX-Code
101
102 width INTEGER
103\layout LyX-Code
104
105}
106\layout Standard
107
108This ASN.1 specification describes a constructed type,
109\emph on
110Rectangle
111\emph default
112, containing two integer fields.
113 This specification may tell the reader that there is this kind of data
114 structure and that some entity may be prepared to send or receive it.
115 The question on
116\emph on
117how
118\emph default
119 that entity is going to send or receive the
120\emph on
121encoded data
122\emph default
123 is outside the scope of ASN.1.
124 For example, this data structure may be encoded according to some encoding
125 rules and sent to the destination using the TCP protocol.
126 The ASN.1 specifies several ways of encoding (or
127\begin_inset Quotes sld
128\end_inset
129
130serializing
131\begin_inset Quotes srd
132\end_inset
133
134, or
135\begin_inset Quotes sld
136\end_inset
137
138marshaling
139\begin_inset Quotes srd
140\end_inset
141
142) the data: BER, CER, DER and XER, some of them which will be described
143 later.
144\layout Standard
145
146The complete specification must be wrapped in a module, which looks like
147 this:
148\layout LyX-Code
149
150UsageExampleModule1
151\layout LyX-Code
152
153 { iso org(3) dod(6) internet(1) private(4)
154\layout LyX-Code
155
156 enterprise(1) spelio(9363) software(1)
157\layout LyX-Code
158
159 asn1c(5) docs(2) usage(1) 1 }
160\layout LyX-Code
161
162 AUTOMATIC TAGS DEFINITIONS ::=
163\layout LyX-Code
164
165BEGIN
166\layout LyX-Code
167
168
169\layout LyX-Code
170
171-- This is a comment which describes nothing.
172\layout LyX-Code
173
174Rectangle ::= SEQUENCE {
175\layout LyX-Code
176
177 height INTEGER, -- Height of the rectangle
178\layout LyX-Code
179
180 width INTEGER, -- Width of the rectangle
181\layout LyX-Code
182
183}
184\layout LyX-Code
185
186
187\layout LyX-Code
188
189END
190\layout Standard
191
192The module header consists of module name (UsageExampleModule1), the module
193 object identifier ({...}), some flags (AUTOMATIC TAGS) and
194\begin_inset Quotes sld
195\end_inset
196
197DEFINITIONS ::= BEGIN
198\begin_inset Quotes srd
199\end_inset
200
201.
202 The module ends with an
203\begin_inset Quotes sld
204\end_inset
205
206END
207\begin_inset Quotes srd
208\end_inset
209
210 statement.
211\layout Section
212
213Some of the ASN.1 Basic Types
214\layout Subsection
215
216The BOOLEAN type
217\layout Standard
218
219The BOOLEAN type models the simple binary TRUE/FALSE, YES/NO, ON/OFF or
220 a similar kind of two-way choice.
221\layout Subsection
222
223The INTEGER type
224\layout Standard
225
226The INTEGER type is a signed natural number type without any restrictions
227 on its size.
228 If the automatic checking on INTEGER value bounds are necessary, the subtype
229 constraints must be used.
230\layout LyX-Code
231
232SimpleInteger ::= INTEGER
233\layout LyX-Code
234
235-- An integer with a very limited range
236\layout LyX-Code
237
238SmallInt ::= INTEGER (0..127)
239\layout LyX-Code
240
241-- Integer, negative
242\layout LyX-Code
243
244NegativeInt ::= INTEGER (MIN..0)
245\layout Subsection
246
247The ENUMERATED type
248\layout Standard
249
250The ENUMERATED type is semantically equivalent to the INTEGER type with
251 some integer values explicitly named.
252\layout LyX-Code
253
254FruitId ::= ENUMERATED { apple(1), orange(2) }
255\layout LyX-Code
256
257-- The numbers in braces are optional,
258\layout LyX-Code
259
260-- the enumeration may be performed
261\layout LyX-Code
262
263-- automatically by the compiler
264\layout LyX-Code
265
266ComputerOSType ::= ENUMERATED {
267\layout LyX-Code
268
269 FreeBSD, -- will be 0
270\layout LyX-Code
271
272 Windows, -- will be 1
273\layout LyX-Code
274
275 Solaris(5), -- will remain 5
276\layout LyX-Code
277
278 Linux, -- will be 6
279\layout LyX-Code
280
281 MacOS -- will be 7
282\layout LyX-Code
283
284}
285\layout Subsection
286
287The OCTET STRING type
288\layout Standard
289
290This type models the sequence of 8-bit bytes.
291 This may be used to transmit some opaque data or data serialized by other
292 types of encoders (i.e.
293 video file, photo picture, etc).
294\layout Subsection
295
296The OBJECT IDENTIFIER type
297\layout Standard
298
299The OBJECT IDENTIFIER is used to represent the unique identifier of any
300 object, starting from the very root of the registration tree.
301 If your organization needs to uniquely identify something (a router, a
302 room, a person, a standard, or whatever), you are encouraged to get your
303 own identification subtree at
304\begin_inset LatexCommand \htmlurl{http://www.iana.org/protocols/forms.htm}
305
306\end_inset
307
308.
309\layout Standard
310
311For example, the very first ASN.1 module in this document has the following
312 OBJECT IDENTIFIER: 1 3 6 1 4 1 9363 1 5 2 1 1.
313\layout LyX-Code
314
315ExampleOID ::= OBJECT IDENTIFIER
316\layout LyX-Code
317
318usageExampleModule1-oid ExampleOID
319\layout LyX-Code
320
321 ::= { 1 3 6 1 4 1 9363 1 5 2 1 1 }
322\layout LyX-Code
323
324-- An identifier of the Internet.
325\layout LyX-Code
326
327internet-id OBJECT IDENTIFIER
328\layout LyX-Code
329
330 ::= { iso(1) identified-organization(3)
331\layout LyX-Code
332
333 dod(6) internet(1) }
334\layout Standard
335
336As you see, names are optional.
337\layout Subsection
338
339The RELATIVE-OID type
340\layout Standard
341
342The RELATIVE-OID type has the semantics of a subtree of an OBJECT IDENTIFIER.
343 There may be no need to repeat the whole sequence of numbers from the root
344 of the registration tree where the only thing of interest is some of the
345 tree's subsequence.
346\layout LyX-Code
347
348this-document RELATIVE-OID ::= { docs(2) usage(1) }
349\layout LyX-Code
350
351this-example RELATIVE-OID ::= {
352\layout LyX-Code
353
354 this-document assorted-examples(0) this-example(1) }
355\layout Section
356
357Some of the ASN.1 String Types
358\layout Subsection
359
360The IA5String type
361\layout Standard
362
363This is essentially the ASCII, with 128 character codes available (7 lower
364 bits of 8-bit byte).
365\layout Subsection
366
367The UTF8String type
368\layout Standard
369
370This is the character string which encodes the full Unicode range (4 bytes)
371 using multibyte character sequences.
372\layout Subsection
373
374The NumericString type
375\layout Standard
376
377This type represents the character string with the alphabet consisting of
378 numbers (
379\begin_inset Quotes sld
380\end_inset
381
3820
383\begin_inset Quotes srd
384\end_inset
385
386 to
387\begin_inset Quotes sld
388\end_inset
389
3909
391\begin_inset Quotes srd
392\end_inset
393
394) and a space.
395\layout Subsection
396
397The PrintableString type
398\layout Standard
399
400The character string with the following alphabet: space,
401\begin_inset Quotes sld
402\end_inset
403
404
405\series bold
406'
407\series default
408
409\begin_inset Quotes srd
410\end_inset
411
412 (single quote),
413\begin_inset Quotes sld
414\end_inset
415
416
417\series bold
418(
419\series default
420
421\begin_inset Quotes sld
422\end_inset
423
424,
425\begin_inset Quotes sld
426\end_inset
427
428
429\series bold
430)
431\series default
432
433\begin_inset Quotes srd
434\end_inset
435
436,
437\begin_inset Quotes sld
438\end_inset
439
440
441\series bold
442+
443\series default
444
445\begin_inset Quotes srd
446\end_inset
447
448,
449\begin_inset Quotes sld
450\end_inset
451
452,
453\begin_inset Quotes srd
454\end_inset
455
456 (comma),
457\begin_inset Quotes sld
458\end_inset
459
460
461\series bold
462-
463\series default
464
465\begin_inset Quotes srd
466\end_inset
467
468,
469\begin_inset Quotes sld
470\end_inset
471
472
473\series bold
474.
475\series default
476
477\begin_inset Quotes srd
478\end_inset
479
480,
481\begin_inset Quotes sld
482\end_inset
483
484
485\series bold
486/
487\series default
488
489\begin_inset Quotes srd
490\end_inset
491
492, digits (
493\begin_inset Quotes sld
494\end_inset
495
4960
497\begin_inset Quotes srd
498\end_inset
499
500 to
501\begin_inset Quotes sld
502\end_inset
503
5049
505\begin_inset Quotes srd
506\end_inset
507
508),
509\begin_inset Quotes sld
510\end_inset
511
512
513\series bold
514:
515\series default
516
517\begin_inset Quotes srd
518\end_inset
519
520,
521\begin_inset Quotes sld
522\end_inset
523
524
525\series bold
526=
527\series default
528
529\begin_inset Quotes srd
530\end_inset
531
532,
533\begin_inset Quotes sld
534\end_inset
535
536
537\series bold
538?
539\series default
540
541\begin_inset Quotes srd
542\end_inset
543
544, upper-case and lower-case letters (
545\begin_inset Quotes sld
546\end_inset
547
548A
549\begin_inset Quotes srd
550\end_inset
551
552 to
553\begin_inset Quotes sld
554\end_inset
555
556Z
557\begin_inset Quotes srd
558\end_inset
559
560 and
561\begin_inset Quotes sld
562\end_inset
563
564a
565\begin_inset Quotes srd
566\end_inset
567
568 to
569\begin_inset Quotes sld
570\end_inset
571
572z
573\begin_inset Quotes srd
574\end_inset
575
576)
577\layout Subsection
578
579The VisibleString type
580\layout Standard
581
582The character string with the alphabet which is more or less a subset of
583 ASCII between space and
584\begin_inset Quotes sld
585\end_inset
586
587~
588\begin_inset Quotes srd
589\end_inset
590
591 (tilde).
592 Alternatively, the alphabet may be represented as the PrintableString alphabet
593 described earlier, plus the following characters:
594\begin_inset Quotes sld
595\end_inset
596
597
598\series bold
599!
600\series default
601
602\begin_inset Quotes srd
603\end_inset
604
605,
606\begin_inset Quotes sld
607\end_inset
608
609
610\series bold
611
612\begin_inset Quotes srd
613\end_inset
614
615
616\series default
617
618\begin_inset Quotes srd
619\end_inset
620
621,
622\begin_inset Quotes sld
623\end_inset
624
625
626\series bold
627#
628\series default
629
630\begin_inset Quotes srd
631\end_inset
632
633,
634\begin_inset Quotes sld
635\end_inset
636
637
638\series bold
639$
640\series default
641
642\begin_inset Quotes srd
643\end_inset
644
645,
646\begin_inset Quotes sld
647\end_inset
648
649
650\series bold
651%
652\series default
653
654\begin_inset Quotes srd
655\end_inset
656
657,
658\begin_inset Quotes sld
659\end_inset
660
661
662\series bold
663&
664\series default
665
666\begin_inset Quotes srd
667\end_inset
668
669,
670\begin_inset Quotes sld
671\end_inset
672
673
674\series bold
675*
676\series default
677
678\begin_inset Quotes srd
679\end_inset
680
681,
682\begin_inset Quotes sld
683\end_inset
684
685
686\series bold
687;
688\series default
689
690\begin_inset Quotes srd
691\end_inset
692
693,
694\begin_inset Quotes sld
695\end_inset
696
697
698\series bold
699<
700\series default
701
702\begin_inset Quotes srd
703\end_inset
704
705,
706\begin_inset Quotes sld
707\end_inset
708
709
710\series bold
711>
712\series default
713
714\begin_inset Quotes srd
715\end_inset
716
717,
718\begin_inset Quotes sld
719\end_inset
720
721
722\series bold
723[
724\series default
725
726\begin_inset Quotes srd
727\end_inset
728
729,
730\begin_inset Quotes sld
731\end_inset
732
733
734\series bold
735
736\backslash
737
738\series default
739
740\begin_inset Quotes srd
741\end_inset
742
743,
744\begin_inset Quotes sld
745\end_inset
746
747
748\series bold
749]
750\series default
751
752\begin_inset Quotes srd
753\end_inset
754
755,
756\begin_inset Quotes sld
757\end_inset
758
759
760\series bold
761^
762\series default
763
764\begin_inset Quotes srd
765\end_inset
766
767,
768\begin_inset Quotes sld
769\end_inset
770
771
772\series bold
773_
774\series default
775
776\begin_inset Quotes srd
777\end_inset
778
779,
780\begin_inset Quotes sld
781\end_inset
782
783
784\series bold
785`
786\series default
787
788\begin_inset Quotes srd
789\end_inset
790
791 (single left quote),
792\begin_inset Quotes sld
793\end_inset
794
795
796\series bold
797{
798\series default
799
800\begin_inset Quotes srd
801\end_inset
802
803,
804\begin_inset Quotes sld
805\end_inset
806
807
808\series bold
809|
810\series default
811
812\begin_inset Quotes srd
813\end_inset
814
815,
816\begin_inset Quotes sld
817\end_inset
818
819
820\series bold
821}
822\series default
823
824\begin_inset Quotes srd
825\end_inset
826
827,
828\begin_inset Quotes sld
829\end_inset
830
831~
832\begin_inset Quotes srd
833\end_inset
834
835.
836\layout Section
837
838ASN.1 Constructed Types
839\layout Subsection
840
841The SEQUENCE type
842\layout Standard
843
844This is an ordered collection of other simple or constructed types.
845 The SEQUENCE constructed type resembles the C
846\begin_inset Quotes sld
847\end_inset
848
849struct
850\begin_inset Quotes srd
851\end_inset
852
853 statement.
854\layout LyX-Code
855
856Address ::= SEQUENCE {
857\layout LyX-Code
858
859 -- The apartment number may be omitted
860\layout LyX-Code
861
862 apartmentNumber NumericString OPTIONAL,
863\layout LyX-Code
864
865 streetName PrintableString,
866\layout LyX-Code
867
868 cityName PrintableString,
869\layout LyX-Code
870
871 stateName PrintableString,
872\layout LyX-Code
873
874 -- This one may be omitted too
875\layout LyX-Code
876
877 zipNo NumericString OPTIONAL
878\layout LyX-Code
879
880}
881\layout Subsection
882
883The SET type
884\layout Standard
885
886This is a collection of other simple or constructed types.
887 Ordering is not important.
888 The data may arrive in the order which is different from the order of specifica
889tion.
890 Data is encoded in the order not necessarily corresponding to the order
891 of specification.
892\layout Subsection
893
894The CHOICE type
895\layout Standard
896
897This type is just a choice between the subtypes specified in it.
898 The CHOICE type contains at most one of the subtypes specified, and it
899 is always implicitly known which choice is being decoded or encoded.
900 This one resembles the C
901\begin_inset Quotes sld
902\end_inset
903
904union
905\begin_inset Quotes srd
906\end_inset
907
908 statement.
909\layout Standard
910
911The following type defines a response code, which may be either an integer
912 code or a boolean
913\begin_inset Quotes sld
914\end_inset
915
916true
917\begin_inset Quotes srd
918\end_inset
919
920/
921\begin_inset Quotes srd
922\end_inset
923
924false
925\begin_inset Quotes srd
926\end_inset
927
928 code.
929\layout LyX-Code
930
931ResponseCode ::= CHOICE {
932\layout LyX-Code
933
934 intCode INTEGER,
935\layout LyX-Code
936
937 boolCode BOOLEAN
938\layout LyX-Code
939
940}
941\layout LyX-Code
942
943\layout Subsection
944
945The SEQUENCE OF type
946\layout Standard
947
948This one is the list (array) of simple or constructed types:
949\layout LyX-Code
950
951-- Example 1
952\layout LyX-Code
953
954ManyIntegers ::= SEQUENCE OF INTEGER
955\layout LyX-Code
956
957-- Example 2
958\layout LyX-Code
959
960ManyRectangles ::= SEQUENCE OF Rectangle
961\layout LyX-Code
962
963-- More complex example:
964\layout LyX-Code
965
966-- an array of structures defined in place.
967\layout LyX-Code
968
969ManyCircles ::= SEQUENCE OF SEQUENCE {
970\layout LyX-Code
971
972 radius INTEGER
973\layout LyX-Code
974
975 }
976\layout Subsection
977
978The SET OF type
979\layout Standard
980
981The SET OF type models the bag of structures.
982 It resembles the SEQUENCE OF type, but the order is not important: i.e.
983 the elements may arrive in the order which is not necessarily the same
984 as the in-memory order on the remote machines.
985\layout LyX-Code
986
987-- A set of structures defined elsewhere
988\layout LyX-Code
989
990SetOfApples :: SET OF Apple
991\layout LyX-Code
992
993-- Set of integers encoding the kind of a fruit
994\layout LyX-Code
995
996FruitBag ::= SET OF ENUMERATED { apple, orange }
vlmcaba97b2004-08-07 05:00:07 +0000997\layout Part
998
999Using the ASN.1 Compiler
vlme18adea2004-06-03 03:49:45 +00001000\layout Chapter
1001
vlmcaba97b2004-08-07 05:00:07 +00001002Introduction to the ASN.1 Compiler
vlme18adea2004-06-03 03:49:45 +00001003\layout Standard
1004
1005The purpose of the ASN.1 compiler, of which this document is part, is to
1006 convert the ASN.1 specifications to some other target language (currently,
1007 only C is supported
1008\begin_inset Foot
1009collapsed false
1010
1011\layout Standard
1012
1013C++ is
1014\begin_inset Quotes sld
1015\end_inset
1016
1017supported
1018\begin_inset Quotes srd
1019\end_inset
1020
1021 too, as long as an object-oriented approach is not a definitive factor.
1022\end_inset
1023
1024).
1025 The compiler reads the specification and emits a series of target language
1026 structures and surrounding maintenance code.
1027 For example, the C structure which may be created by compiler to represent
1028 the simple
1029\emph on
1030Rectangle
1031\emph default
1032 specification defined earlier in this document, may look like this
1033\begin_inset Foot
1034collapsed false
1035
1036\layout Standard
1037
1038
1039\emph on
1040-fnative-integers
1041\emph default
1042 compiler option is used to produce basic C
1043\emph on
1044int
1045\emph default
1046 types instead of generic INTEGER_t.
1047\end_inset
1048
1049:
1050\layout LyX-Code
1051
1052typedef struct Rectangle_s {
1053\layout LyX-Code
1054
1055 int height;
1056\layout LyX-Code
1057
1058 int width;
1059\layout LyX-Code
1060
1061} Rectangle_t;
1062\layout Standard
1063
1064This would not be of much value for such a simple specification, so the
1065 compiler goes further and actually produces the code which fills in this
1066 structure by parsing the binary
1067\begin_inset Foot
1068collapsed false
1069
1070\layout Standard
1071
1072BER, CER and DER encodings are binary.
1073 However, the XER encoding is text (XML) based.
1074\end_inset
1075
1076 data provided in some buffer.
1077 It also produces the code that takes this structure as an argument and
1078 performs structure serialization by emitting a series of bytes.
1079\layout Section
1080
1081Quick start
1082\layout Standard
1083
1084After building and installing the compiler, the asn1c command may be used
1085 to compile the ASN.1 specification
1086\begin_inset Foot
1087collapsed false
1088
1089\layout Standard
1090
1091This is probably
1092\series bold
1093not
1094\series default
1095 what you want to try out right now -- read through the rest of this chapter
1096 to find out about -P option.
1097\end_inset
1098
1099:
1100\layout LyX-Code
1101
1102asn1c
1103\emph on
1104<spec.asn1>
1105\layout Standard
1106
1107If several specifications contain interdependencies, all of them must be
1108 specified:
1109\layout LyX-Code
1110
1111asn1c
1112\emph on
1113<spec1.asn1> <spec2.asn1> ...
1114\layout Standard
1115
1116The compiler -E and -EF options are used for testing the parser and the
1117 semantic fixer, respectively.
1118 These options will instruct the compiler to dump out the parsed (and fixed)
1119 ASN.1 specification as it was "understood" by the compiler.
1120 It might might be useful to check whether a particular syntactic construction
1121 is properly supported by the compiler.
1122\layout LyX-Code
1123
1124asn1c -EF
1125\emph on
1126<spec-to-test.asn1>
1127\layout Standard
1128
1129The -P option is used to dump the compiled output on the screen instead
1130 of creating a bunch of .c and .h files on disk in the current directory.
1131 You would probably want to start with -P option instead of creating a mess
1132 in your current directory.
1133\layout Section
1134
1135Slow start
1136\layout Subsection
1137
1138Recognizing compiler output
1139\layout Standard
1140
1141After compiling, the following entities will be created in your current
1142 directory:
1143\layout Itemize
1144
1145A set of .c and .h files, generally a single pair for each type defined in
1146 the ASN.1 specifications.
1147 These files will be named similarly to the ASN.1 types (
1148\emph on
1149Rectangle.c
1150\emph default
1151 and
1152\emph on
1153Rectangle.h
1154\emph default
1155 for the specification defined in the beginning of this document).
1156\layout Itemize
1157
1158A set of helper .c and .h files which contain generic encoders, decoders and
1159 other useful routines.
1160 There will be many of them, some of them even not necessary
1161\begin_inset Foot
1162collapsed false
1163
1164\layout Standard
1165
1166Soon the compiler will be modified to emit the smallest subset of necessary
1167 files.
1168\end_inset
1169
1170, but the overall amount of code after compiling will be rather small anyway.
1171\layout Standard
1172
1173It is your responsibility to create .c file with the
1174\emph on
1175 int main()
1176\emph default
1177 routine and the Makefile (if needed).
1178 Compiler helps you with the latter by creating the Makefile.am.sample, containing
1179 the skeleton definition for the automake, should you want to use autotools.
1180\layout Standard
1181
1182In other words, after compiling the Rectangle module, you have the following
1183 set of files: { Makefile.am.sample, Rectangle.c, Rectangle.h,
1184\series bold
1185\SpecialChar \ldots{}
1186
1187\series default
1188 }, where
1189\series bold
1190
1191\begin_inset Quotes sld
1192\end_inset
1193
1194\SpecialChar \ldots{}
1195
1196\begin_inset Quotes srd
1197\end_inset
1198
1199
1200\series default
1201 stands for the set of additional
1202\begin_inset Quotes sld
1203\end_inset
1204
1205helper
1206\begin_inset Quotes srd
1207\end_inset
1208
1209 files created by the compiler.
1210 If you add the simple file with the
1211\emph on
1212int main()
1213\emph default
1214 routine, it would even be possible to compile everything with the single
1215 instruction:
1216\layout LyX-Code
1217
1218cc -o rectangle *.c # It could be
1219\emph on
1220that
1221\emph default
1222 simple
1223\begin_inset Foot
1224collapsed false
1225
1226\layout Standard
1227
1228Provided that you've also created a .c file with the
1229\emph on
1230int main()
1231\emph default
1232 routine.
1233\end_inset
1234
1235
1236\layout Subsection
1237
1238Invoking the ASN.1 helper code from the application
1239\layout Standard
1240
1241First of all, you would want to include one or more header files into your
1242 application.
1243 For the Rectangle module, including the Rectangle.h file is enough:
1244\layout LyX-Code
1245
1246#include <Rectangle.h>
1247\layout Standard
1248
1249The header files defines the C structure corresponding to the ASN.1 definition
1250 of a rectangle and the declaration of the ASN.1 type descriptor, which is
1251 used as an argument to most of the functions provided by the ASN.1 module.
1252 For example, here is the code which frees the Rectangle_t structure:
1253\layout LyX-Code
1254
1255Rectangle_t *rect = ;
1256\layout LyX-Code
1257
1258asn1_DEF_Rectangle->free_struct(&asn1_DEF_Rectangle,
1259\layout LyX-Code
1260
1261 rect, 0);
1262\layout Standard
1263
1264This code defines a
1265\emph on
1266rect
1267\emph default
1268 pointer which points to the Rectangle_t structure which needs to be freed.
1269 The second line invokes the generic free_struct routine created specifically
1270 for this Rectangle_t structure.
1271 The
1272\emph on
1273asn1_DEF_Rectangle
1274\emph default
1275 is the type descriptor, which holds a collection of generic routines to
1276 deal with the Rectangle_t structure.
1277\layout Standard
1278
1279There are several generic functions available:
1280\layout Description
1281
1282check_constraints Check that the contents of the target structure are semantical
1283ly valid and constrained to appropriate implicit or explicit subtype constraints.
1284 Please refer to Section
1285\begin_inset LatexCommand \vref{sub:Validating-the-target}
1286
1287\end_inset
1288
1289.
1290\layout Description
1291
1292ber_decoder This is the generic
1293\emph on
1294restartable
1295\begin_inset Foot
1296collapsed false
1297
1298\layout Standard
1299
1300Restartable means that if the decoder encounters the end of the buffer,
1301 it will fail, but may later be invoked again with the rest of the buffer
1302 to continue decoding.
1303\end_inset
1304
1305
1306\emph default
1307BER decoder (Basic Encoding Rules).
1308 This decoder would create and/or fill the target structure for you.
1309 Please refer to Section
1310\begin_inset LatexCommand \ref{sub:Decoding-BER}
1311
1312\end_inset
1313
1314.
1315\layout Description
1316
1317der_encoder This is the generic DER encoder (Distinguished Encoding Rules).
1318 This decoder will take the target structure and encode it into a series
1319 of bytes.
1320 Please refer to Section
1321\begin_inset LatexCommand \ref{sub:Encoding-DER}
1322
1323\end_inset
1324
1325.
1326\layout Description
1327
1328print_struct This function convert the contents of the passed target structure
1329 into human readable form.
1330 This form is not formal and cannot be converted back into the structure,
1331 but it may turn out to be useful for debugging or quick-n-dirty printing.
1332 Please refer to Section
1333\begin_inset LatexCommand \ref{sub:Printing-the-target}
1334
1335\end_inset
1336
1337.
1338\layout Description
1339
1340free_struct This is a generic disposal which frees the target structure.
1341 Please refer to Section
1342\begin_inset LatexCommand \ref{sub:Freeing-the-target}
1343
1344\end_inset
1345
1346.
1347\layout Standard
1348
1349Each of the above function takes the type descriptor (
1350\emph on
1351asn1_DEF_\SpecialChar \ldots{}
1352
1353\emph default
1354) and the target structure (
1355\emph on
1356rect
1357\emph default
1358, in the above example).
1359 The target structure is typically created by the generic BER decoder or
1360 by the application itself.
1361\layout Standard
1362
1363Here is how the buffer can be deserialized into the structure:
1364\layout LyX-Code
1365
1366Rectangle_t *
1367\layout LyX-Code
1368
1369simple_deserializer(void *buffer, size_t buf_size) {
1370\layout LyX-Code
1371
1372 Rectangle_t *rect = 0; /* Note this 0! */
1373\layout LyX-Code
1374
1375 ber_dec_rval_t rval;
1376\layout LyX-Code
1377
1378
1379\layout LyX-Code
1380
1381 rval = asn1_DEF_Rectangle->ber_decoder(
1382\layout LyX-Code
1383
1384 &asn1_DEF_Rectangle,
1385\layout LyX-Code
1386
1387 (void **)&rect,
1388\layout LyX-Code
1389
1390 buffer, buf_size,
1391\layout LyX-Code
1392
1393 0);
1394\layout LyX-Code
1395
1396
1397\layout LyX-Code
1398
1399 if(rval
1400\series bold
1401.code
1402\series default
1403 == RC_OK) {
1404\layout LyX-Code
1405
1406 return rect; /* Decoding succeeded */
1407\layout LyX-Code
1408
1409 } else {
1410\layout LyX-Code
1411
1412 asn1_DEF_Rectangle->free_struct(
1413\layout LyX-Code
1414
1415 &asn1_DEF_Rectangle, rect, 0);
1416\layout LyX-Code
1417
1418 return 0;
1419\layout LyX-Code
1420
1421 }
1422\layout LyX-Code
1423
1424}
1425\layout Standard
1426
1427The code above defines a function,
1428\emph on
1429simple_deserializer
1430\emph default
1431, which takes a buffer and its length and expected to return a pointer to
1432 the Rectangle_t structure.
1433 Inside, it tries to convert the bytes passed into the target structure
1434 (rect) using the generic BER decoder and returns the rect pointer afterwards.
1435 If the structure cannot be deserialized, it frees the memory which might
1436 be left allocated by the unfinished
1437\emph on
1438ber_decoder
1439\emph default
1440 routine and returns NULL.
1441
1442\series bold
1443This freeing is necessary
1444\series default
1445 because the ber_decoder is a restartable procedure, and may fail just because
1446 there is more data needs to be provided before decoding could be finalized.
1447 The code above obviously does not take into account the way the
1448\emph on
1449ber_decoder
1450\emph default
1451 failed, so the freeing is necessary because the part of the buffer may
1452 already be decoded into the structure by the time something goes wrong.
1453\layout Standard
1454
1455Restartable decoding is a little bit trickier: you need to provide the old
1456 target structure pointer (which might be already half-decoded) and react
1457 on RC_WMORE return code.
1458 This will be explained later in Section
1459\begin_inset LatexCommand \vref{sub:Decoding-BER}
1460
1461\end_inset
1462
1463
1464\layout Subsubsection
1465
1466
1467\begin_inset LatexCommand \label{sub:Decoding-BER}
1468
1469\end_inset
1470
1471Decoding BER
1472\layout Standard
1473
1474The Basic Encoding Rules describe the basic way how the structure can be
1475 encoded and decoded.
1476 Several other encoding rules (CER, DER) define a more restrictive versions
1477 of BER, so the generic BER parser is also capable of decoding the data
1478 encoded by CER and DER encoders.
1479 The opposite is not true.
1480\layout Standard
1481
1482The ASN.1 compiler provides the generic BER decoder which is implicitly capable
1483 of decoding BER, CER and DER encoded data.
1484\layout Standard
1485
1486The decoder is restartable (stream-oriented), which means that in case the
1487 buffer has less data than it is expected, the decoder will process whatever
1488 it is available and ask for more data to be provided.
1489 Please note that the decoder may actually process less data than it is
1490 given in the buffer, which means that you should be able to make the next
1491 buffer contain the unprocessed part of the previous buffer.
1492\layout Standard
1493
1494Suppose, you have two buffers of encoded data: 100 bytes and 200 bytes.
1495\layout Itemize
1496
1497You may concatenate these buffers and feed the BER decoder with 300 bytes
1498 of data, or
1499\layout Itemize
1500
1501You may feed it the first buffer of 100 bytes of data, realize that the
1502 ber_decoder consumed only 95 bytes from it and later feed the decoder with
1503 205 bytes buffer which consists of 5 unprocessed bytes from the first buffer
1504 and the latter 200 bytes from the second buffer.
1505\layout Standard
1506
1507This is not as convenient as it could be (like, the BER encoder would consume
1508 the whole 100 bytes and keep these 5 bytes in some temporary storage),
1509 but in case of stream-based processing it might actually be OK.
1510 Suggestions are welcome.
1511\layout Standard
1512
1513There are two ways to invoke a BER decoder.
1514 The first one is a direct reference of the type-specific decoder.
1515 This way was shown in the previous example of
1516\emph on
1517simple_deserializer
1518\emph default
1519 function.
1520 The second way is to invoke a
1521\emph on
1522ber_decode
1523\emph default
1524 function, which is just a simple wrapper of the former approach into a
1525 less wordy notation:
1526\layout LyX-Code
1527
1528rval = ber_decode(&asn1_DEF_Rectangle, (void **)&rect,
1529\layout LyX-Code
1530
1531 buffer, buf_size);
1532\layout Standard
1533
1534Note that the initial (asn1_DEF_Rectangle->ber_decoder) reference is gone,
1535 and also the last argument (0) is no longer necessary.
1536\layout Standard
1537
1538These two ways of invocations are fully equivalent.
1539\layout Standard
1540
1541The BER de
1542\emph on
1543coder
1544\emph default
1545 may fail because (
1546\emph on
1547the following RC_\SpecialChar \ldots{}
1548 codes are defined in ber_decoder.h
1549\emph default
1550):
1551\layout Itemize
1552
1553RC_WMORE: There is more data expected than it is provided (stream mode continuat
1554ion feature);
1555\layout Itemize
1556
1557RC_FAIL: General failure to decode the buffer;
1558\layout Itemize
1559
1560\SpecialChar \ldots{}
1561 other codes may be defined as well.
1562\layout Standard
1563
1564Together with the return code (.code) the ber_dec_rval_t type contains the
1565 number of bytes which is consumed from the buffer.
1566 In the previous hypothetical example of two buffers (of 100 and 200 bytes),
1567 the first call to ber_decode() would return with .code = RC_WMORE and .consumed
1568 = 95.
1569 The .consumed field of the BER decoder return value is
1570\series bold
1571always
1572\series default
1573 valid, even if the decoder succeeds or fails with any other return code.
1574\layout Standard
1575
1576Please look into ber_decoder.h for the precise definition of ber_decode()
1577 and related types.
1578\layout Subsubsection
1579
1580
1581\begin_inset LatexCommand \label{sub:Encoding-DER}
1582
1583\end_inset
1584
1585Encoding DER
1586\layout Standard
1587
1588The Distinguished Encoding Rules is the variant of BER encoding rules which
1589 is oriented on representing the structures with length known beforehand.
1590 This is probably exactly how you want to encode: either after a BER decoding
1591 or after a manual fill-up, the target structure contains the data which
1592 size is implicitly known before encoding.
1593 The DER encoding is used, for example, to encode X.509 certificates.
1594\layout Standard
1595
1596As with BER decoder, the DER encoder may be invoked either directly from
1597 the ASN.1 type descriptor (asn1_DEF_Rectangle) or from the stand-alone function,
1598 which is somewhat simpler:
1599\layout LyX-Code
1600
1601/*
1602\layout LyX-Code
1603
1604 * This is a custom function which writes the
1605\layout LyX-Code
1606
1607 * encoded output into some FILE stream.
1608\layout LyX-Code
1609
1610 */
1611\layout LyX-Code
1612
1613int _write_stream(void *buffer, size_t size, void *app_key) {
1614\layout LyX-Code
1615
1616 FILE *ostream = app_key;
1617\layout LyX-Code
1618
1619 size_t wrote;
1620\layout LyX-Code
1621
1622
1623\layout LyX-Code
1624
1625 wrote = fwrite(buffer, 1, size, ostream);
1626\layout LyX-Code
1627
1628
1629\layout LyX-Code
1630
1631 return (wrote == size) ? 0 : -1;
1632\layout LyX-Code
1633
1634}
1635\layout LyX-Code
1636
1637
1638\layout LyX-Code
1639
1640/*
1641\layout LyX-Code
1642
1643 * This is the serializer itself,
1644\layout LyX-Code
1645
1646 * it supplies the DER encoder with the
1647\layout LyX-Code
1648
1649 * pointer to the custom output function.
1650\layout LyX-Code
1651
1652 */
1653\layout LyX-Code
1654
1655ssize_t
1656\layout LyX-Code
1657
1658simple_serializer(FILE *ostream, Rectangle_t *rect) {
1659\layout LyX-Code
1660
1661 der_enc_rval_t rval; /* Return value */
1662\layout LyX-Code
1663
1664
1665\layout LyX-Code
1666
1667 rval = der_encode(&asn1_DEF_Rect, rect,
1668\layout LyX-Code
1669
1670 _write_stream, ostream);
1671\layout LyX-Code
1672
1673 if(rval
1674\series bold
1675.encoded
1676\series default
1677 == -1) {
1678\layout LyX-Code
1679
1680 /*
1681\layout LyX-Code
1682
1683 * Failure to encode the rectangle data.
1684\layout LyX-Code
1685
1686 */
1687\layout LyX-Code
1688
1689 fprintf(stderr,
1690\begin_inset Quotes sld
1691\end_inset
1692
1693Cannot encode %s: %s
1694\backslash
1695n
1696\begin_inset Quotes srd
1697\end_inset
1698
1699,
1700\layout LyX-Code
1701
1702 rval
1703\series bold
1704.failed_type
1705\series default
1706->name,
1707\layout LyX-Code
1708
1709 strerror(errno));
1710\layout LyX-Code
1711
1712 return -1;
1713\layout LyX-Code
1714
1715 } else {
1716\layout LyX-Code
1717
1718 /* Return the number of bytes */
1719\layout LyX-Code
1720
1721 return rval.encoded;
1722\layout LyX-Code
1723
1724 }
1725\layout LyX-Code
1726
1727}
1728\layout Standard
1729
1730As you see, the DER encoder does not write into some sort of buffer or something.
1731 It just invokes the custom function (possible, multiple times) which would
1732 save the data into appropriate storage.
1733 The optional argument
1734\emph on
1735app_key
1736\emph default
1737 is opaque for the DER encoder code and just used by
1738\emph on
1739_write_stream()
1740\emph default
1741 as the pointer to the appropriate output stream to be used.
1742\layout Standard
1743
1744If the custom write function is not given (passed as 0), then the DER encoder
1745 will essentially do the same thing (i.e., encode the data) but no callbacks
1746 will be invoked (so the data goes nowhere).
1747 It may prove useful to determine the size of the structure's encoding before
1748 actually doing the encoding
1749\begin_inset Foot
1750collapsed false
1751
1752\layout Standard
1753
1754It is actually faster too: the encoder might skip over some computations
1755 which aren't important for the size determination.
1756\end_inset
1757
1758.
1759\layout Standard
1760
1761Please look into der_encoder.h for the precise definition of der_encode()
1762 and related types.
1763\layout Subsubsection
1764
1765
1766\begin_inset LatexCommand \label{sub:Validating-the-target}
1767
1768\end_inset
1769
1770Validating the target structure
1771\layout Standard
1772
1773Sometimes the target structure needs to be validated.
1774 For example, if the structure was created by the application (as opposed
1775 to being decoded from some external source), some important information
1776 required by the ASN.1 specification might be missing.
1777 On the other hand, the successful decoding of the data from some external
1778 source does not necessarily mean that the data is fully valid either.
1779 It might well be the case that the specification describes some subtype
1780 constraints that were not taken into account during decoding, and it would
1781 actually be useful to perform the last check when the data is ready to
1782 be encoded or when the data has just been decoded to ensure its validity
1783 according to some stricter rules.
1784\layout Standard
1785
1786The asn_check_constraints() function checks the type for various implicit
1787 and explicit constraints.
1788 It is recommended to use asn_check_constraints() function after each decoding
1789 and before each encoding.
1790\layout Standard
1791
1792Please look into constraints.h for the precise definition of asn_check_constraint
1793s() and related types.
1794\layout Subsubsection
1795
1796
1797\begin_inset LatexCommand \label{sub:Printing-the-target}
1798
1799\end_inset
1800
1801Printing the target structure
1802\layout Standard
1803
1804There are two ways to print the target structure: either invoke the print_struct
1805 member of the ASN.1 type descriptor, or using the asn_fprint() function,
1806 which is a simpler wrapper of the former:
1807\layout LyX-Code
1808
1809asn_fprint(stdout, &asn1_DEF_Rectangle, rect);
1810\layout Standard
1811
1812Please look into constr_TYPE.h for the precise definition of asn_fprint()
1813 and related types.
1814\layout Subsubsection
1815
1816
1817\begin_inset LatexCommand \label{sub:Freeing-the-target}
1818
1819\end_inset
1820
1821Freeing the target structure
1822\layout Standard
1823
1824Freeing the structure is slightly more complex than it may seem to.
1825 When the ASN.1 structure is freed, all the members of the structure and
1826 their submembers etc etc are recursively freed too.
1827 But it might not be feasible to free the structure itself.
1828 Consider the following case:
1829\layout LyX-Code
1830
1831struct my_figure { /* The custom structure */
1832\layout LyX-Code
1833
1834 int flags; /* <some custom member> */
1835\layout LyX-Code
1836
1837 /* The type is generated by the ASN.1 compiler */
1838\layout LyX-Code
1839
1840
1841\emph on
1842Rectangle_t rect;
1843\layout LyX-Code
1844
1845 /* other members of the structure */
1846\layout LyX-Code
1847
1848};
1849\layout Standard
1850
1851In this example, the application programmer defined a custom structure with
1852 one ASN.1-derived member (rect).
1853 This member is not a reference to the Rectangle_t, but an in-place inclusion
1854 of the Rectangle_t structure.
1855 If the freeing is necessary, the usual procedure of freeing everything
1856 must not be applied to the &rect pointer itself, because it does not point
1857 to the memory block directly allocated by memory allocation routine, but
1858 instead lies within such a block allocated for my_figure structure.
1859\layout Standard
1860
1861To solve this problem, the free_struct routine has the additional argument
1862 (besides the intuitive type descriptor and target structure pointers),
1863 which is the flag specifying whether the outer pointer itself must be freed
1864 (0, default) or it should be left intact (non-zero value).
1865\layout LyX-Code
1866
1867/* Rectangle_t is defined within my_figure */
1868\layout LyX-Code
1869
1870struct my_figure *mf =
1871\series bold
1872...
1873\series default
1874;
1875\layout LyX-Code
1876
1877/*
1878\layout LyX-Code
1879
1880 * Freeing the Rectangle_td
1881\layout LyX-Code
1882
1883 * without freeing the mf->rect pointer
1884\layout LyX-Code
1885
1886 */
1887\layout LyX-Code
1888
1889asn1_DEF_Rectangle->free_struct(
1890\layout LyX-Code
1891
1892 &asn1_DEF_Rectangle, &mf->rect,
1893\emph on
18941
1895\emph default
1896 /* !free */);
1897\layout LyX-Code
1898
1899
1900\layout LyX-Code
1901
1902/* Rectangle_t is a stand-alone pointer */
1903\layout LyX-Code
1904
1905Rectangle_t *rect =
1906\series bold
1907...
1908\series default
1909;
1910\layout LyX-Code
1911
1912/*
1913\layout LyX-Code
1914
1915 * Freeing the Rectangle_t
1916\layout LyX-Code
1917
1918 * and freeing the rect pointer
1919\layout LyX-Code
1920
1921 */
1922\layout LyX-Code
1923
1924asn1_DEF_Rectangle->free_struct(
1925\layout LyX-Code
1926
1927 &asn1_DEF_Rectangle, rect,
1928\emph on
19290
1930\emph default
1931 /* free the pointer too */);
1932\layout Standard
1933
1934It is safe to invoke the
1935\emph on
1936free_struct
1937\emph default
1938 function with the target structure pointer set to 0 (NULL), the function
1939 will do nothing.
1940\layout Bibliography
1941\bibitem [Dub00]{Dub00}
1942
1943Olivier Dubuisson --
1944\emph on
1945ASN.1 Communication between heterogeneous systems
1946\emph default
1947 -- Morgan Kaufmann Publishers, 2000.
1948
1949\begin_inset LatexCommand \htmlurl{http://asn1.elibel.tm.fr/en/book/}
1950
1951\end_inset
1952
1953.
1954 ISBN:0-12-6333361-0.
1955\layout Bibliography
1956\bibitem [ITU-T/ASN.1]{ITU-T/ASN.1}
1957
1958ITU-T Study Group 17 -- Languages for Telecommunication Systems
1959\begin_inset LatexCommand \url{http://www.itu.int/ITU-T/studygroups/com17/languages/}
1960
1961\end_inset
1962
1963
1964\the_end