ffasn1c compiles ASN.1 source and generate C code to manipulate, encode and decode the corresponding ASN.1 messages.
The generated C code is made of a header defining the ASN.1 types and a source defining an internal binary representation of the ASN.1 types.
The library libffasn1 (source code in libffasn1/) contains the functions to allocate, encode, decode and free ASN.1 messages.
The compiler ffasn1c does not need a specific installation. The ffasn1c executable does not need any other file so you can copy it anywhere (for example in /usr/local/bin on a Linux system).
In the examples directory you can build the asn1convert
example.
make to build the example.
make CONFIG_WIN32=y to build the example.
nmake -f Makefile.msvc to build the example.
ffasn1c is invoked to generate
simpletest.h and simpletest.c from the ASN.1 source
simpletest.asn.
asn1convert is a simple tool to convert messages of type
ObjectList from any ASN.1 encoding to any encoding. You can try:
./asn1convert ber gser simpletest.der a.gser
a.gser contains the GSER (i.e. text) representation of the DER encoded message stored in simpletest.der.
Usage:
ffasn1c [options] inputfile...
There can be several input files. Each input file defines one or more ASN.1 modules.
Options:
int or uint32_t type only if the
PER-visible contraints tells that it can fit. Otherwise, large
integers are used (ASN1Integer C type).
Debug options: these options are useful if you want to know if the compiler really understood what you meant.
The compiler implements the following standards:
ANY type is supported to be able to compile older ASN.1
sources (X.208 specification).
The runtime library implements the following standards:
Known limitations and rationale:
SET OF is not
canonical. [SET OF is almost never used in PER notation and
making it canonical has a large runtime cost].
SEQUENCE or SET components with complex default values
are converted to OPTIONAL components in the generated C
code. [The runtime cost of handling these cases would be high while
being almost never used in practise.]
EMBEDDED PDV, EXTERNAL and CHARACTER STRING
types are supported but are always encoded as the SEQUENCE
value indicated in X.680.
GeneralString,
GraphicString, TeletexString, GeneralizedTime,
UTCTime and ObjectDescriptor are handled as OCTET
STRING. No consistency check are done. [These types should no longer
be really needed. However we fully support the restricted multiplier
strings (NumericString, PrintableString,
VisibleString, IA5String, BMPString and
UniversalString) and UTF8String.
REAL type is compiled as the double C type. [In our
current use case, arbitrary precision floating point values were not
needed.]
A few useful types are predefined by the compiler in a built-in
UsefulDefinitions module. The types are:
TYPE-IDENTIFIER (X 681 Annex A)
ABSTRACT-SYNTAX (X 681 Annex B)
InstanceOfType (used to implement the INSTANCE OF type of X 681 Annex C)
EXTERNAL-Internal (used to implement the EXTERNAL type)
EMBEDDED-PDV-Internal (used to implement the EMBEDDED PDV type)
CHARACTER-STRING-Internal (used to implement the CHARACTER STRING type)
The user must provide the 3 following functions so that the library can allocate, reallocate and free memory:
void *asn1_malloc(int size);
void *asn1_realloc(void *ptr, int size);
void asn1_free(void *ptr);
The ASN.1 types are compiled into an opaque C type: ASN1CType
*. All the API uses this type to manipulate ASN.1 types.
The ASN.1 values of the corresponding types are represented in memory
using the structures, unions and other types defined in the C header
generated by the compiler. A flat representation is used for
SEQUENCE/SET and CHOICE to minimize the cost of memory
allocations. Pointer indirections are used for SEQUENCE/SET OF
and for recursive types.
The following functions are defined to manage ASN.1 types and values:
int asn1_get_size(const ASN1CType *p);void *asn1_mallocz_value(const ASN1CType *p);void asn1_free_value(const ASN1CType *p, void *data);int asn1_cmp_value(const ASN1CType *p, const void *data1, const void *data2);void *asn1_random(const ASN1CType *p, int seed);int asn1_uper_encode(uint8_t **pbuf, const ASN1CType *p, const void *data);asn1_free().
int asn1_aper_encode(uint8_t **pbuf, const ASN1CType *p, const void *data);int asn1_der_encode(uint8_t **pbuf, const ASN1CType *p, const void *data);int asn1_ber_encode(uint8_t **pbuf, const ASN1CType *p, const void *data, const ASN1BERParams *params);int asn1_gser_encode(uint8_t **pbuf, const ASN1CType *p, const void *data);int asn1_xer_encode(uint8_t **pbuf, const ASN1CType *p, const void *data);int asn1_xer_encode2(uint8_t **pbuf, const ASN1CType *p, const void *data, const ASN1XERParams *params);int asn1_uper_decode(void **pdata, const ASN1CType *p, const uint8_t *buf, int buf_len, ASN1Error *err);*pdata contains the decoded value or NULL if
there was an error. The decoded value can be freed with
asn1_free_value(). In case of error, more information about the
error is returned in err.
int asn1_aper_decode(void **pdata, const ASN1CType *p, const uint8_t *buf, int buf_len, ASN1Error *err);int asn1_ber_decode(void **pdata, const ASN1CType *p, const uint8_t *buf, int buf_len, ASN1Error *err);int asn1_gser_decode(void **pdata, const ASN1CType *p, const uint8_t *buf, int buf_len, ASN1Error *err);int asn1_xer_decode(void **pdata, const ASN1CType *p, const uint8_t *buf, int buf_len, ASN1Error *err);BOOL asn1_check_constraints(const ASN1CType *p, const void *data, char *msg_buf, int msg_buf_size);msg_buf of maximum size
msg_buf_size.
ffasn1c and its runtime library is copyright 2011-2012 Fabrice Bellard.
ffasn1c and its associated runtime library is available without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software.