Commit f15320bf authored by Lev Walkin's avatar Lev Walkin

Initial revision

parent 746cb60b
Lev Walkin <vlm@lionet.info>
0. ASN.1 grammar parser is written mostly with respect to constructing a tree,
so a tree destruction is not fully supported and certain memory leaks are
known. Not a huge problem for run-once programs like a compiler.
NOTE: This statement does not apply to the target code _produced_
by the compiler.
1. REAL type is not supported yet.
2. For purposes of compilation, INTEGER type is modelled using a large
static type (asn_integer_t), but defined as any positive or negative value
by ASN.1. Not a problem as most specifications use very small values anyway.
NOTE: This statement does not apply to the target code _produced_
by the compiler.
3. ASN Macros are prohibited by the current ASN.1 standard,
and are not supported.
4. Multiple tags applied at the same level are not supported:
BadTags ::= [0] EXPLICIT [2] IMPLICIT OtherType
The same thing could be achieved by using the indirection:
GoodTags ::= [0] EXPLICIT OtherTypePtr
OtherTypePtr ::= [2] IMPLICIT OtherType
5. Mixed definite/indefinite length in a _single_ BER tags sequence is not
supported. Should not be a problem in the real world. Please note that it
is still possible, for example, to encode a wrapper structure using definite
length, and encode its substructure member using indefinite length. The BER
decoder is perfectly capable of decoding such sequences.
/*-
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
0.8.10: 2004-Jun-02
* Added const qualifier where necessary.
* Changed position of outmost_tag fetcher within asn1_TYPE_descriptor_t
structure.
0.8.9: 2004-May-26
* Added *_{get|set}_arcs_*() functions for OBJECT IDENTIFIER
and RELATIVE-OID, together with test cases.
0.8.8: 2004-May-09
* Introduced subtype constraints support (incomplete!).
* Fixed compiler. If the last member of the SEQUENCE is OPTIONAL
and absent in the encoding, and the type is extensible (...) or
EXTENSIBILITY IMPLIED flag is set, then the structure could not
be correctly decoded. (Severity: high, Security impact: low).
* Compiler: fixed recursive ASN.1 types inclusion (Severity: low,
Security impact: none).
* Parser: IMPORTS/FROM fixes, now allowing multiple sections.
* Code compiled and checked on PowerPC (@MacOS X). No major portability
issues experienced.
0.8.7: 2004-Apr-11 T-version-0-8-7
* Fixed SEQUENCE BER decoder: if the last member of the SEQUENCE is
OPTIONAL and absent in the encoding, RC_FAIL was returned instead
of RC_OK (Severity: high, Security impact: low).
* Added test case to check the above problem.
* Added test case to check -fnative-integers mode.
0.8.6: 2004-Apr-03 T-version-0-8-6
* Fixed compiler output for embedded ASN.1 structures.
0.8.5: 2004-Mar-28 T-version-0-8-5
* Fixed ber_tlv_length() computation problem (Severity: blocker,
Security impact: none).
Reported by <vss@high.net.ru>
0.8.4: 2004-Mar-22
* Removed RC_ITAG enumeration element from BER decoder.
This return code did not have much practical value.
0.8.3: 2004-Mar-14 T-version-0-8-3
* Fixed SET::BER decoder: restart after reaching a buffer boundary
weas broken (Severity: blocker, Security impact: low).
* Fixed OCTET STRING::BER decoder: restart after reaching a buffer
boundary was broken (Severity: blocker, Security impact: low).
Reported by <vss@high.net.ru>
* Added test cases to check decoders restartability.
* Slightly more general INTEGER2long decoder.
* Allowed nested /* C-type */ comments, as per X.680:2002.
0.8.2: 2004-Mar-01 T-version-0-8-2
* Fixed SEQUENCE BER decoder: an OPTIONAL element was required, where
should not have been (Severity: major; Security impact: low).
* Fixed print_struct pointer inheritance.
* Added -fno-c99 and -funnamed-unions
0.8.1: 2004-Feb-22
* -R switch to asn1c: Omit support code, compile only the tables.
* Introduced NativeInteger pseudotype.
* Corrected the informal print_struct()'s output format.
0.8.0: 2004-Feb-03 T-version-0-8-0
* Some documentation is created (a .pdf and a short manual page).
* Last touches to the code.
0.7.9: 2004-Feb-01 T-version-0-7-9
* Human readable printing support.
* Support for implicit (standard) constraints.
0.7.8: 2004-Jan-31
* SET now rejects duplicate fields in the data stream.
0.7.7: 2004-Jan-25
* Added types: GeneralizedTime and UTCTime.
0.7.6: 2004-Jan-24 T-version-0-7-6
* DER encoding of a SET OF now involves dynamic sorting.
0.7.5: 2004-Jan-24 T-version-0-7-5
* DER encoding of a SET with untagged CHOICE
now involves dynamic sorting.
0.7.0: 2004-Jan-19 T-version-0-7-0
* A bunch of DER encoders is implemented.
0.6.6: 2004-Jan-11
* Implemented CHOICE decoder.
* Implemented destructors support.
0.6.5: 2004-Jan-03
* Implemented SET decoder.
* Implemented SET OF and SEQUENCE OF decoders.
0.6.4: 2003-Dec-31
* Implemented BOOLEAN, NULL, ENUMERATED decoders.
* Implemented OCTET STRING decoder.
* Implemented BIT STRING decoder.
0.6: 2003-Dec-30
* First decoding of a BER-encoded structure!
0.5: 2003-Dec-28
* Framework and most of the compiler backbone coding done.
0.1: 2003-Nov-28
* Programming started.
QUICK START INSTALLATION
========================
./configure # Configure the build infrastructure for your platform
make # Build the libraries and the compiler
make check # Ensure that the code is still behaving well
# after compiling on your platform
make install # Install the compiler into standard location
QUICK USAGE GUIDE
=================
For usage guide and more information please refer to README file.
libasn1compiler
libasn1parser
libasn1print
libasn1fix
skeletons
examples
tests
asn1c
doc
SUBDIRS = \
libasn1parser libasn1print \
libasn1fix libasn1compiler \
skeletons examples tests \
doc asn1c
EXTRA_DIST = BUGS MANIFEST
This diff is collapsed.
WHAT TO READ?
=============
For quick installation tips read INSTALL.
For more complete documentation on this compiler and on using the
results of compilation please look into ./doc directory.
An excellent book on ASN.1 is written by Olivier Dubuisson:
"ASN.1 Communication between heterogeneous systems", ISBN:0-12-6333361-0.
QUICK START
===========
After building [and installing] the compiler (see INSTALL), you may use
the asn1c command to compile the ASN.1 specification:
asn1c <spec.asn1>
If several specifications contain interdependencies, all of them must be
specified:
asn1c <spec1.asn1> <spec2.asn1> ...
The ./examples directory contains several ASN.1 modules and a script to
extract ASN.1 modules from RFC documents. To compile X.509 PKI module:
./asn1c/asn1c -P ./examples/*PKIX*93*.asn1
In this example, -P option is used to instruct the compiler to print the
compiled text on the standard output instead of creating multiple .c
and .h files for every ASN.1 type found inside the specified files.
This is useful for debugging and tests automation.
The compiler -E and -EF options are used for testing the parser and
the semantic fixer, respectively. These options will instruct the compiler
to dump out the parsed (and fixed) ASN.1 specification as it was
"understood" by the compiler. It might be useful for checking
whether a particular syntactic construction is properly supported
by the compiler.
asn1c -EF <spec-to-test.asn1>
MODEL OF OPERATION
==================
The asn1c compiler works by processing the ASN.1 module specification
in several stages:
1. In the first stage, the ASN.1 file is parsed.
(Parsing produces an ASN.1 syntax tree for the subsequent levels.)
2. In the second stage, the syntax tree is "fixed".
(Fixing is done by checking the tree for semantic errors
and by transforming the tree into the canonical representation.)
3. In the third stage, the syntax tree is compiled into the target language.
There are several command-line options reserved for printing the results
after each stage of operation:
<parser> => print (-E)
<parser> => <fixer> => print (-E -F)
<parser> => <fixer> => <compiler> => print (-P)
<parser> => <fixer> => <compiler> => save-compiled [default]
--
Lev Walkin
vlm@lionet.info
MAJOR:
1. Support for the explicit subtype constraints:
Name ::= IA5String (FROM("A".."Z"))
Status: in progress.
2. Support for Information Object Classes.
Status: support for parsing IOCs is mostly present. Support for slicing
the IOCs to produce "views" is not yet designed.
3. Support for PER encoding. Requires advanced subtype constraints support (#1)
4. Support for XER encoding.
MISC:
1. Make sure asn1_DEF_<TYPE>_tags is not an empty structure.
This diff is collapsed.
SUBDIRS = . tests
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = \
-I${top_srcdir}/libasn1compiler \
-I${top_srcdir}/libasn1parser \
-I${top_srcdir}/libasn1print \
-I${top_srcdir}/libasn1fix \
-DDATADIR=\"${pkgdatadir}\"
LDADD = \
${top_builddir}/libasn1parser/libasn1parser.la \
${top_builddir}/libasn1fix/libasn1fix.la \
${top_builddir}/libasn1print/libasn1print.la \
${top_builddir}/libasn1compiler/libasn1compiler.la
bin_PROGRAMS = asn1c
dist_man1_MANS = asn1c.1
check_SCRIPTS = check-parsing.sh
TESTS = check-parsing.sh
EXTRA_DIST = check-parsing.sh
CLEANFILES = .check-parsing.*.tmp
This diff is collapsed.
The ASN.1 Compiler
.de Id
..
.Id $Id"
.TH ASN1C 1 "\*(Dt" "ASN.1 Compiler" "ASN.1 Compiler"
.SH NAME
asn1c \- ASN.1 Compiler
.ND ASN.1 compiler
.SH SYNOPSIS
.B asn1c
.RI "[ " option " | " filename " ].\|.\|."
.SH DESCRIPTION
asn1c is a tool to compile the ASN.1 specifications into C language structures
and accompanying routines to perform data encoding and decoding.
.SH OPTIONS
.TP
.B Overall Options
\-E
\-F
\-L
\-N
\-P
.RI "\-S " directory
\-R
.TP
.B Language Options
.br
\-ftypes88
\-fnative-integers
\-fno-c99
\-funnamed-unions
.TP
.B Warning Options
.br
\-Werror
\-Wdebug-lexer
\-Wdebug-fixer
\-Wdebug-compiler
.SH OVERALL OPTIONS
.TP
.B \-E
Stop after the parsing stage. The output is reconstructed ASN.1
specification code, which is sent to the standard output.
.TP
.B \-F
Used together with \c
.B \-E\c
, instructs the compiler to stop after the ASN.1 syntax
tree fixing stage and dump the reconstructed ASN.1 specification
to the standard output.
.TP
.B \-L
Generate "-- #line" comments in
.B -E
output.
.TP
.B \-N
Do not generate certain type of comments in
.B -E
output.
.TP
.B \-P
Dump the compiled output to the standard output instead of creating the
target language files on disk.
.TP
.B \-S directory
Use the specified directory with ASN.1 skeleton files.
.TP
.B \-R
Restrict the compiler to generate only the ASN.1 tables,
omitting the usual support code.
.SH LANGUAGE OPTIONS
.TP
.B \-ftypes88
Use only ASN.1:1988 embedded types.
.TP
.B \-fnative-integers
Use native machine's integer types whenever possible,
instead of the complex ASN.1 INTEGER and ENUMERATED types.
.TP
.B \-fno-c99
Disable use of certain C99 extensions, like designated initializers.
.TP
.B \-funnamed-unions
Enable unnamed unions in structures definitions.
.SH WARNING OPTIONS
.TP
.B \-Werror
Treat warnings as errors; abort if any warning is produced.
.TP
.B \-Wdebug-lexer
Enable lexer debugging during the ASN.1 parsing stage.
.TP
.B \-Wdebug-fixer
Enable ASN.1 syntax tree fixer debugging during the fixing stage.
.TP
.B \-Wdebug-compiler
Enable debugging during the actual compile time.
.SH AUTHORS
Lev Walkin <vlm@lionet.info>
/*
* This is the program that connects the libasn1* libraries together.
* It uses them in turn to parse, fix and then compile or print the ASN.1 tree.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h> /* for stat(2) */
#include <unistd.h>
#include <libgen.h> /* for basename(3) */
#include <sysexits.h> /* for EX_USAGE */
#include <assert.h>
#include <errno.h>
#include <asn1parser.h> /* Parse the ASN.1 file and build a tree */
#include <asn1fix.h> /* Fix the ASN.1 tree */
#include <asn1print.h> /* Print the ASN.1 tree */
#include <asn1compiler.h> /* Compile the ASN.1 tree */
static void usage(char *av0); /* Print the Usage screen and exit(EX_USAGE) */
int
main(int ac, char **av) {
enum asn1p_flags asn1_parser_flags = A1P_NOFLAGS;
enum asn1f_flags asn1_fixer_flags = A1F_NOFLAGS;
enum asn1c_flags asn1_compiler_flags = A1C_NOFLAGS;
int print_arg__print_out = 0; /* Don't compile, just print parsed */
int print_arg__fix_n_print = 0; /* Fix and print */
enum asn1print_flags_e print_arg__flags = APF_NOFLAGS;
int warnings_as_errors = 0; /* Treat warnings as errors */
char *skeletons_dir = NULL; /* Directory with supplementary stuff */
asn1p_t *asn = 0; /* An ASN.1 parsed tree */
int ret; /* Return value from misc functions */
int ch; /* Command line character */
int i; /* Index in some loops */
/*
* Process command-line options.
*/
while((ch = getopt(ac, av, "EFf:LNPRS:W:")) != -1)
switch(ch) {
case 'E':
print_arg__print_out = 1;
break;
case 'F':
print_arg__fix_n_print = 1;
break;
case 'f':
if(strcmp(optarg, "types88") == 0) {
asn1_parser_flags |= A1P_TYPES_RESTRICT_TO_1988;
} else if(strcmp(optarg, "constr90") == 0) {
asn1_parser_flags |= A1P_CONSTRUCTS_RESTRICT_TO_1990;
} else if(strcmp(optarg, "native-integers") == 0) {
asn1_compiler_flags |= A1C_USE_NATIVE_INTEGERS;
} else if(strcmp(optarg, "no-c99") == 0) {
asn1_compiler_flags |= A1C_NO_C99;
} else if(strcmp(optarg, "unnamed-unions") == 0) {
asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
} else {
fprintf(stderr, "-f%s: Invalid argument\n", optarg);
exit(EX_USAGE);
}
break;
case 'L':
print_arg__flags = APF_LINE_COMMENTS;
break;
case 'N':
print_arg__flags = APF_NO_SOURCE_COMMENTS;
break;
case 'P':
asn1_compiler_flags |= A1C_PRINT_COMPILED;
break;
case 'R':
asn1_compiler_flags |= A1C_OMIT_SUPPORT_CODE;
break;
case 'S':
skeletons_dir = optarg;
break;
case 'W':
if(strcmp(optarg, "error") == 0) {
warnings_as_errors = 1;
break;
} else if(strcmp(optarg, "debug-lexer") == 0) {
asn1_parser_flags |= A1P_LEXER_DEBUG;
break;
} else if(strcmp(optarg, "debug-fixer") == 0) {
asn1_fixer_flags |= A1F_DEBUG;
break;
} else if(strcmp(optarg, "debug-compiler") == 0) {
asn1_compiler_flags |= A1C_DEBUG;
break;
} else {
fprintf(stderr, "-W%s: Invalid argument\n", optarg);
exit(EX_USAGE);
}
break;
default:
usage(av[0]);
}
/*
* Validate the options combination.
*/
if(!print_arg__print_out) {
if(print_arg__fix_n_print) {
fprintf(stderr, "Error: -F requires -E\n");
exit(EX_USAGE);
}
}
/*
* Ensure that there are some input files present.
*/
if(ac > optind) {
ac -= optind;
av += optind;
} else {
fprintf(stderr, "%s: No input files specified\n",
basename(av[0]));
exit(1);
}
/*
* Iterate over input files and parse each.
* All syntax trees from all files will be bundled together.
*/
for(i = 0; i < ac; i++) {
asn1p_t *new_asn;
new_asn = asn1p_parse_file(av[i], asn1_parser_flags);
if(new_asn == NULL) {
fprintf(stderr, "Cannot parse \"%s\"\n", av[i]);
exit(EX_DATAERR);
}
/*
* Bundle the parsed tree with existing one.
*/
if(asn) {
asn1p_module_t *mod;
while((mod = TQ_REMOVE(&(new_asn->modules), mod_next)))
TQ_ADD(&(asn->modules), mod, mod_next);
asn1p_free(new_asn);
} else {
asn = new_asn;
}
}
/*
* Dump the parsed ASN.1 tree if -E specified and -F is not given.
*/
if(print_arg__print_out && !print_arg__fix_n_print) {
if(asn1print(asn, print_arg__flags))
exit(EX_SOFTWARE);
return 0;
}
/*
* Process the ASN.1 specification: perform semantic checks,
* expand references, etc, etc.
* This function will emit necessary warnings and error messages.
*/
ret = asn1f_process(asn, asn1_fixer_flags,
NULL /* default fprintf(stderr) */);
switch(ret) {
case 1:
if(!warnings_as_errors)
/* Fall through */
case 0:
break; /* All clear */
case -1:
exit(EX_DATAERR); /* Fatal failure */
}
/*
* Dump the parsed ASN.1 tree if -E specified and -F is given.
*/
if(print_arg__print_out && print_arg__fix_n_print) {
if(asn1print(asn, print_arg__flags))
exit(EX_SOFTWARE);
return 0;
}
/*
* Make sure the skeleton directory is out there.
*/
if(skeletons_dir == NULL) {
struct stat sb;
skeletons_dir = DATADIR;
if((av[-optind][0] == '.' || av[-optind][1] == '/')
&& stat(skeletons_dir, &sb)) {
/*
* The default skeletons directory does not exist,
* compute it from my file name:
* ./asn1c/asn1c -> ./skeletons
*/
char *p;
int len;
p = dirname(av[-optind]);
len = strlen(p) + sizeof("/../skeletons");
skeletons_dir = alloca(len);
snprintf(skeletons_dir, len, "%s/../skeletons", p);
if(stat(skeletons_dir, &sb)) {
fprintf(stderr,
"WARNING: skeletons are neither in "
"\"%s\" nor in \"%s\"!\n",
DATADIR, skeletons_dir);
if(warnings_as_errors)
exit(EX_SOFTWARE);
}
}
}
/*
* Compile the ASN.1 tree into a set of source files
* of another language.
*/
if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags)) {
exit(EX_SOFTWARE);
}
return 0;
}
/*
* Print the usage screen and exit(EX_USAGE).
*/
static void
usage(char *av0) {
fprintf(stderr,
"ASN.1 Compiler, v" VERSION "\n"
"Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>\n"
"Usage: %s [options] ...\n"
"Where [options] are:\n"
"\t-E\tRun only the ASN.1 parser and print out the tree\n"
"\t-F\tDuring -E operation, also perform tree fixing\n"
"\t-L\tGenerate \"-- #line\" comments in -E output\n"
"\t-N\tDo not generate certain type of comments in -E output\n"
"\n"
"\t-P \tConcatenate and print the compiled text\n"
"\t-S <dir>\tDirectory with support (skeleton?) files\n"
"\t \t(Default is \"%s\")\n"
"\t-R \tRestrict output (tables only, no support code)\n"
"\n"
"\t-ftypes88\tUse only ASN.1:1988 embedded types\n"
/*
"\t-fconstr90\tUse only ASN.1:1990 constructs (not available)\n"
*/
"\t-fnative-integers\tUse native integers where possible\n"
"\t-fno-c99\tDisable C99 extensions\n"
"\t-funnamed-unions\tEnable unnamed unions in structures\n"
"\n"
"\t-Werror \tTreat warnings as errors; abort if any warning\n"
"\t-Wdebug-lexer\tEnable verbose debugging output from lexer\n"
"\t-Wdebug-fixer\tDebug ASN.1 semantics processor\n"
"\t-Wdebug-compiler\tDebug ASN.1 compiler\n"
,
basename(av0), DATADIR
);
exit(EX_USAGE);
}
#!/bin/sh
tmpfile=".check-parsing.$$.tmp"
ec=0
for ref in ../tests/*.asn1.-*; do
src=`echo "$ref" | sed -e 's/\.-[a-zA-Z]*$//'`
flags=`echo "$ref" | sed -e 's/.*\.-//'`
echo "Checking $src against $ref"
./asn1c "-$flags" "$src" > "$tmpfile" || ec=$?
if [ $? = 0 ]; then
diff "$ref" "$tmpfile" || ec=$?
fi
rm -f "$tmpfile"
done
exit $ec
check_SCRIPTS = ./check-assembly.sh
TESTS_ENVIRONMENT= ./check-assembly.sh
TESTS = check-*.c
EXTRA_DIST = ${check_SCRIPTS} check-*.c
clean:
for t in test-*; do rm -rf $$t; done
# Makefile.in generated automatically by automake 1.5 from Makefile.am.
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
ADD_CFLAGS = @ADD_CFLAGS@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AWK = @AWK@
CC = @CC@
CONFIGURE_DEPENDS = @CONFIGURE_DEPENDS@
CPP = @CPP@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
EXEEXT = @EXEEXT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LEX = @LEX@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAINT = @MAINT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PATH = @PATH@
RANLIB = @RANLIB@
VERSION = @VERSION@
YACC = @YACC@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
check_SCRIPTS = ./check-assembly.sh
TESTS_ENVIRONMENT = ./check-assembly.sh
TESTS = check-*.c
EXTRA_DIST = ${check_SCRIPTS} check-*.c
subdir = asn1c/tests
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
DIST_COMMON = README Makefile.am Makefile.in
all: all-am
.SUFFIXES:
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu asn1c/tests/Makefile
Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && \
CONFIG_HEADERS= CONFIG_LINKS= \
CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
uninstall-info-am:
tags: TAGS
TAGS:
check-TESTS: $(TESTS)
@failed=0; all=0; xfail=0; xpass=0; \
srcdir=$(srcdir); export srcdir; \
list='$(TESTS)'; \
if test -n "$$list"; then \
for tst in $$list; do \
if test -f ./$$tst; then dir=./; \
elif test -f $$tst; then dir=; \
else dir="$(srcdir)/"; fi; \
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*" $$tst "*) \
xpass=`expr $$xpass + 1`; \
failed=`expr $$failed + 1`; \
echo "XPASS: $$tst"; \
;; \
*) \
echo "PASS: $$tst"; \
;; \
esac; \
elif test $$? -ne 77; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*" $$tst "*) \
xfail=`expr $$xfail + 1`; \
echo "XFAIL: $$tst"; \
;; \
*) \
failed=`expr $$failed + 1`; \
echo "FAIL: $$tst"; \
;; \
esac; \
fi; \
done; \
if test "$$failed" -eq 0; then \
if test "$$xfail" -eq 0; then \
banner="All $$all tests passed"; \
else \
banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
fi; \
else \
if test "$$xpass" -eq 0; then \
banner="$$failed of $$all tests failed"; \
else \
banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
fi; \
fi; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
echo "$$dashes"; \
test "$$failed" -eq 0; \
fi
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
if test -f $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
$(mkinstalldirs) "$(distdir)/$$dir"; \
fi; \
if test -d $$d/$$file; then \
cp -pR $$d/$$file $(distdir) \
|| exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic distclean-libtool
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-TESTS check-am clean clean-generic \
clean-libtool distclean distclean-generic distclean-libtool \
distdir dvi dvi-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool uninstall uninstall-am uninstall-info-am
clean:
for t in test-*; do rm -rf $$t; done
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
This is a very funny test automation. The name of the check-*.c file is used
as a pointer to the file in ../..//tests/*-*.asn1. This file is compiled
using the asn1c from above directory. Then, everything is build together
in a temporary directory with a check-*.c used as a testing engine.
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T1.h>
uint8_t buf1[] = {
32 | 16, /* [UNIVERSAL 16], constructed */
12, /* L */
/* INTEGER a */
((2 << 6) + 0), /* [0], primitive */
2, /* L */
150,
70,
/* b [1] EXPLICIT CHOICE */
32 | ((2 << 6) + 1), /* [1] */
3, /* L */
((2 << 6) + 1), /* [1] */
1,
'i',
/* UTF8String c */
((2 << 6) + 2), /* [2], primitive */
1, /* L */
'x'
};
uint8_t buf2[128];
int buf2_pos;
static int
buf2_fill(const void *buffer, size_t size, void *app_key) {
if(buf2_pos + size > sizeof(buf2))
return -1;
memcpy(buf2 + buf2_pos, buffer, size);
buf2_pos += size;
return 0;
}
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
T1_t t, *tp;
ber_dec_rval_t rval;
der_enc_rval_t erval;
int i;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p\n", buf);
rval = ber_decode(&asn1_DEF_T1, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(t.a.size == 2);
assert(t.b.present == b_PR_n);
assert(t.b.choice.n.size == 1);
assert(t.b.choice.n.buf[0] == 'i');
assert(t.c.size == 1);
assert(t.c.buf[0] == 'x');
} else {
if(rval.code == RC_OK) {
assert(t.a.size != 2
|| t.b.present != b_PR_n
|| t.b.choice.n.size != 1
|| t.c.size != 1
);
}
assert(rval.consumed <= consumed);
return;
}
fprintf(stderr, "=> Re-creating using DER encoder <=\n");
/*
* Try to re-create using DER encoding.
*/
buf2_pos = 0;
erval = der_encode(&asn1_DEF_T1, tp, buf2_fill, 0);
assert(erval.encoded != -1);
if(erval.encoded != sizeof(buf1)) {
printf("%d != %d\n", (int)erval.encoded, (int)sizeof(buf1));
}
assert(erval.encoded == sizeof(buf1));
for(i = 0; i < sizeof(buf1); i++) {
if(buf1[i] != buf2[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
i,
buf1[i], buf2[i],
buf1[i], buf2[i]
);
}
assert(buf1[i] == buf2[i]);
}
fprintf(stderr, "=== PRINT ===\n");
asn_fprint(stderr, &asn1_DEF_T1, tp);
fprintf(stderr, "=== EOF ===\n");
}
static void
try_corrupt(uint8_t *buf, int size) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(tmp[loc] >= 70);
do { tmp[loc] ^= random(); } while(tmp[loc] == buf[loc]);
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, size);
}
}
int
main(int ac, char **av) {
check(1, buf1, sizeof(buf1), sizeof(buf1));
try_corrupt(buf1, sizeof(buf1));
check(1, buf1, sizeof(buf1) + 10, sizeof(buf1));
return 0;
}
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf1[] = {
32 | ((2 << 6) + 5), /* [5], constructed */
17, /* L */
32 | 16, /* [UNIVERSAL 16], constructed */
15, /* L */
/* INTEGER a */
2, /* [UNIVERSAL 2] */
2, /* L */
150,
70,
/* INTEGER b */
((2 << 6) + 0), /* [0] */
1, /* L */
123,
/* INTEGER c */
((2 << 6) + 1), /* [1] */
1, /* L */
123,
/* INTEGER d */
32 | ((2 << 6) + 5), /* [5], constructed */
3,
2,
1, /* L */
123,
};
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
T_t t, *tp;
ber_dec_rval_t rval;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p\n", buf);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
} else {
if(rval.code == RC_OK) {
assert(t.a.size != 2
|| (!t.b || t.b->size != 1)
|| (!t.c || t.c->size != 1)
|| t.d.size != 1
);
}
assert(rval.consumed <= consumed);
}
}
static void
try_corrupt(uint8_t *buf, int size) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(tmp[loc] >= 70);
do { tmp[loc] ^= random(); } while(tmp[loc] == buf[loc]);
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, size);
}
}
int
main(int ac, char **av) {
check(1, buf1, sizeof(buf1), sizeof(buf1));
try_corrupt(buf1, sizeof(buf1));
return 0;
}
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf1[] = {
32 | 16, /* [UNIVERSAL 16], constructed */
128, /* L */
/* a INTEGER */
2, /* [UNIVERSAL 2] */
2, /* L */
150,
70,
/* b BOOLEAN */
128 | 2, /* [2] */
1, /* L */
0xff,
/* c NULL */
5, /* [UNIVERSAL 5] */
0, /* L */
/* d ENUMERATED */
10, /* [UNIVERSAL 10] */
1, /* L */
222,
4, /* [UNIVERSAL 4] */
3, /* L */
'x',
'y',
'z',
/* f OCTET STRING */
32 | 4, /* [UNIVERSAL 4], constructed */
128, /* L indefinite */
4, /* [UNIVERSAL 4], primitive */
2,
'l',
'o',
32 | 4, /* [UNIVERSAL 4], recursively constructed */
128,
4,
1,
'v',
4,
2,
'e',
'_',
0,
0,
4, /* [UNIVERSAL 4], primitive */
2,
'i',
't',
0,
0,
/* g BIT STRING */
3, /* [UNIVERSAL 3], primitive */
3, /* L */
2, /* Skip 2 bits */
147,
150, /* => 148 */
/* h BIT STRING */
32 | 3, /* [UNIVERSAL 3], constructed */
128, /* L indefinite */
3, /* [UNIVERSAL 3], primitive */
3, /* L */
0, /* Skip 0 bits */
140,
141,
3, /* [UNIVERSAL 3], primitive */
2, /* L */
1, /* Skip 1 bit */
143, /* => 142 */
0, /* End of f */
0,
0, /* End of the whole structure */
0,
/* Three bytes of planned leftover */
111, 222, 223
};
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
T_t t, *tp;
ber_dec_rval_t rval;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p (%d)\n", buf, (int)size);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d, expected %d\n",
(int)rval.code, (int)rval.consumed, (int)consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(strcmp(t.e->buf, "xyz") == 0);
assert(strcmp(t.f->buf, "love_it") == 0);
assert(t.g->size == 3);
assert(t.g->buf[0] == 2);
assert(t.g->buf[1] == 147);
assert(t.g->buf[2] == 148);
printf("%d\n", t.h->buf[3]);
assert(t.h->size == 4);
assert(t.h->buf[0] == 1);
assert(t.h->buf[1] == 140);
assert(t.h->buf[2] == 141);
assert(t.h->buf[3] == 142);
} else {
if(rval.code == RC_OK) {
assert(t.a.size != 2
|| !t.d
|| t.d->size != 1
|| !t.e
|| t.e->size != 3
|| !t.f
|| t.f->size != 7
|| !t.g
|| t.g->size != 3
|| !t.h
|| t.h->size != 4
);
}
fprintf(stderr, "%d %d\n", (int)rval.consumed, (int)consumed);
assert(rval.consumed <= consumed);
}
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
}
static void
try_corrupt(uint8_t *buf, int size, int allow_consume) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(
loc == 44 /* bit skips */
|| loc == 51 /* bit skips */
|| loc == 56 /* bit skips */
|| tmp[loc] >= 70);
do { tmp[loc] = buf[loc] ^ random(); } while(
(tmp[loc] == buf[loc])
|| (buf[loc] == 0 && tmp[loc] == 0x80));
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, allow_consume);
}
}
static void
partial_read(uint8_t *buf, int size) {
T_t t, *tp;
ber_dec_rval_t rval;
int i1, i2;
uint8_t *buf1 = alloca(size);
uint8_t *buf2 = alloca(size);
uint8_t *buf3 = alloca(size);
fprintf(stderr, "\nPartial read sequence...\n");
/*
* Divide the space (size) into three blocks in various combinations:
* |<----->i1<----->i2<----->|
* ^ buf ^ buf+size
* Try to read block by block.
*/
for(i1 = 0; i1 < size; i1++) {
for(i2 = i1; i2 < size; i2++) {
uint8_t *chunk1 = buf;
int size1 = i1;
uint8_t *chunk2 = buf + size1;
int size2 = i2 - i1;
uint8_t *chunk3 = buf + size1 + size2;
int size3 = size - size1 - size2;
fprintf(stderr, "\n%d:{%d, %d, %d}...\n",
size, size1, size2, size3);
memset(buf1, 0, size);
memset(buf2, 0, size);
memset(buf3, 0, size);
memcpy(buf1, chunk1, size1);
memcpy(buf2, chunk2, size2);
memcpy(buf3, chunk3, size3);
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "=> Chunk 1 (%d):\n", size1);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf1, size1);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size1);
if(rval.consumed < size1) {
int leftover = size1 - rval.consumed;
memcpy(buf2, buf1 + rval.consumed, leftover);
memcpy(buf2 + leftover, chunk2, size2);
size2 += leftover;
}
fprintf(stderr, "=> Chunk 2 (%d):\n", size2);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf2, size2);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size2);
if(rval.consumed < size2) {
int leftover = size2 - rval.consumed;
memcpy(buf3, buf2 + rval.consumed, leftover);
memcpy(buf3 + leftover, chunk3, size3);
size3 += leftover;
}
fprintf(stderr, "=> Chunk 3 (%d):\n", size3);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf3, size3);
assert(rval.code == RC_OK);
assert(rval.consumed == size3);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
}
}
}
int
main(int ac, char **av) {
/* Check that the full buffer may be decoded normally */
check(1, buf1, sizeof(buf1), sizeof(buf1) - 3);
/* Check that some types of buffer corruptions will lead to failure */
try_corrupt(buf1, sizeof(buf1) - 3, sizeof(buf1) - 3);
/* Split the buffer in parts and check decoder restartability */
partial_read(buf1, sizeof(buf1) - 3);
return 0;
}
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf1[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
8, /* L */
/* a INTEGER */
64 | 3, /* [APPLICATION 3] */
1, /* L */
96,
/* b IA5String */
22, /* [UNIVERSAL 22] */
3, /* L */
'x',
'y',
'z'
};
/*
* This buffer aims at checking the duplication.
*/
uint8_t buf2[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
8, /* L */
/* a INTEGER */
64 | 3, /* [APPLICATION 3] */
1, /* L */
96,
/* a INTEGER _again_ */
64 | 3, /* [APPLICATION 3] */
1, /* L */
97,
};
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
T_t t, *tp;
ber_dec_rval_t rval;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p\n", buf);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(t.a.size == 1);
assert(t.a.buf[0] == 96);
assert(t.b.size == 3);
assert(t.c == 0);
assert(strcmp(t.b.buf, "xyz") == 0);
} else {
if(rval.code == RC_OK) {
assert(t.a.size != 1
|| t.b.size != 3
|| !t.c
);
}
assert(rval.consumed <= consumed);
}
}
static void
try_corrupt(uint8_t *buf, int size) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(tmp[loc] >= 70);
do { tmp[loc] = buf[loc] ^ random(); } while(
(tmp[loc] == buf[loc])
|| (buf[loc] == 0 && tmp[loc] == 0x80));
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, size);
}
}
int
main(int ac, char **av) {
fprintf(stderr, "Must succeed:\n");
check(1, buf1, sizeof(buf1) + 20, sizeof(buf1));
fprintf(stderr, "\nMust fail:\n");
check(0, buf2, sizeof(buf2) + 1, 5);
fprintf(stderr, "\nPseudo-random buffer corruptions must fail\n");
try_corrupt(buf1, sizeof(buf1));
return 0;
}
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <Forest.h>
uint8_t buf1[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
128, /* L, indefinite */
32 | 16, /* [UNIVERSAL 16], constructed */
6, /* L */
/* height INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
100,
/* width INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
80,
32 | 16, /* [UNIVERSAL 16], constructed */
6, /* L */
/* height INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
110,
/* width INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
82,
0, /* End of forest */
0
};
uint8_t buf1_reconstr[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
16, /* L */
32 | 16, /* [UNIVERSAL 16], constructed */
6, /* L */
/* height INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
100,
/* width INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
80,
32 | 16, /* [UNIVERSAL 16], constructed */
6, /* L */
/* height INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
110,
/* width INTEGER */
2, /* [UNIVERSAL 2] */
1, /* L */
82
};
int buf_pos;
int bytes_compare(const void *bufferp, size_t size, void *key) {
const uint8_t *buffer = bufferp;
assert(buf_pos + size <= sizeof(buf1_reconstr));
fprintf(stderr, " writing %d (%d)\n", (int)size, buf_pos + (int)size);
for(; size; buf_pos++, size--, buffer++) {
if(buf1_reconstr[buf_pos] != *buffer) {
fprintf(stderr,
"Byte %d is different: %d != %d (%x != %x)\n",
buf_pos,
*buffer, buf1_reconstr[buf_pos],
*buffer, buf1_reconstr[buf_pos]
);
assert(buf1_reconstr[buf_pos] == *buffer);
}
}
return 0;
}
static void
check(int is_ok, uint8_t *buf, int size, int consumed) {
Forest_t t, *tp;
ber_dec_rval_t rval;
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "Buf %p\n", buf);
rval = ber_decode(&asn1_DEF_Forest, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
if(is_ok) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(t.list.count == 2);
assert(t.list.array[0]->height.size == 1);
assert(t.list.array[0]->width.size == 1);
assert(t.list.array[1]->height.size == 1);
assert(t.list.array[1]->width.size == 1);
} else {
if(rval.code == RC_OK) {
assert(t.list.count != 2
|| t.list.array[0]->height.size != 1
|| t.list.array[0]->width.size != 1
|| t.list.array[1]->height.size != 1
|| t.list.array[1]->width.size != 1
);
}
assert(rval.consumed <= consumed);
return;
}
/*
* Try to re-create the buffer.
*/
buf_pos = 0;
der_encode(&asn1_DEF_Forest, &t,
bytes_compare, buf1_reconstr);
assert(buf_pos == sizeof(buf1_reconstr));
asn_fprint(stderr, &asn1_DEF_Forest, &t);
asn1_DEF_Forest.free_struct(&asn1_DEF_Forest, &t, 1);
}
static void
try_corrupt(uint8_t *buf, int size) {
uint8_t *tmp;
int i;
fprintf(stderr, "\nCorrupting...\n");
tmp = alloca(size);
for(i = 0; i < 1000; i++) {
int loc;
memcpy(tmp, buf, size);
/* Corrupt random _non-value_ location. */
do { loc = random() % size; } while(tmp[loc] >= 70);
do { tmp[loc] = buf[loc] ^ random(); } while(
(tmp[loc] == buf[loc])
|| (buf[loc] == 0 && tmp[loc] == 0x80));
fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
i, loc, buf[loc], tmp[loc]);
check(0, tmp, size, size);
}
}
int
main(int ac, char **av) {
check(1, buf1, sizeof(buf1), sizeof(buf1));
try_corrupt(buf1, sizeof(buf1));
check(1, buf1, sizeof(buf1) + 20, sizeof(buf1));
return 0;
}
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <Programming.h>
int
main(int ac, char **av) {
Programming_t p;
memset(&p, 0, sizeof(p));
/*
* No plans to fill it up: just checking whether it compiles or not.
*/
return 0;
}
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
int
main(int ac, char **av) {
T_t t;
memset(&t, 0, sizeof(t));
/*
* No plans to fill it up: just checking whether it compiles or not.
*/
return 0;
}
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf1[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
13, /* L */
/* b CHOICE { b2 ObjectDescriptor }*/
7, /* [UNIVERSAL 7] */
1, /* L */
'z',
/* c BOOLEAN */
1, /* [UNIVERSAL 1] */
0, /* L */
/* a NumericString */
18, /* [UNIVERSAL 18] */
2, /* L */
'n',
's',
/* d.r-oid RELATIVE-OID */
13, /* [UNIVERSAL 13] */
2, /* L */
85,
79,
};
uint8_t buf1_reconstr[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
14, /* L */
/* c BOOLEAN */
1, /* [UNIVERSAL 1] */
1, /* L */
0,
/* b CHOICE { b2 ObjectDescriptor }*/
7, /* [UNIVERSAL 7] */
1, /* L */
'z',
/* d.r-oid RELATIVE-OID */
13, /* [UNIVERSAL 1] */
2, /* L */
85,
79,
/* a NumericString */
18, /* [UNIVERSAL 18] */
2, /* L */
'n',
's'
};
uint8_t buf2[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
13, /* L */
/* a NumericString */
18, /* [UNIVERSAL 18] */
2, /* L */
'n',
's',
/* c BOOLEAN */
1, /* [UNIVERSAL 1] */
1, /* L */
2, /* True */
/* b CHOICE { b1 IA5String }*/
22, /* [UNIVERSAL 22] */
1, /* L */
'z',
/* d.oid RELATIVE-OID */
6, /* [UNIVERSAL 6] */
1, /* L */
81,
};
uint8_t buf2_reconstr[] = {
32 | 17, /* [UNIVERSAL 17], constructed */
13, /* L */
/* c BOOLEAN */
1, /* [UNIVERSAL 1] */
1, /* L */
0xff, /* Canonical True */
/* d.oid RELATIVE-OID */
6, /* [UNIVERSAL 6] */
1, /* L */
81,
/* a NumericString */
18, /* [UNIVERSAL 18] */
2, /* L */
'n',
's',
/* b CHOICE { b1 IA5String }*/
22, /* [UNIVERSAL 22] */
1, /* L */
'z'
};
static void
check(T_t *tp, uint8_t *buf, int size, int consumed) {
ber_dec_rval_t rval;
tp = memset(tp, 0, sizeof(*tp));
fprintf(stderr, "Buf %p (%d)\n", buf, size);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(strcmp(tp->a.buf, "ns") == 0);
assert(strcmp(tp->b.choice.b1.buf, "z") == 0
&& strcmp(tp->b.choice.b2.buf, "z") == 0);
}
int buf_pos;
int buf_size;
uint8_t *buf;
static int
buf_fill(const void *buffer, size_t size, void *app_key) {
if(buf_pos + size > buf_size) {
fprintf(stderr, "%d + %d > %d\n", buf_pos, (int)size, buf_size);
return -1;
}
memcpy(buf + buf_pos, buffer, size);
buf_pos += size;
fprintf(stderr, " written %d (%d)\n", (int)size, buf_pos);
return 0;
}
void
compare(T_t *tp, uint8_t *cmp_buf, int cmp_buf_size) {
der_enc_rval_t erval;
int i;
buf_size = cmp_buf_size + 100;
buf = alloca(buf_size);
buf_pos = 0;
/*
* Try to re-create using DER encoding.
*/
erval = der_encode(&asn1_DEF_T, tp, buf_fill, 0);
assert(erval.encoded != -1);
if(erval.encoded != cmp_buf_size) {
printf("%d != %d\n", erval.encoded, cmp_buf_size);
}
assert(erval.encoded == cmp_buf_size);
for(i = 0; i < cmp_buf_size; i++) {
if(buf[i] != cmp_buf[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
i,
buf[i], cmp_buf[i],
buf[i], cmp_buf[i]
);
}
assert(buf[i] == cmp_buf[i]);
}
}
static void
partial_read(uint8_t *buf, int size) {
T_t t, *tp;
ber_dec_rval_t rval;
int i1, i2;
uint8_t *buf1 = alloca(size);
uint8_t *buf2 = alloca(size);
uint8_t *buf3 = alloca(size);
fprintf(stderr, "\nPartial read sequence...\n");
/*
* Divide the space (size) into three blocks in various combinations:
* |<----->i1<----->i2<----->|
* ^ buf ^ buf+size
* Try to read block by block.
*/
for(i1 = 0; i1 < size; i1++) {
for(i2 = i1; i2 < size; i2++) {
uint8_t *chunk1 = buf;
int size1 = i1;
uint8_t *chunk2 = buf + size1;
int size2 = i2 - i1;
uint8_t *chunk3 = buf + size1 + size2;
int size3 = size - size1 - size2;
fprintf(stderr, "\n%d:{%d, %d, %d}...\n",
size, size1, size2, size3);
memset(buf1, 0, size);
memset(buf2, 0, size);
memset(buf3, 0, size);
memcpy(buf1, chunk1, size1);
memcpy(buf2, chunk2, size2);
memcpy(buf3, chunk3, size3);
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "=> Chunk 1 (%d):\n", size1);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf1, size1);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size1);
if(rval.consumed < size1) {
int leftover = size1 - rval.consumed;
memcpy(buf2, buf1 + rval.consumed, leftover);
memcpy(buf2 + leftover, chunk2, size2);
size2 += leftover;
}
fprintf(stderr, "=> Chunk 2 (%d):\n", size2);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf2, size2);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size2);
if(rval.consumed < size2) {
int leftover = size2 - rval.consumed;
memcpy(buf3, buf2 + rval.consumed, leftover);
memcpy(buf3 + leftover, chunk3, size3);
size3 += leftover;
}
fprintf(stderr, "=> Chunk 3 (%d):\n", size3);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf3, size3);
assert(rval.code == RC_OK);
assert(rval.consumed == size3);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
}
}
}
int
main(int ac, char **av) {
T_t t;
check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Split the buffer in parts and check decoder restartability */
partial_read(buf1, sizeof(buf1));
return 0;
}
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <T.h>
uint8_t buf0[] = {
32 | ((2 << 6) + 1), /* [1], constructed */
18,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
16, /* L */
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
};
uint8_t buf0_reconstr[] = {
32 | ((2 << 6) + 1), /* [1], constructed */
18,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
16, /* L */
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
};
uint8_t buf1[] = {
32 | (2 << 6), /* [0], constructed */
0x80 | 1, /* L */
134,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
0x80 | 1, /* L */
128,
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
/* alpha [1] IMPLICIT INTEGER OPTIONAL */
(2 << 6) + 1, /* [1] */
1, /* L */
75,
};
uint8_t buf1_reconstr[] = {
32 | (2 << 6), /* [0], constructed */
0x80 | 1, /* L */
134,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
0x80 | 1, /* L */
128,
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
/* alpha [1] IMPLICIT INTEGER OPTIONAL */
(2 << 6) + 1, /* [1] */
1, /* L */
75,
};
uint8_t buf2[] = {
32 | ((2 << 6) + 1), /* [1], constructed */
0x80 | 1, /* L */
134,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
0x80 | 1, /* L */
128,
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
/* beta [2] IMPLICIT INTEGER OPTIONAL */
(2 << 6) + 2, /* [2] */
1, /* L */
75,
};
uint8_t buf2_reconstr[] = {
32 | ((2 << 6) + 1), /* [1], constructed */
0x80 | 1, /* L */
134,
/* string [0] IMPLICIT UTF8String, */
(2 << 6), /* [0] */
0x80 | 1, /* L */
128,
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
/* beta [2] IMPLICIT INTEGER OPTIONAL */
(2 << 6) + 2, /* [2] */
1, /* L */
75,
};
static void
check(T_t *tp, uint8_t *buf, int size, int consumed) {
ber_dec_rval_t rval;
tp = memset(tp, 0, sizeof(*tp));
fprintf(stderr, "Buf %p (%d)\n", buf, size);
rval = ber_decode(&asn1_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %d\n",
(int)rval.code, (int)rval.consumed);
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
/*
assert(tp->string.size == 128);
assert(strncmp(tp->string.buf, "zz") == 0);
assert(strcmp(tp->b.choice.b1.buf, "z") == 0
&& strcmp(tp->b.choice.b2.buf, "z") == 0);
*/
}
int buf_pos;
int buf_size;
uint8_t *buf;
static int
buf_fill(const void *buffer, size_t size, void *app_key) {
if(buf_pos + size > buf_size) {
fprintf(stderr, "%d + %d > %d\n", buf_pos, (int)size, buf_size);
return -1;
}
memcpy(buf + buf_pos, buffer, size);
buf_pos += size;
fprintf(stderr, " written %d (%d)\n", (int)size, buf_pos);
return 0;
}
void
compare(T_t *tp, uint8_t *cmp_buf, int cmp_buf_size) {
der_enc_rval_t erval;
int i;
buf_size = cmp_buf_size + 100;
buf = alloca(buf_size);
buf_pos = 0;
/*
* Try to re-create using DER encoding.
*/
erval = der_encode(&asn1_DEF_T, tp, buf_fill, 0);
assert(erval.encoded != -1);
if(erval.encoded != cmp_buf_size) {
printf("%d != %d\n", erval.encoded, cmp_buf_size);
}
assert(erval.encoded == cmp_buf_size);
for(i = 0; i < cmp_buf_size; i++) {
if(buf[i] != cmp_buf[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
i,
buf[i], cmp_buf[i],
buf[i], cmp_buf[i]
);
}
assert(buf[i] == cmp_buf[i]);
}
}
static void
partial_read(uint8_t *buf, int size) {
T_t t, *tp;
ber_dec_rval_t rval;
int i1, i2;
uint8_t *buf1 = alloca(size);
uint8_t *buf2 = alloca(size);
uint8_t *buf3 = alloca(size);
fprintf(stderr, "\nPartial read sequence...\n");
/*
* Divide the space (size) into three blocks in various combinations:
* |<----->i1<----->i2<----->|
* ^ buf ^ buf+size
* Try to read block by block.
*/
for(i1 = 0; i1 < size; i1++) {
for(i2 = i1; i2 < size; i2++) {
uint8_t *chunk1 = buf;
int size1 = i1;
uint8_t *chunk2 = buf + size1;
int size2 = i2 - i1;
uint8_t *chunk3 = buf + size1 + size2;
int size3 = size - size1 - size2;
fprintf(stderr, "\n%d:{%d, %d, %d}...\n",
size, size1, size2, size3);
memset(buf1, 0, size);
memset(buf2, 0, size);
memset(buf3, 0, size);
memcpy(buf1, chunk1, size1);
memcpy(buf2, chunk2, size2);
memcpy(buf3, chunk3, size3);
tp = memset(&t, 0, sizeof(t));
fprintf(stderr, "=> Chunk 1 (%d):\n", size1);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf1, size1);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size1);
if(rval.consumed < size1) {
int leftover = size1 - rval.consumed;
memcpy(buf2, buf1 + rval.consumed, leftover);
memcpy(buf2 + leftover, chunk2, size2);
size2 += leftover;
}
fprintf(stderr, "=> Chunk 2 (%d):\n", size2);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf2, size2);
assert(rval.code == RC_WMORE);
assert(rval.consumed <= size2);
if(rval.consumed < size2) {
int leftover = size2 - rval.consumed;
memcpy(buf3, buf2 + rval.consumed, leftover);
memcpy(buf3 + leftover, chunk3, size3);
size3 += leftover;
}
fprintf(stderr, "=> Chunk 3 (%d):\n", size3);
rval = ber_decode(&asn1_DEF_T, (void **)&tp,
buf3, size3);
assert(rval.code == RC_OK);
assert(rval.consumed == size3);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
}
}
}
int
main(int ac, char **av) {
T_t t;
/* Check exact buf0 */
check(&t, buf0, sizeof(buf0), sizeof(buf0));
compare(&t, buf0_reconstr, sizeof(buf0_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Check exact buf1 */
check(&t, buf1, sizeof(buf1), sizeof(buf1));
compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Check slightly more than buf1 */
check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Check exact buf2 */
check(&t, buf2, sizeof(buf2), sizeof(buf2));
compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Check slightly more than buf2 */
check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
asn_fprint(stderr, &asn1_DEF_T, &t);
asn1_DEF_T.free_struct(&asn1_DEF_T, &t, 1);
/* Split the buffer in parts and check decoder restartability */
partial_read(buf0, sizeof(buf0));
return 0;
}
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <Test-structure-1.h>
#include <Sets.h>
int
main(int ac, char **av) {
Test_structure_1_t ts1;
Sets_t s1;
memset(&ts1, 0, sizeof(ts1));
memset(&s1, 0, sizeof(s1));
/*
* No plans to fill it up: just checking whether it compiles or not.
*/
return 0;
}
#!/bin/sh
#
# This script is designed to quickly create lots of files in underlying
# test-* directories, do lots of other magic stuff and exit cleanly.
#
# Compute the .asn1 spec name by the given file name.
source=$(echo "$1" | sed -e 's/.*\///')
testno=`echo "$source" | cut -f2 -d'-' | cut -f1 -d'.'`
args=$(echo "$source" | sed -e 's/\.c$//')
testdir=test-${args}
OFS=$IFS
IFS="."
set $args
shift
IFS=$OFS
if [ ! -d $testdir ]; then
mkdir $testdir || exit $?
fi
cd $testdir || exit $?
ln -fs ../$source || exit $?
# Compile the corresponding .asn1 spec.
set -x
../../asn1c \
-S ../../../skeletons \
-Wdebug-compiler "$@" \
../../../tests/${testno}-*.asn1 || exit $?
set +x
# Create a Makefile for the project.
cat > Makefile <<EOM
CFLAGS=-I. -Wall -g ${CFLAGS} -DEMIT_ASN_DEBUG
SRCS=`echo *.c`
OBJS=\${SRCS:.c=.o}
check-executable: \${OBJS}
\${CC} \${CFLAGS} -o check-executable \${OBJS}
.SUFFIXES:
.SUFFIXES: .c .o
.c.o:
\${CC} \${CFLAGS} -o \$@ -c \$<
check: check-executable
./check-executable
clean:
@rm -f *.o
EOM
# Perform building and checking
make check || exit $?
# Uncomment this to jeopardize debugging
# make clean
This diff is collapsed.
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtoimax' function. */
#undef HAVE_STRTOIMAX
/* Define to 1 if you have the `strtoll' function. */
#undef HAVE_STRTOLL
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Version number of package */
#undef VERSION
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
/* Define to `int64_t' if <sys/types.h> does not define. */
#undef intmax_t
/* Define to `long' if <sys/types.h> does not define. */
#undef off_t
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
This diff is collapsed.
This diff is collapsed.
dnl Process this file with autoconf to produce a configure script.
AC_INIT(libasn1parser/asn1p_y.y)
AC_CANONICAL_SYSTEM
AC_PREREQ(2.53)
AM_INIT_AUTOMAKE(asn1c, 0.8.10)
AC_SUBST(PATH)
AM_MAINTAINER_MODE
AM_PROG_LIBTOOL
dnl *** Autoconf support ***
AC_ARG_ENABLE(autoconf,
[ --disable-autoconf disable automatic generation of configure script ],
enable_autoconf=$enableval, enable_autoconf=yes
)
AC_PATH_PROG(AUTOCONF, autoconf, @echo autoconf not available)
AC_PATH_PROG(AUTOHEADER, autoheader, @echo autoheader not available)
if test -z "$AUTOCONF"; then enable_autoconf=no ; fi
if test -z "$AUTOHEADER"; then enable_autoconf=no ; fi
if test x$enable_autoconf = xyes; then
CONFIGURE_DEPENDS="configure.in aclocal.m4"
fi
AC_SUBST(CONFIGURE_DEPENDS)
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_YACC
AM_PROG_LEX
AC_PATH_PROG(AR, ar, ar, $PATH:/usr/ucb:/usr/ccs/bin)
dnl *** Building mingw32 with cygwin compiler ***
case "$build" in
*cygwin*)
case "$target" in
*mingw*)
CC="$CC -mno-cygwin"
esac ;;
esac
AC_ARG_ENABLE(autoconf,
[ --enable-Werror abort compilation after any C compiler warning],
ADD_CFLAGS="-Werror")
AC_SUBST(ADD_CFLAGS)
dnl Add these flags if we're using GCC.
case "$GCC" in
yes)
CFLAGS="$CFLAGS -Wall"
CFLAGS="$CFLAGS -Wshadow"
CFLAGS="$CFLAGS -Wcast-qual"
CFLAGS="$CFLAGS -Wcast-align"
CFLAGS="$CFLAGS -Wmissing-prototypes"
CFLAGS="$CFLAGS -Wmissing-declarations"
CFLAGS="$CFLAGS -Wredundant-decls"
CFLAGS="$CFLAGS -Wnested-externs"
;;
esac
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(errno.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_BIGENDIAN
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_STRUCT_TM
AC_CHECK_TYPE(intmax_t, int64_t)
AC_CHECK_FUNCS(strtoimax strtoll)
AM_CONFIG_HEADER(config.h)
AC_OUTPUT( \
libasn1compiler/Makefile \
skeletons/tests/Makefile \
libasn1parser/Makefile \
libasn1print/Makefile \
asn1c/tests/Makefile \
libasn1fix/Makefile \
skeletons/Makefile \
examples/Makefile \
tests/Makefile \
asn1c/Makefile \
doc/Makefile \
Makefile \
)
This diff is collapsed.
EXTRA_DIST = *.pdf
CLEANFILES = *.*~
# Makefile.in generated automatically by automake 1.5 from Makefile.am.
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
ADD_CFLAGS = @ADD_CFLAGS@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AWK = @AWK@
CC = @CC@
CONFIGURE_DEPENDS = @CONFIGURE_DEPENDS@
CPP = @CPP@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
EXEEXT = @EXEEXT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LEX = @LEX@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAINT = @MAINT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PATH = @PATH@
RANLIB = @RANLIB@
VERSION = @VERSION@
YACC = @YACC@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
EXTRA_DIST = *.pdf
CLEANFILES = *.*~
subdir = doc
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
DIST_COMMON = Makefile.am Makefile.in
all: all-am
.SUFFIXES:
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu doc/Makefile
Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && \
CONFIG_HEADERS= CONFIG_LINKS= \
CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
uninstall-info-am:
tags: TAGS
TAGS:
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
if test -f $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
$(mkinstalldirs) "$(distdir)/$$dir"; \
fi; \
if test -d $$d/$$file; then \
cp -pR $$d/$$file $(distdir) \
|| exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic distclean-libtool
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool uninstall uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
dist_bin_SCRIPTS = crfc2asn1.pl clyx2asn1.pl
EXTRA_DIST = *.asn1 rfc*.txt
This diff is collapsed.
This directory contains several convertors from known text formats into
the ASN.1 specifications, as well as examples of these formats and the
sample convertor's output.
Try ../asn1c/asn1c -P *PKIX*93.asn1
#!/usr/bin/perl
#
# $Id$
# $Author$
#
# Simple tool that fetches known ASN.1 specifications from the
# stream of LyX data.
#
if($#ARGV == -1) {
print STDERR "Extract known modules from LyX data\n";
print STDERR "Usage: cat *.lyx | $0 <ASN-Module-Name> ...\n";
exit 64;
}
# Convert arguments into a hash for quicker search.
for(my $i; $i <= $#ARGV; $i++) {
$modules{$ARGV[$i]} = $ARGV[$i].".asn1";
}
# Process incoming stream in search for ASN.1 modules.
while(<STDIN>) {
chop;
if($inmodule) {
next if(/^$/);
if(/^\\layout /) {
print O "\n";
next;
}
if(/^\\begin_inset Quotes/) {
print O '"';
next;
}
next if(/^\\/);
print O;
if(/^END$/) {
$inmodule = 0;
print O "\n";
}
} else {
next unless $modules{$_};
open(O, '> '.$modules{$_});
print O;
$inmodule = 1;
delete $modules{$_};
}
}
# Make sure noone's missing.
die "Modules not found: " . join(", ", keys %modules) . "\n" if keys %modules;
This diff is collapsed.
This diff is collapsed.
AM_CPPFLAGS = \
-I${top_srcdir}/libasn1parser \
-I${top_srcdir}/libasn1fix
noinst_LTLIBRARIES = libasn1compiler.la
libasn1compiler_la_LDFLAGS = -all-static
libasn1compiler_la_SOURCES = \
asn1compiler.c asn1compiler.h \
asn1c_misc.c asn1c_misc.h \
asn1c_out.c asn1c_out.h \
asn1c_lang.c asn1c_lang.h \
asn1c_save.c asn1c_save.h \
asn1c_C.c asn1c_C.h \
asn1c_internal.h
libasn1compiler_la_LIBADD = \
${top_builddir}/libasn1parser/libasn1parser.la \
${top_builddir}/libasn1fix/libasn1fix.la
check_PROGRAMS = check_compiler
TESTS = ${check_PROGRAMS}
LDADD = ${noinst_LTLIBRARIES} ${libasn1compiler_la_LIBADD}
DEPENDENCIES = ${LDADD}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef _ASN1_SAVE_H_
#define _ASN1_SAVE_H_
int asn1c_save_compiled_output(arg_t *arg, const char *datadir);
#endif /* _ASN1_SAVE_H_ */
This diff is collapsed.
This diff is collapsed.
#include "asn1compiler.h"
int
main(int ac, char **av) {
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment