Merge pull request #10 from leenaars/pkgconf
[quick-der] / README.MD
1 # Quick (and Easy) DER, a Library for parsing ASN.1
2
3 <img alt="Quick DER logo" src="quick-der-logo.png" style="float: right;"/>
4
5 > *Quick DER, or if you like, "Quick and Easy DER", is a library for handling
6 > DER, which is a widely used binary representation of ASN.1 syntax in binary
7 > formats.  The library describes ASN.1 syntax in a parser table that can be
8 > fed into library routines, resulting in pointer/length descriptors for the
9 > individual data fragments.*
10
11 ## Basic Usage
12
13 The basic approach of using this library is translating the ASN.1 syntax into
14 a parser table.  This is done when building your software, as a phase preceding
15 the compilation of your Quick DER using program.  The translation from ASN.1
16 to C code can be done manually and **TODO** will in the future be automated with
17 an ASN.1 parser.
18
19 The resulting *path walks* are used in calls like `der_unpack()` to transform
20 DER into C-style structures, and `der_pack()` to make the opposite transformation.
21 The C-style structures are derived from the ASN.1 syntax, and permits access to
22 the information with no further need of understanding the depths of processing
23 DER.
24
25 Since you are handling binary data (rather than character strings), all data
26 is described in so-called `dercursor` structures; each containing a pointer
27 and a size of the data pointed at.
28
29
30 ## Basic Code Structure
31
32 The output from mapping ASN.1 to a parser table is an include file for the
33 C programming language.  This defines the various *path walks* that can be
34 used to unpack and pack DER data.  The output and input of these routines
35 takes the form of an array of `dercursor` values.
36
37 To simplify use of the unpacked data, there are overlay structures for the
38 `dercursor` array.  These overlay structures use the same labels that are
39 used in the ASN.1 syntax, so it is possible to walk around in the structures.
40
41 Some parts of the syntax indicate `OPTIONAL` elements.  Such elements result
42 in the respective `dercursor` variables to be NULL values; specifically, the
43 function `der_isnull()` returns a true value for these elements.
44
45
46 ## Extra Coding Facilities
47
48 There are routines `der_iterate_first()` and `der_iterate_next()` routines
49 to manually iterate over a DER structure's components.  This can be used to
50 analyse structures that have not been unpacked (yet).  The `der_countelements()`
51 routine can be used to predict the number of iterations.
52
53 There are also routines to manually walk through packaged DER structures,
54 namely `der_enter()` and `der_skip()` to enter into a nested structure and to
55 find the next element in a concatenation of such elements.
56
57 A much more advanced form of such walks through a DER structure exists in the
58 form of `der_walk()`, which is fed another kind of walk, a sequence of enter/skip
59 statements with tags that will be validated.
60
61
62 ## Validation of DER
63
64 To validate the structures written in DER, both `der_unpack()` and `der_walk()`
65 can be used.  Most other routines are coded for flexibility and should not be
66 assumed to validate DER in more detail than strictly required.
67
68 The `der_unpack()` routine runs through the entire structure, and validates
69 the tags it runs by, as well as the complete nesting structure it encounters.
70 It is a complete validation of the structures.
71
72 The `der_walk()` routine performs *lazy validation*, meaning that it will
73 carefully check tags and nesting inasfar as it is needed to get from its
74 starting point to its end point.  Anything but the paths explored will be
75 accepted without question.
76
77 ### Relation to BER
78
79 *This is for ASN.1 experts; others can safely skip this subsection.*
80
81 The Quick DER library is designed to process DER, although it will also accept
82 some of the more general BER format.  If a length or value is written in more
83 than the minimal space, the library is still likely to accept it.  Note that
84 the `BIT STRING` type is somewhat likely to run into overflow problems, so
85 there the full restrictiveness of DER is applied.
86
87
88 ## No Memory Allocation
89
90 The entire library has been designed to operate without dynamic memory allocation.
91 This means that there will never be a memory leak as a result of using Quick DER.
92
93 When DER information is unpacked, it is assumed to be loaded into a memory buffer
94 by the calling program, and the `dercursor` structures point to portions of that
95 buffer.  The data is stored in `dercursor` arrays which the user program may
96 overlay with meaningful, ASN.1-labelled structures.  In many applications, such
97 structures can be allocated on the stack.
98
99 Some portions of the data may be dynamically sized, notably the `SEQUENCE OF`
100 and `SET OF` structures, which indicate that the structural description following
101 it may be repeated in the binary data.  Such data portions will be stored and
102 not yet unpacked by `der_unpack()`.  Based on the stored DER data in a `dercursor`,
103 the calling application can choose to use iterators, `der_walk()` and so on to
104 avoid actually unpacking it; or it may allocate memory dynamically, and use that
105 to repeatedly call `der_unpack()` to find the individual entries.
106
107 In short, the Quick DER library *never* needs to perform memory allocation, and
108 it provides the calling program with a lot of control to avoid it too.  This is
109 ideal for embedded applications, but is also beneficial for a secure programming
110 style.
111
112
113 ## ASN.1 Compiler
114
115 We have equiped a simple
116 [ASN.1 Compiler](https://github.com/vanrein/asn2quickder)
117 with a backend that generates both the overlay data structures and the
118 byte codes for `der_pack()` and `der_unpack()`.  For most everyday ASN.1
119 this should suffice to produce a header file from an ASN.1 module.
120
121
122 ## RFC Collection
123
124 We have started a collection of RFC's, stripped down to ASN.1 modules,
125 that can be mapped to header files that can simply be include in a C program:
126
127     #include <quick-der/rfc5280.h>
128     #include <quick-der/rfc4120.h>
129     #include <quick-der/rfc4511.h>
130
131 These three examples were included already:
132
133   * X.509 certificate and CRL structures
134   * Kerberos packet formats and messaging
135   * LDAP as a protocol description
136
137 Most modules do things that confuse the compiler, so small changes have been
138 made, and clearly marked with `asn1ate` and an explanation in the ASN.1 files
139 in the `rfc/` directory.  The issues found were usually quite simple:
140
141   * we had to use uppercase initial characters in type names
142   * we removed complex constraints (as Quick DER does not implement them anyway)
143   * LDAP contained an infinitely circular reference for `Filter.not`
144
145 There are some specifications that go far beyond the abilities of `asn1ate`,
146 by using such concepts as macros.  This applied to the SNMP RFC's.
147
148 ## Future Plans
149
150 There are a few things that this library can use:
151
152   * **More testing.** The current `test` directory is far too small; we can take a PKIX certificate apart and re-compose it, so we're definately doing something good, but this is nowhere near thorough testing.  If you run into a problem case, then *please* share it so we can solve it and extend our test base.
153   * **Compiler output testing.** The compiler output is currently compiled to see if there are C syntactical problems, but that is all.  They have been visually compared to manually crafted code, too.  More exhaustive tests, including a full application, would be in order.
154   * **Python embedding.** This would be useful for many protocol applications that need to modify a few things.  It also greatly helps to get more protocols within the reach of Python.  See our [ideas about Python Quick DER](PYTHON.MD) for a plan that greatly simplifies ASN.1 processing with Python.
155
156 And of course, there are many useful things we may do with this library:
157
158   * **Kerberos in PKIX.** [Certificates wrapping Kerberos Tickets](http://github.com/arpa2/kerberos2pkix) for use with [TLS-KDH](https://tools.ietf.org/html/draft-vanrein-tls-kdh)
159   * **Miniature LDAP services.** These can help you centralise your data storage under own control; for instance, your PGP key ring or your vCard collection are good canidadates for sharing locally.
160   * **Remote PKCS #11.** The main issue in doing this well is proper encapsulation, but with Quick and Easy DER, and the emphasis of both on security and well-defined sizes, it appears to be a perfect match to wrap PKCS #11 arguments in DER structures.
161