first stange of asn1 table driven compiler
This commit is contained in:
@@ -7,34 +7,44 @@ YFLAGS = -d -t
|
||||
lib_LTLIBRARIES = libasn1.la
|
||||
libasn1_la_LDFLAGS = -version-info 8:0:0
|
||||
|
||||
noinst_LTLIBRARIES = libasn1base.la
|
||||
|
||||
if versionscript
|
||||
libasn1_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map
|
||||
endif
|
||||
|
||||
|
||||
libasn1_la_LIBADD = \
|
||||
libasn1base.la \
|
||||
@LIB_com_err@ \
|
||||
$(LIBADD_roken)
|
||||
|
||||
BUILT_SOURCES = \
|
||||
$(gen_files_rfc2459:.x=.c) \
|
||||
rfc2459_asn1-template.c \
|
||||
$(gen_files_cms:.x=.c) \
|
||||
$(gen_files_k5:.x=.c) \
|
||||
cms_asn1-template.c \
|
||||
$(gen_files_krb5:.x=.c) \
|
||||
krb5_asn1-template.c \
|
||||
$(gen_files_pkinit:.x=.c) \
|
||||
pkinit_asn1-template.c \
|
||||
$(gen_files_pkcs8:.x=.c) \
|
||||
pkcs8_asn1-template.c \
|
||||
$(gen_files_pkcs9:.x=.c) \
|
||||
pkcs9_asn1-template.c \
|
||||
$(gen_files_pkcs12:.x=.c) \
|
||||
pkcs12_asn1-template.c \
|
||||
$(gen_files_digest:.x=.c) \
|
||||
digest_asn1-template.c \
|
||||
$(gen_files_kx509:.x=.c) \
|
||||
asn1_err.h \
|
||||
asn1_err.c
|
||||
kx509_asn1-template.c
|
||||
|
||||
gen_files_k5 = \
|
||||
gen_files_krb5 = \
|
||||
asn1_AD_AND_OR.x \
|
||||
asn1_AD_IF_RELEVANT.x \
|
||||
asn1_AD_KDCIssued.x \
|
||||
asn1_AD_MANDATORY_FOR_KDC.x \
|
||||
asn1_AD_LoginAlias.x \
|
||||
asn1_AD_MANDATORY_FOR_KDC.x \
|
||||
asn1_APOptions.x \
|
||||
asn1_AP_REP.x \
|
||||
asn1_AP_REQ.x \
|
||||
@@ -62,12 +72,15 @@ gen_files_k5 = \
|
||||
asn1_EncryptedData.x \
|
||||
asn1_EncryptionKey.x \
|
||||
asn1_EtypeList.x \
|
||||
asn1_FastOptions.x \
|
||||
asn1_HostAddress.x \
|
||||
asn1_HostAddresses.x \
|
||||
asn1_KDCOptions.x \
|
||||
asn1_KDC_REP.x \
|
||||
asn1_KDC_REQ.x \
|
||||
asn1_KDC_REQ_BODY.x \
|
||||
asn1_KRB5SignedPath.x \
|
||||
asn1_KRB5SignedPathData.x \
|
||||
asn1_KRB_CRED.x \
|
||||
asn1_KRB_ERROR.x \
|
||||
asn1_KRB_PRIV.x \
|
||||
@@ -76,12 +89,22 @@ gen_files_k5 = \
|
||||
asn1_KerberosString.x \
|
||||
asn1_KerberosTime.x \
|
||||
asn1_KrbCredInfo.x \
|
||||
asn1_KrbFastArmor.x \
|
||||
asn1_KrbFastArmoredRep.x \
|
||||
asn1_KrbFastArmoredReq.x \
|
||||
asn1_KrbFastFinished.x \
|
||||
asn1_KrbFastReq.x \
|
||||
asn1_KrbFastResponse.x \
|
||||
asn1_LR_TYPE.x \
|
||||
asn1_LastReq.x \
|
||||
asn1_MESSAGE_TYPE.x \
|
||||
asn1_METHOD_DATA.x \
|
||||
asn1_NAME_TYPE.x \
|
||||
asn1_PA_FX_FAST_REPLY.x \
|
||||
asn1_PA_FX_FAST_REQUEST.x \
|
||||
asn1_PADATA_TYPE.x \
|
||||
asn1_PA_ClientCanonicalized.x \
|
||||
asn1_PA_ClientCanonicalizedNames.x \
|
||||
asn1_PA_DATA.x \
|
||||
asn1_PA_ENC_SAM_RESPONSE_ENC.x \
|
||||
asn1_PA_ENC_TS_ENC.x \
|
||||
@@ -92,11 +115,9 @@ gen_files_k5 = \
|
||||
asn1_PA_SAM_REDIRECT.x \
|
||||
asn1_PA_SAM_RESPONSE_2.x \
|
||||
asn1_PA_SAM_TYPE.x \
|
||||
asn1_PA_ClientCanonicalized.x \
|
||||
asn1_PA_ClientCanonicalizedNames.x \
|
||||
asn1_PA_SvrReferralData.x \
|
||||
asn1_PA_ServerReferralData.x \
|
||||
asn1_PA_SERVER_REFERRAL_DATA.x \
|
||||
asn1_PA_ServerReferralData.x \
|
||||
asn1_PA_SvrReferralData.x \
|
||||
asn1_PROV_SRV_LOCATION.x \
|
||||
asn1_Principal.x \
|
||||
asn1_PrincipalName.x \
|
||||
@@ -111,18 +132,7 @@ gen_files_k5 = \
|
||||
asn1_TransitedEncoding.x \
|
||||
asn1_TypedData.x \
|
||||
asn1_krb5int32.x \
|
||||
asn1_krb5uint32.x \
|
||||
asn1_KRB5SignedPathData.x \
|
||||
asn1_KRB5SignedPath.x \
|
||||
asn1_FastOptions.x \
|
||||
asn1_KrbFastArmor.x \
|
||||
asn1_KrbFastArmoredRep.x \
|
||||
asn1_KrbFastArmoredReq.x \
|
||||
asn1_KrbFastFinished.x \
|
||||
asn1_KrbFastReq.x \
|
||||
asn1_KrbFastResponse.x \
|
||||
asn1_PA_FX_FAST_REPLY.x \
|
||||
asn1_PA_FX_FAST_REQUEST.x
|
||||
asn1_krb5uint32.x
|
||||
|
||||
gen_files_cms = \
|
||||
asn1_CMSAttributes.x \
|
||||
@@ -430,8 +440,10 @@ gen_files_pkcs9 = \
|
||||
asn1_PKCS9_friendlyName.x
|
||||
|
||||
gen_files_test = \
|
||||
asn1_TESTOptional.x \
|
||||
asn1_TESTAlloc.x \
|
||||
asn1_TESTAllocInner.x \
|
||||
asn1_TESTBitString.x \
|
||||
asn1_TESTCONTAINING.x \
|
||||
asn1_TESTCONTAININGENCODEDBY.x \
|
||||
asn1_TESTCONTAININGENCODEDBY2.x \
|
||||
@@ -445,14 +457,21 @@ gen_files_test = \
|
||||
asn1_TESTInteger2.x \
|
||||
asn1_TESTInteger3.x \
|
||||
asn1_TESTLargeTag.x \
|
||||
asn1_TESTSeq.x \
|
||||
asn1_TESTUSERCONSTRAINED.x \
|
||||
asn1_TESTSeqOf.x \
|
||||
asn1_TESTOSSize1.x \
|
||||
asn1_TESTPreserve.x \
|
||||
asn1_TESTSeq.x \
|
||||
asn1_TESTSeqOf.x \
|
||||
asn1_TESTSeqOf2.x \
|
||||
asn1_TESTSeqOf3.x \
|
||||
asn1_TESTSeqOfSeq.x \
|
||||
asn1_TESTSeqOfSeq2.x \
|
||||
asn1_TESTSeqOfSeq3.x \
|
||||
asn1_TESTSeqSizeOf1.x \
|
||||
asn1_TESTSeqSizeOf2.x \
|
||||
asn1_TESTSeqSizeOf3.x \
|
||||
asn1_TESTSeqSizeOf4.x
|
||||
asn1_TESTSeqSizeOf4.x \
|
||||
asn1_TESTUSERCONSTRAINED.x \
|
||||
asn1_TESTuint32.x
|
||||
|
||||
gen_files_digest = \
|
||||
asn1_DigestError.x \
|
||||
@@ -479,15 +498,20 @@ noinst_PROGRAMS = asn1_gen
|
||||
|
||||
libexec_heimdal_PROGRAMS = asn1_compile asn1_print
|
||||
|
||||
TESTS = check-der check-gen check-timegm check-ber
|
||||
TESTS = check-der check-gen check-timegm check-ber check-template
|
||||
check_PROGRAMS = $(TESTS)
|
||||
|
||||
asn1_gen_SOURCES = asn1_gen.c
|
||||
asn1_print_SOURCES = asn1_print.c
|
||||
check_der_SOURCES = check-der.c check-common.c check-common.h
|
||||
|
||||
check_template_SOURCES = check-template.c check-common.c check-common.h
|
||||
nodist_check_template_SOURCES = $(gen_files_test:.x=.c) test_asn1-template.c
|
||||
|
||||
dist_check_gen_SOURCES = check-gen.c check-common.c check-common.h
|
||||
nodist_check_gen_SOURCES = $(gen_files_test:.x=.c)
|
||||
nodist_check_gen_SOURCES = $(gen_files_test:.x=.c) test_asn1-template.c
|
||||
|
||||
build_HEADERZ = asn1-template.h
|
||||
|
||||
asn1_compile_SOURCES = \
|
||||
asn1-common.h \
|
||||
@@ -503,16 +527,17 @@ asn1_compile_SOURCES = \
|
||||
gen_length.c \
|
||||
gen_locl.h \
|
||||
gen_seq.c \
|
||||
gen_template.c \
|
||||
hash.c \
|
||||
hash.h \
|
||||
lex.l \
|
||||
lex.h \
|
||||
main.c \
|
||||
asn1-template.h \
|
||||
symbol.c \
|
||||
symbol.h
|
||||
|
||||
dist_libasn1_la_SOURCES = \
|
||||
der-protos.h \
|
||||
dist_libasn1base_la_SOURCES = \
|
||||
der_locl.h \
|
||||
der.c \
|
||||
der.h \
|
||||
@@ -525,28 +550,38 @@ dist_libasn1_la_SOURCES = \
|
||||
der_format.c \
|
||||
heim_asn1.h \
|
||||
extra.c \
|
||||
template.c \
|
||||
timegm.c
|
||||
|
||||
nodist_libasn1base_la_SOURCES = \
|
||||
asn1_err.h \
|
||||
asn1_err.c
|
||||
|
||||
nodist_libasn1_la_SOURCES = $(BUILT_SOURCES)
|
||||
|
||||
asn1_compile_LDADD = \
|
||||
$(LIB_roken) $(LEXLIB)
|
||||
|
||||
check_der_LDADD = \
|
||||
libasn1base.la \
|
||||
$(LIB_roken)
|
||||
|
||||
check_template_LDADD = $(check_der_LDADD)
|
||||
asn1_print_LDADD = $(check_der_LDADD) $(LIB_com_err)
|
||||
asn1_gen_LDADD = $(check_der_LDADD)
|
||||
check_timegm_LDADD = $(check_der_LDADD)
|
||||
|
||||
check_gen_LDADD = \
|
||||
libasn1.la \
|
||||
$(LIB_roken)
|
||||
|
||||
check_gen_LDADD = $(check_der_LDADD)
|
||||
check_ber_LDADD = $(check_der_LDADD)
|
||||
asn1_print_LDADD = $(check_der_LDADD)
|
||||
asn1_gen_LDADD = $(check_der_LDADD)
|
||||
check_timegm_LDADD = $(check_der_LDADD)
|
||||
check_ber_LDADD = $(check_gen_LDADD)
|
||||
|
||||
CLEANFILES = \
|
||||
$(BUILT_SOURCES) \
|
||||
$(gen_files_rfc2459) \
|
||||
$(gen_files_cms) \
|
||||
$(gen_files_k5) \
|
||||
$(gen_files_krb5) \
|
||||
$(gen_files_pkinit) \
|
||||
$(gen_files_pkcs8) \
|
||||
$(gen_files_pkcs9) \
|
||||
@@ -554,6 +589,7 @@ CLEANFILES = \
|
||||
$(gen_files_digest) \
|
||||
$(gen_files_kx509) \
|
||||
$(gen_files_test) $(nodist_check_gen_SOURCES) \
|
||||
test_asn1-template.c \
|
||||
rfc2459_asn1_files rfc2459_asn1.h* \
|
||||
cms_asn1_files cms_asn1.h* \
|
||||
krb5_asn1_files krb5_asn1.h* \
|
||||
@@ -565,7 +601,7 @@ CLEANFILES = \
|
||||
kx509_asn1_files kx509_asn1.h* \
|
||||
test_asn1_files test_asn1.h*
|
||||
|
||||
dist_include_HEADERS = der.h heim_asn1.h der-protos.h
|
||||
dist_include_HEADERS = der.h heim_asn1.h der-protos.h der-private.h
|
||||
|
||||
nodist_include_HEADERS = asn1_err.h
|
||||
nodist_include_HEADERS += krb5_asn1.h
|
||||
@@ -578,14 +614,28 @@ nodist_include_HEADERS += pkcs12_asn1.h
|
||||
nodist_include_HEADERS += digest_asn1.h
|
||||
nodist_include_HEADERS += kx509_asn1.h
|
||||
|
||||
$(asn1_compile_OBJECTS): asn1parse.h asn1parse.c $(srcdir)/der-protos.h
|
||||
$(libasn1_la_OBJECTS): $(nodist_include_HEADERS) $(srcdir)/der-protos.h
|
||||
priv_headers = krb5_asn1-priv.h
|
||||
priv_headers += pkinit_asn1-priv.h
|
||||
priv_headers += cms_asn1-priv.h
|
||||
priv_headers += rfc2459_asn1-priv.h
|
||||
priv_headers += pkcs8_asn1-priv.h
|
||||
priv_headers += pkcs9_asn1-priv.h
|
||||
priv_headers += pkcs12_asn1-priv.h
|
||||
priv_headers += digest_asn1-priv.h
|
||||
priv_headers += kx509_asn1-priv.h
|
||||
|
||||
|
||||
|
||||
$(asn1_compile_OBJECTS): asn1parse.h asn1parse.c $(srcdir)/der-protos.h $(srcdir)/der-private.h
|
||||
$(libasn1_la_OBJECTS): $(nodist_include_HEADERS) $(priv_headers) asn1_err.h $(srcdir)/der-protos.h $(srcdir)/der-private.h
|
||||
$(libasn1base_la_OBJECTS): asn1_err.h $(srcdir)/der-protos.h $(srcdir)/der-private.h
|
||||
$(check_gen_OBJECTS): test_asn1.h
|
||||
$(check_template_OBJECTS): test_asn1_files
|
||||
$(asn1_print_OBJECTS): krb5_asn1.h
|
||||
|
||||
asn1parse.h: asn1parse.c
|
||||
|
||||
$(gen_files_k5) krb5_asn1.hx: krb5_asn1_files
|
||||
$(gen_files_krb5) krb5_asn1.hx: krb5_asn1_files
|
||||
$(gen_files_pkinit) pkinit_asn1.hx: pkinit_asn1_files
|
||||
$(gen_files_pkcs8) pkcs8_asn1.hx: pkcs8_asn1_files
|
||||
$(gen_files_pkcs9) pkcs9_asn1.hx: pkcs9_asn1_files
|
||||
@@ -626,6 +676,7 @@ kx509_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/kx509.asn1
|
||||
test_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/test.asn1
|
||||
$(ASN1_COMPILE) --sequence=TESTSeqOf $(srcdir)/test.asn1 test_asn1 || (rm -f test_asn1_files ; exit 1)
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
cms.asn1 \
|
||||
cms.opt \
|
||||
@@ -646,4 +697,7 @@ EXTRA_DIST = \
|
||||
version-script.map
|
||||
|
||||
$(srcdir)/der-protos.h:
|
||||
cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -o der-protos.h $(dist_libasn1_la_SOURCES) || rm -f der-protos.h
|
||||
cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -o der-protos.h $(dist_libasn1base_la_SOURCES) || rm -f der-protos.h
|
||||
|
||||
$(srcdir)/der-private.h:
|
||||
cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p der-private.h $(dist_libasn1base_la_SOURCES) || rm -f der-private.h
|
||||
|
131
lib/asn1/README.template
Normal file
131
lib/asn1/README.template
Normal file
@@ -0,0 +1,131 @@
|
||||
#!/bin/sh
|
||||
|
||||
size .libs/libasn1.dylib
|
||||
size .libs/libasn1base.a | awk '{sum += $1} END {print sum}' | sed 's/^/TEXT baselib: /'
|
||||
size .libs/asn1_*.o | awk '{sum += $1} END {print sum}' | sed 's/^/generated code stubs: /'
|
||||
size *_asn1-template.o | awk '{sum += $1} END {print sum}' | sed 's/^/TEXT stubs: /'
|
||||
|
||||
exit 0
|
||||
|
||||
Notes about the template parser:
|
||||
|
||||
- assumption: code is large, tables smaller
|
||||
|
||||
- how to generate template based stubs:
|
||||
|
||||
make check asn1_compile_FLAGS=--template > log
|
||||
|
||||
- pretty much the same as the generate code, except uses tables instead of code
|
||||
|
||||
TODO:
|
||||
- Make hdb work
|
||||
|
||||
- Fuzzing tests
|
||||
|
||||
- Performance testing
|
||||
|
||||
- ASN1_MALLOC_ENCODE() as a function, replaces encode_ and length_
|
||||
|
||||
- Fix SIZE constraits
|
||||
|
||||
- Compact types that only contain on entry to not having a header.
|
||||
|
||||
|
||||
SIZE - Futher down is later generations of the template parser
|
||||
|
||||
code:
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
462848 12288 0 323584 798720 c3000 (O2)
|
||||
|
||||
trivial types:
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
446464 12288 0 323584 782336 bf000 (O2)
|
||||
|
||||
OPTIONAL
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
425984 16384 0 323584 765952 bb000 (O2)
|
||||
|
||||
SEQ OF
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
368640 32768 0 327680 729088 b2000 (O2)
|
||||
348160 32768 0 327680 708608 ad000 (Os)
|
||||
|
||||
BOOLEAN
|
||||
==================
|
||||
339968 32768 0 327680 700416 ab000 (Os)
|
||||
|
||||
TYPE_EXTERNAL:
|
||||
==================
|
||||
331776 32768 0 327680 692224 a9000 (Os)
|
||||
|
||||
SET OF
|
||||
==================
|
||||
327680 32768 0 327680 688128 a8000 (Os)
|
||||
|
||||
TYPE_EXTERNAL everywhere
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
167936 69632 0 327680 565248 8a000 (Os)
|
||||
|
||||
TAG uses ->ptr (header and trailer)
|
||||
==================
|
||||
229376 102400 0 421888 753664 b8000 (O0)
|
||||
|
||||
TAG uses ->ptr (header only)
|
||||
==================
|
||||
221184 77824 0 421888 720896 b0000 (O0)
|
||||
|
||||
BER support for octet string (not working)
|
||||
==================
|
||||
180224 73728 0 417792 671744 a4000 (O2)
|
||||
|
||||
CHOICE and BIT STRING missign
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
172032 73728 0 417792 663552 a2000 (Os)
|
||||
|
||||
No accessor functions to global variable
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
159744 73728 0 393216 626688 99000 (Os)
|
||||
|
||||
All types tables (except choice) (id still objects)
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
167936 77824 0 421888 667648 a3000
|
||||
base lib: 22820
|
||||
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
==================
|
||||
167936 77824 0 421888 667648 a3000 (Os)
|
||||
baselib: 22820
|
||||
generated code stubs: 41472
|
||||
TEXT stubs: 112560
|
||||
|
||||
All types, id still objects
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
155648 81920 0 430080 667648 a3000 (Os)
|
||||
TEXT baselib: 23166
|
||||
generated code stubs: 20796
|
||||
TEXT stubs: 119891
|
||||
|
||||
All types, id still objects, dup compression
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
143360 65536 0 376832 585728 8f000 (Os)
|
||||
TEXT baselib: 23166
|
||||
generated code stubs: 20796
|
||||
TEXT stubs: 107147
|
||||
|
||||
All types, dup compression, id vars
|
||||
==================
|
||||
__TEXT __DATA __OBJC others dec hex
|
||||
131072 65536 0 352256 548864 86000
|
||||
TEXT baselib: 23166
|
||||
generated code stubs: 7536
|
||||
TEXT stubs: 107147
|
141
lib/asn1/asn1-template.h
Normal file
141
lib/asn1/asn1-template.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2006 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. 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.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
|
||||
*/
|
||||
|
||||
/* asn1 templates */
|
||||
|
||||
#ifndef __TEMPLATE_H__
|
||||
#define __TEMPLATE_H__
|
||||
|
||||
/* tag:
|
||||
* 0..20 tag
|
||||
* 21 type
|
||||
* 22..23 class
|
||||
* 24..27 flags
|
||||
* 28..31 op
|
||||
*/
|
||||
|
||||
/* parse:
|
||||
* 0..11 type
|
||||
* 12..23 unused
|
||||
* 24..27 flags
|
||||
* 28..31 op
|
||||
*/
|
||||
|
||||
#define A1_OP_MASK (0xf0000000)
|
||||
#define A1_OP_TYPE (0x10000000)
|
||||
#define A1_OP_TYPE_EXTERN (0x20000000)
|
||||
#define A1_OP_TAG (0x30000000)
|
||||
#define A1_OP_PARSE (0x40000000)
|
||||
#define A1_OP_SEQOF (0x50000000)
|
||||
#define A1_OP_SETOF (0x60000000)
|
||||
#define A1_OP_BMEMBER (0x70000000)
|
||||
#define A1_OP_CHOICE (0x80000000)
|
||||
|
||||
#define A1_FLAG_MASK (0x0f000000)
|
||||
#define A1_FLAG_OPTIONAL (0x01000000)
|
||||
#define A1_FLAG_IMPLICIT (0x02000000)
|
||||
|
||||
#define A1_TAG_T(CLASS,TYPE,TAG) ((A1_OP_TAG) | (((CLASS) << 22) | ((TYPE) << 21) | (TAG)))
|
||||
#define A1_TAG_CLASS(x) (((x) >> 22) & 0x3)
|
||||
#define A1_TAG_TYPE(x) (((x) >> 21) & 0x1)
|
||||
#define A1_TAG_TAG(x) ((x) & 0x1fffff)
|
||||
|
||||
#define A1_TAG_LEN(t) ((uintptr_t)(t)->ptr)
|
||||
#define A1_HEADER_LEN(t) ((uintptr_t)(t)->ptr)
|
||||
|
||||
#define A1_PARSE_T(type) ((A1_OP_PARSE) | (type))
|
||||
#define A1_PARSE_TYPE_MASK 0xfff
|
||||
#define A1_PARSE_TYPE(x) (A1_PARSE_TYPE_MASK & (x))
|
||||
|
||||
#define A1_PF_INDEFINTE 0x1
|
||||
#define A1_PF_ALLOW_BER 0x2
|
||||
|
||||
#define A1_HF_PRESERVE 0x1
|
||||
#define A1_HF_ELLIPSIS 0x2
|
||||
|
||||
#define A1_HBF_RFC1510 0x1
|
||||
|
||||
|
||||
struct asn1_template {
|
||||
uint32_t tt;
|
||||
size_t offset;
|
||||
const void *ptr;
|
||||
};
|
||||
|
||||
typedef int (*asn1_type_decode)(const unsigned char *, size_t, void *, size_t *);
|
||||
typedef int (*asn1_type_encode)(unsigned char *, size_t, const void *, size_t *);
|
||||
typedef size_t (*asn1_type_length)(const void *);
|
||||
typedef void (*asn1_type_release)(void *);
|
||||
typedef int (*asn1_type_copy)(const void *, void *);
|
||||
|
||||
struct asn1_type_func {
|
||||
asn1_type_encode encode;
|
||||
asn1_type_decode decode;
|
||||
asn1_type_length length;
|
||||
asn1_type_copy copy;
|
||||
asn1_type_release release;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct template_of {
|
||||
unsigned int len;
|
||||
void *val;
|
||||
};
|
||||
|
||||
enum template_types {
|
||||
A1T_IMEMBER = 0,
|
||||
A1T_HEIM_INTEGER,
|
||||
A1T_INTEGER,
|
||||
A1T_UNSIGNED,
|
||||
A1T_GENERAL_STRING,
|
||||
A1T_OCTET_STRING,
|
||||
A1T_OCTET_STRING_BER,
|
||||
A1T_IA5_STRING,
|
||||
A1T_BMP_STRING,
|
||||
A1T_UNIVERSAL_STRING,
|
||||
A1T_PRINTABLE_STRING,
|
||||
A1T_VISIBLE_STRING,
|
||||
A1T_UTF8_STRING,
|
||||
A1T_GENERALIZED_TIME,
|
||||
A1T_UTC_TIME,
|
||||
A1T_HEIM_BIT_STRING,
|
||||
A1T_BOOLEAN,
|
||||
A1T_OID,
|
||||
A1T_TELETEX_STRING,
|
||||
A1T_NULL
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@@ -24,4 +24,6 @@ error_code MAX_CONSTRAINT, "ASN.1 too many elements"
|
||||
error_code EXACT_CONSTRAINT, "ASN.1 wrong number of elements"
|
||||
error_code INDEF_OVERRUN, "ASN.1 BER indefinte encoding overrun"
|
||||
error_code INDEF_UNDERRUN, "ASN.1 BER indefinte encoding underun"
|
||||
error_code GOT_BER, "ASN.1 got BER encoded when expected DER"
|
||||
error_code INDEF_EXTRA_DATA, "ASN.1 EoC tag contained data"
|
||||
end
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -182,7 +184,9 @@ loop (unsigned char *buf, size_t len, int indent)
|
||||
case UT_GeneralizedTime :
|
||||
case UT_GeneralString :
|
||||
case UT_PrintableString :
|
||||
case UT_VisibleString : {
|
||||
case UT_VisibleString :
|
||||
case UT_IA5String :
|
||||
case UT_UTF8String : {
|
||||
heim_general_string str;
|
||||
|
||||
ret = der_get_general_string (buf, length, &str, NULL);
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -250,7 +252,7 @@ ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
ModuleBody : /* Exports */ Imports AssignmentList
|
||||
ModuleBody : Exports Imports AssignmentList
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
@@ -272,11 +274,22 @@ SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
|
||||
for(sl = $1; sl != NULL; sl = sl->next) {
|
||||
Symbol *s = addsym(sl->string);
|
||||
s->stype = Stype;
|
||||
gen_template_import(s);
|
||||
}
|
||||
add_import($3);
|
||||
}
|
||||
;
|
||||
|
||||
Exports : kw_EXPORTS referencenames ';'
|
||||
{
|
||||
struct string_list *sl;
|
||||
for(sl = $2; sl != NULL; sl = sl->next)
|
||||
add_export(sl->string);
|
||||
}
|
||||
| kw_EXPORTS kw_ALL
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
AssignmentList : Assignment
|
||||
| Assignment AssignmentList
|
||||
;
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -197,7 +199,8 @@ generic_test (const struct test_case *tests,
|
||||
int (*length)(void *),
|
||||
int (*decode)(unsigned char *, size_t, void *, size_t *),
|
||||
int (*free_data)(void *),
|
||||
int (*cmp)(void *a, void *b))
|
||||
int (*cmp)(void *a, void *b),
|
||||
int (*copy)(const void *from, void *to))
|
||||
{
|
||||
unsigned char *buf, *buf2;
|
||||
int i;
|
||||
@@ -210,6 +213,7 @@ generic_test (const struct test_case *tests,
|
||||
for (i = 0; i < ntests; ++i) {
|
||||
int ret;
|
||||
size_t sz, consumed_sz, length_sz, buf_sz;
|
||||
void *to = NULL;
|
||||
|
||||
current_test = tests[i].name;
|
||||
|
||||
@@ -261,6 +265,11 @@ generic_test (const struct test_case *tests,
|
||||
printf ("\nactual: ");
|
||||
print_bytes (buf, sz);
|
||||
printf ("\n");
|
||||
#if 0
|
||||
rk_dumpdata("correct", tests[i].bytes, tests[i].byte_len);
|
||||
rk_dumpdata("actual", buf, sz);
|
||||
exit (1);
|
||||
#endif
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
@@ -287,9 +296,33 @@ generic_test (const struct test_case *tests,
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
|
||||
current_state = "copy";
|
||||
if (copy) {
|
||||
to = emalloc(data_size);
|
||||
ret = (*copy)(data, to);
|
||||
if (ret != 0) {
|
||||
printf ("copy of %s failed %d\n", tests[i].name, ret);
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
|
||||
current_state = "cmp-copy";
|
||||
if ((*cmp)(data, to) != 0) {
|
||||
printf ("%s: copy comparison failed\n", tests[i].name);
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
current_state = "free";
|
||||
if (free_data)
|
||||
if (free_data) {
|
||||
(*free_data)(data);
|
||||
if (to) {
|
||||
(*free_data)(to);
|
||||
free(to);
|
||||
}
|
||||
}
|
||||
|
||||
current_state = "free";
|
||||
map_free(buf_map, tests[i].name, "encode");
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -42,6 +44,7 @@ typedef int (*generic_encode)(unsigned char *, size_t, void *, size_t *);
|
||||
typedef int (*generic_length)(void *);
|
||||
typedef int (*generic_decode)(unsigned char *, size_t, void *, size_t *);
|
||||
typedef int (*generic_free)(void *);
|
||||
typedef int (*generic_copy)(const void *, void *);
|
||||
|
||||
int
|
||||
generic_test (const struct test_case *tests,
|
||||
@@ -51,7 +54,8 @@ generic_test (const struct test_case *tests,
|
||||
int (*length)(void *),
|
||||
int (*decode)(unsigned char *, size_t, void *, size_t *),
|
||||
int (*free_data)(void *),
|
||||
int (*cmp)(void *a, void *b));
|
||||
int (*cmp)(void *a, void *b),
|
||||
int (*copy)(const void *a, void *b));
|
||||
|
||||
int
|
||||
generic_decode_fail(const struct test_case *tests,
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -82,10 +84,11 @@ test_integer (void)
|
||||
|
||||
ret = generic_test (tests, ntests, sizeof(int),
|
||||
(generic_encode)der_put_integer,
|
||||
(generic_length) der_length_integer,
|
||||
(generic_decode)der_get_integer,
|
||||
(generic_free)NULL,
|
||||
cmp_integer);
|
||||
(generic_length) der_length_integer,
|
||||
(generic_decode)der_get_integer,
|
||||
(generic_free)NULL,
|
||||
cmp_integer,
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < ntests; ++i)
|
||||
free (tests[i].name);
|
||||
@@ -207,7 +210,8 @@ test_unsigned (void)
|
||||
(generic_length)der_length_unsigned,
|
||||
(generic_decode)der_get_unsigned,
|
||||
(generic_free)NULL,
|
||||
cmp_unsigned);
|
||||
cmp_unsigned,
|
||||
NULL);
|
||||
for (i = 0; i < ntests; ++i)
|
||||
free (tests[i].name);
|
||||
return ret;
|
||||
@@ -246,7 +250,8 @@ test_octet_string (void)
|
||||
(generic_length)der_length_octet_string,
|
||||
(generic_decode)der_get_octet_string,
|
||||
(generic_free)der_free_octet_string,
|
||||
cmp_octet_string);
|
||||
cmp_octet_string,
|
||||
NULL);
|
||||
free(tests[0].name);
|
||||
return ret;
|
||||
}
|
||||
@@ -290,7 +295,8 @@ test_bmp_string (void)
|
||||
(generic_length)der_length_bmp_string,
|
||||
(generic_decode)der_get_bmp_string,
|
||||
(generic_free)der_free_bmp_string,
|
||||
cmp_bmp_string);
|
||||
cmp_bmp_string,
|
||||
NULL);
|
||||
free(tests[0].name);
|
||||
free(tests[1].name);
|
||||
return ret;
|
||||
@@ -335,7 +341,8 @@ test_universal_string (void)
|
||||
(generic_length)der_length_universal_string,
|
||||
(generic_decode)der_get_universal_string,
|
||||
(generic_free)der_free_universal_string,
|
||||
cmp_universal_string);
|
||||
cmp_universal_string,
|
||||
NULL);
|
||||
free(tests[0].name);
|
||||
free(tests[1].name);
|
||||
return ret;
|
||||
@@ -370,7 +377,8 @@ test_general_string (void)
|
||||
(generic_length)der_length_general_string,
|
||||
(generic_decode)der_get_general_string,
|
||||
(generic_free)der_free_general_string,
|
||||
cmp_general_string);
|
||||
cmp_general_string,
|
||||
NULL);
|
||||
free(tests[0].name);
|
||||
return ret;
|
||||
}
|
||||
@@ -407,7 +415,8 @@ test_generalized_time (void)
|
||||
(generic_length)der_length_generalized_time,
|
||||
(generic_decode)der_get_generalized_time,
|
||||
(generic_free)NULL,
|
||||
cmp_generalized_time);
|
||||
cmp_generalized_time,
|
||||
NULL);
|
||||
for (i = 0; i < ntests; ++i)
|
||||
free(tests[i].name);
|
||||
return ret;
|
||||
@@ -454,7 +463,8 @@ test_oid (void)
|
||||
(generic_length)der_length_oid,
|
||||
(generic_decode)der_get_oid,
|
||||
(generic_free)der_free_oid,
|
||||
test_cmp_oid);
|
||||
test_cmp_oid,
|
||||
NULL);
|
||||
for (i = 0; i < ntests; ++i)
|
||||
free(tests[i].name);
|
||||
return ret;
|
||||
@@ -490,7 +500,8 @@ test_bit_string (void)
|
||||
(generic_length)der_length_bit_string,
|
||||
(generic_decode)der_get_bit_string,
|
||||
(generic_free)der_free_bit_string,
|
||||
test_cmp_bit_string);
|
||||
test_cmp_bit_string,
|
||||
NULL);
|
||||
for (i = 0; i < ntests; ++i)
|
||||
free(tests[i].name);
|
||||
return ret;
|
||||
@@ -541,7 +552,8 @@ test_heim_integer (void)
|
||||
(generic_length)der_length_heim_integer,
|
||||
(generic_decode)der_get_heim_integer,
|
||||
(generic_free)der_free_heim_integer,
|
||||
test_cmp_heim_integer);
|
||||
test_cmp_heim_integer,
|
||||
NULL);
|
||||
for (i = 0; i < ntests; ++i)
|
||||
free (tests[i].name);
|
||||
if (ret)
|
||||
@@ -590,7 +602,8 @@ test_boolean (void)
|
||||
(generic_length)der_length_boolean,
|
||||
(generic_decode)der_get_boolean,
|
||||
(generic_free)NULL,
|
||||
test_cmp_boolean);
|
||||
test_cmp_boolean,
|
||||
NULL);
|
||||
for (i = 0; i < ntests; ++i)
|
||||
free (tests[i].name);
|
||||
if (ret)
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -67,6 +69,8 @@ static char *nada_tgt_principal[] = { "krbtgt", "NADA.KTH.SE" };
|
||||
do { if (strcmp((ac)->e, (bc)->e) != 0) return 1; } while(0)
|
||||
#define COMPARE_INTEGER(ac,bc,e) \
|
||||
do { if ((ac)->e != (bc)->e) return 1; } while(0)
|
||||
#define COMPARE_OPT_INTEGER(ac,bc,e) \
|
||||
do { if (*(ac)->e != *(bc)->e) return 1; } while(0)
|
||||
#define COMPARE_MEM(ac,bc,e,len) \
|
||||
do { if (memcmp((ac)->e, (bc)->e,len) != 0) return 1; } while(0)
|
||||
|
||||
@@ -128,7 +132,8 @@ test_principal (void)
|
||||
(generic_length)length_Principal,
|
||||
(generic_decode)decode_Principal,
|
||||
(generic_free)free_Principal,
|
||||
cmp_principal);
|
||||
cmp_principal,
|
||||
NULL);
|
||||
for (i = 0; i < ntests; ++i)
|
||||
free (tests[i].name);
|
||||
|
||||
@@ -194,7 +199,8 @@ test_authenticator (void)
|
||||
(generic_length)length_Authenticator,
|
||||
(generic_decode)decode_Authenticator,
|
||||
(generic_free)free_Authenticator,
|
||||
cmp_authenticator);
|
||||
cmp_authenticator,
|
||||
(generic_copy)copy_Authenticator);
|
||||
for (i = 0; i < ntests; ++i)
|
||||
free(tests[i].name);
|
||||
|
||||
@@ -288,7 +294,8 @@ test_krb_error (void)
|
||||
(generic_length)length_KRB_ERROR,
|
||||
(generic_decode)decode_KRB_ERROR,
|
||||
(generic_free)free_KRB_ERROR,
|
||||
cmp_KRB_ERROR);
|
||||
cmp_KRB_ERROR,
|
||||
(generic_copy)copy_KRB_ERROR);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -372,7 +379,8 @@ test_Name (void)
|
||||
(generic_length)length_Name,
|
||||
(generic_decode)decode_Name,
|
||||
(generic_free)free_Name,
|
||||
cmp_Name);
|
||||
cmp_Name,
|
||||
(generic_copy)copy_Name);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -431,9 +439,226 @@ test_bit_string (void)
|
||||
(generic_length)length_KeyUsage,
|
||||
(generic_decode)decode_KeyUsage,
|
||||
(generic_free)free_KeyUsage,
|
||||
cmp_KeyUsage);
|
||||
cmp_KeyUsage,
|
||||
(generic_copy)copy_KeyUsage);
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_TicketFlags (void *a, void *b)
|
||||
{
|
||||
TicketFlags *aa = a;
|
||||
TicketFlags *ab = b;
|
||||
|
||||
return TicketFlags2int(*aa) != TicketFlags2int(*ab);
|
||||
}
|
||||
|
||||
static int
|
||||
test_bit_string_rfc1510 (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 7,
|
||||
"\x03\x05\x00\x80\x00\x00\x00",
|
||||
"TF bitstring 1"
|
||||
},
|
||||
{ NULL, 7,
|
||||
"\x03\x05\x00\x40\x20\x00\x00",
|
||||
"TF bitstring 2"
|
||||
},
|
||||
{ NULL, 7,
|
||||
"\x03\x05\x00\x00\x20\x00\x00",
|
||||
"TF bitstring 3"
|
||||
},
|
||||
{ NULL, 7,
|
||||
"\x03\x05\x00\x00\x00\x00\x00",
|
||||
"TF bitstring 4"
|
||||
}
|
||||
};
|
||||
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
TicketFlags tf1, tf2, tf3, tf4;
|
||||
|
||||
memset(&tf1, 0, sizeof(tf1));
|
||||
tf1.reserved = 1;
|
||||
tests[0].val = &tf1;
|
||||
|
||||
memset(&tf2, 0, sizeof(tf2));
|
||||
tf2.forwardable = 1;
|
||||
tf2.pre_authent = 1;
|
||||
tests[1].val = &tf2;
|
||||
|
||||
memset(&tf3, 0, sizeof(tf3));
|
||||
tf3.pre_authent = 1;
|
||||
tests[2].val = &tf3;
|
||||
|
||||
memset(&tf4, 0, sizeof(tf4));
|
||||
tests[3].val = &tf4;
|
||||
|
||||
|
||||
return generic_test (tests, ntests, sizeof(TicketFlags),
|
||||
(generic_encode)encode_TicketFlags,
|
||||
(generic_length)length_TicketFlags,
|
||||
(generic_decode)decode_TicketFlags,
|
||||
(generic_free)free_TicketFlags,
|
||||
cmp_TicketFlags,
|
||||
(generic_copy)copy_TicketFlags);
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_KerberosTime (void *a, void *b)
|
||||
{
|
||||
KerberosTime *aa = a;
|
||||
KerberosTime *ab = b;
|
||||
|
||||
return *aa != *ab;
|
||||
}
|
||||
|
||||
static int
|
||||
test_time (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 17,
|
||||
"\x18\x0f\x31\x39\x37\x30\x30\x31\x30\x31\x30\x31\x31\x38\x33\x31"
|
||||
"\x5a",
|
||||
"time 1" },
|
||||
{ NULL, 17,
|
||||
"\x18\x0f\x32\x30\x30\x39\x30\x35\x32\x34\x30\x32\x30\x32\x34\x30"
|
||||
"\x5a"
|
||||
"time 2" }
|
||||
};
|
||||
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
KerberosTime times[] = {
|
||||
4711,
|
||||
1243130560
|
||||
};
|
||||
|
||||
tests[0].val = ×[0];
|
||||
tests[1].val = ×[1];
|
||||
|
||||
return generic_test (tests, ntests, sizeof(KerberosTime),
|
||||
(generic_encode)encode_KerberosTime,
|
||||
(generic_length)length_KerberosTime,
|
||||
(generic_decode)decode_KerberosTime,
|
||||
(generic_free)free_KerberosTime,
|
||||
cmp_KerberosTime,
|
||||
(generic_copy)copy_KerberosTime);
|
||||
}
|
||||
|
||||
struct {
|
||||
const char *cert;
|
||||
size_t len;
|
||||
} certs[] = {
|
||||
{
|
||||
"\x30\x82\x02\x6c\x30\x82\x01\xd5\xa0\x03\x02\x01\x02\x02\x09\x00"
|
||||
"\x99\x32\xde\x61\x0e\x40\x19\x8a\x30\x0d\x06\x09\x2a\x86\x48\x86"
|
||||
"\xf7\x0d\x01\x01\x05\x05\x00\x30\x2a\x31\x1b\x30\x19\x06\x03\x55"
|
||||
"\x04\x03\x0c\x12\x68\x78\x35\x30\x39\x20\x54\x65\x73\x74\x20\x52"
|
||||
"\x6f\x6f\x74\x20\x43\x41\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
|
||||
"\x02\x53\x45\x30\x1e\x17\x0d\x30\x39\x30\x34\x32\x36\x32\x30\x32"
|
||||
"\x39\x34\x30\x5a\x17\x0d\x31\x39\x30\x34\x32\x34\x32\x30\x32\x39"
|
||||
"\x34\x30\x5a\x30\x2a\x31\x1b\x30\x19\x06\x03\x55\x04\x03\x0c\x12"
|
||||
"\x68\x78\x35\x30\x39\x20\x54\x65\x73\x74\x20\x52\x6f\x6f\x74\x20"
|
||||
"\x43\x41\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x53\x45\x30"
|
||||
"\x81\x9f\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05"
|
||||
"\x00\x03\x81\x8d\x00\x30\x81\x89\x02\x81\x81\x00\xb9\xd3\x1b\x67"
|
||||
"\x1c\xf7\x5e\x26\x81\x3b\x82\xff\x03\xa4\x43\xb5\xb2\x63\x0b\x89"
|
||||
"\x58\x43\xfe\x3d\xe0\x38\x7d\x93\x74\xbb\xad\x21\xa4\x29\xd9\x34"
|
||||
"\x79\xf3\x1c\x8c\x5a\xd6\xb0\xd7\x19\xea\xcc\xaf\xe0\xa8\x40\x02"
|
||||
"\x1d\x91\xf1\xac\x36\xb0\xfb\x08\xbd\xcc\x9a\xe1\xb7\x6e\xee\x0a"
|
||||
"\x69\xbf\x6d\x2b\xee\x20\x82\x61\x06\xf2\x18\xcc\x89\x11\x64\x7e"
|
||||
"\xb2\xff\x47\xd1\x3b\x52\x73\xeb\x5a\xc0\x03\xa6\x4b\xc7\x40\x7e"
|
||||
"\xbc\xe1\x0e\x65\x44\x3f\x40\x8b\x02\x82\x54\x04\xd9\xcc\x2c\x67"
|
||||
"\x01\xb6\x16\x82\xd8\x33\x53\x17\xd7\xde\x8d\x5d\x02\x03\x01\x00"
|
||||
"\x01\xa3\x81\x99\x30\x81\x96\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16"
|
||||
"\x04\x14\x6e\x48\x13\xdc\xbf\x8b\x95\x4c\x13\xf3\x1f\x97\x30\xdd"
|
||||
"\x27\x96\x59\x9b\x0e\x68\x30\x5a\x06\x03\x55\x1d\x23\x04\x53\x30"
|
||||
"\x51\x80\x14\x6e\x48\x13\xdc\xbf\x8b\x95\x4c\x13\xf3\x1f\x97\x30"
|
||||
"\xdd\x27\x96\x59\x9b\x0e\x68\xa1\x2e\xa4\x2c\x30\x2a\x31\x1b\x30"
|
||||
"\x19\x06\x03\x55\x04\x03\x0c\x12\x68\x78\x35\x30\x39\x20\x54\x65"
|
||||
"\x73\x74\x20\x52\x6f\x6f\x74\x20\x43\x41\x31\x0b\x30\x09\x06\x03"
|
||||
"\x55\x04\x06\x13\x02\x53\x45\x82\x09\x00\x99\x32\xde\x61\x0e\x40"
|
||||
"\x19\x8a\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff"
|
||||
"\x30\x0b\x06\x03\x55\x1d\x0f\x04\x04\x03\x02\x01\xe6\x30\x0d\x06"
|
||||
"\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x03\x81\x81\x00"
|
||||
"\x52\x9b\xe4\x0e\xee\xc2\x5d\xb7\xf1\xba\x47\xe3\xfe\xaf\x3d\x51"
|
||||
"\x10\xfd\xe8\x0d\x14\x58\x05\x36\xa7\xeb\xd8\x05\xe5\x27\x6f\x51"
|
||||
"\xb8\xec\x90\xd9\x03\xe1\xbc\x9c\x93\x38\x21\x5c\xaf\x4e\x6c\x7b"
|
||||
"\x6c\x65\xa9\x92\xcd\x94\xef\xa8\xae\x90\x12\x14\x78\x2d\xa3\x15"
|
||||
"\xaa\x42\xf1\xd9\x44\x64\x2c\x3c\xc0\xbd\x3a\x48\xd8\x80\x45\x8b"
|
||||
"\xd1\x79\x82\xe0\x0f\xdf\x08\x3c\x60\x21\x6f\x31\x47\x98\xae\x2f"
|
||||
"\xcb\xb1\xa1\xb9\xc1\xa3\x71\x5e\x4a\xc2\x67\xdf\x66\x0a\x51\xb5"
|
||||
"\xad\x60\x05\xdb\x02\xd4\x1a\xd2\xb9\x4e\x01\x08\x2b\xc3\x57\xaf",
|
||||
624 },
|
||||
{
|
||||
"\x30\x82\x02\x54\x30\x82\x01\xbd\xa0\x03\x02\x01\x02\x02\x01\x08"
|
||||
"\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x30"
|
||||
"\x2a\x31\x1b\x30\x19\x06\x03\x55\x04\x03\x0c\x12\x68\x78\x35\x30"
|
||||
"\x39\x20\x54\x65\x73\x74\x20\x52\x6f\x6f\x74\x20\x43\x41\x31\x0b"
|
||||
"\x30\x09\x06\x03\x55\x04\x06\x13\x02\x53\x45\x30\x1e\x17\x0d\x30"
|
||||
"\x39\x30\x34\x32\x36\x32\x30\x32\x39\x34\x30\x5a\x17\x0d\x31\x39"
|
||||
"\x30\x34\x32\x34\x32\x30\x32\x39\x34\x30\x5a\x30\x1b\x31\x0b\x30"
|
||||
"\x09\x06\x03\x55\x04\x06\x13\x02\x53\x45\x31\x0c\x30\x0a\x06\x03"
|
||||
"\x55\x04\x03\x0c\x03\x6b\x64\x63\x30\x81\x9f\x30\x0d\x06\x09\x2a"
|
||||
"\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x81\x8d\x00\x30\x81"
|
||||
"\x89\x02\x81\x81\x00\xd2\x41\x7a\xf8\x4b\x55\xb2\xaf\x11\xf9\x43"
|
||||
"\x9b\x43\x81\x09\x3b\x9a\x94\xcf\x00\xf4\x85\x75\x92\xd7\x2a\xa5"
|
||||
"\x11\xf1\xa8\x50\x6e\xc6\x84\x74\x24\x17\xda\x84\xc8\x03\x37\xb2"
|
||||
"\x20\xf3\xba\xb5\x59\x36\x21\x4d\xab\x70\xe2\xc3\x09\x93\x68\x14"
|
||||
"\x12\x79\xc5\xbb\x9e\x1b\x4a\xf0\xc6\x24\x59\x25\xc3\x1c\xa8\x70"
|
||||
"\x66\x5b\x3e\x41\x8e\xe3\x25\x71\x9a\x94\xa0\x5b\x46\x91\x6f\xdd"
|
||||
"\x58\x14\xec\x89\xe5\x8c\x96\xc5\x38\x60\xe4\xab\xf2\x75\xee\x6e"
|
||||
"\x62\xfc\xe1\xbd\x03\x47\xff\xc4\xbe\x0f\xca\x70\x73\xe3\x74\x58"
|
||||
"\x3a\x2f\x04\x2d\x39\x02\x03\x01\x00\x01\xa3\x81\x98\x30\x81\x95"
|
||||
"\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55"
|
||||
"\x1d\x0f\x04\x04\x03\x02\x05\xe0\x30\x12\x06\x03\x55\x1d\x25\x04"
|
||||
"\x0b\x30\x09\x06\x07\x2b\x06\x01\x05\x02\x03\x05\x30\x1d\x06\x03"
|
||||
"\x55\x1d\x0e\x04\x16\x04\x14\x3a\xd3\x73\xff\xab\xdb\x7d\x8d\xc6"
|
||||
"\x3a\xa2\x26\x3e\xae\x78\x95\x80\xc9\xe6\x31\x30\x48\x06\x03\x55"
|
||||
"\x1d\x11\x04\x41\x30\x3f\xa0\x3d\x06\x06\x2b\x06\x01\x05\x02\x02"
|
||||
"\xa0\x33\x30\x31\xa0\x0d\x1b\x0b\x54\x45\x53\x54\x2e\x48\x35\x4c"
|
||||
"\x2e\x53\x45\xa1\x20\x30\x1e\xa0\x03\x02\x01\x01\xa1\x17\x30\x15"
|
||||
"\x1b\x06\x6b\x72\x62\x74\x67\x74\x1b\x0b\x54\x45\x53\x54\x2e\x48"
|
||||
"\x35\x4c\x2e\x53\x45\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01"
|
||||
"\x01\x05\x05\x00\x03\x81\x81\x00\x83\xf4\x14\xa7\x6e\x59\xff\x80"
|
||||
"\x64\xe7\xfa\xcf\x13\x80\x86\xe1\xed\x02\x38\xad\x96\x72\x25\xe5"
|
||||
"\x06\x7a\x9a\xbc\x24\x74\xa9\x75\x55\xb2\x49\x80\x69\x45\x95\x4a"
|
||||
"\x4c\x76\xa9\xe3\x4e\x49\xd3\xc2\x69\x5a\x95\x03\xeb\xba\x72\x23"
|
||||
"\x9c\xfd\x3d\x8b\xc6\x07\x82\x3b\xf4\xf3\xef\x6c\x2e\x9e\x0b\xac"
|
||||
"\x9e\x6c\xbb\x37\x4a\xa1\x9e\x73\xd1\xdc\x97\x61\xba\xfc\xd3\x49"
|
||||
"\xa6\xc2\x4c\x55\x2e\x06\x37\x76\xb5\xef\x57\xe7\x57\x58\x8a\x71"
|
||||
"\x63\xf3\xeb\xe7\x55\x68\x0d\xf6\x46\x4c\xfb\xf9\x43\xbb\x0c\x92"
|
||||
"\x4f\x4e\x22\x7b\x63\xe8\x4f\x9c",
|
||||
600
|
||||
}
|
||||
};
|
||||
|
||||
static int
|
||||
test_cert(void)
|
||||
{
|
||||
Certificate c, c2;
|
||||
size_t size;
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < sizeof(certs)/sizeof(certs[0]); i++) {
|
||||
|
||||
ret = decode_Certificate((unsigned char *)certs[i].cert,
|
||||
certs[i].len, &c, &size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = copy_Certificate(&c, &c2);
|
||||
free_Certificate(&c);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
free_Certificate(&c2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmp_TESTLargeTag (void *a, void *b)
|
||||
{
|
||||
@@ -441,6 +666,7 @@ cmp_TESTLargeTag (void *a, void *b)
|
||||
TESTLargeTag *ab = b;
|
||||
|
||||
COMPARE_INTEGER(aa,ab,foo);
|
||||
COMPARE_INTEGER(aa,ab,bar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -448,7 +674,7 @@ static int
|
||||
test_large_tag (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 8, "\x30\x06\xbf\x7f\x03\x02\x01\x01", "large tag 1" }
|
||||
{ NULL, 15, "\x30\x0d\xbf\x7f\x03\x02\x01\x01\xbf\x81\x00\x03\x02\x01\x02", "large tag 1" }
|
||||
};
|
||||
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
@@ -456,6 +682,7 @@ test_large_tag (void)
|
||||
|
||||
memset(<1, 0, sizeof(lt1));
|
||||
lt1.foo = 1;
|
||||
lt1.bar = 2;
|
||||
|
||||
tests[0].val = <1;
|
||||
|
||||
@@ -464,7 +691,8 @@ test_large_tag (void)
|
||||
(generic_length)length_TESTLargeTag,
|
||||
(generic_decode)decode_TESTLargeTag,
|
||||
(generic_free)free_TESTLargeTag,
|
||||
cmp_TESTLargeTag);
|
||||
cmp_TESTLargeTag,
|
||||
(generic_copy)copy_TESTLargeTag);
|
||||
}
|
||||
|
||||
struct test_data {
|
||||
@@ -490,9 +718,9 @@ check_tag_length(void)
|
||||
{ 0, 5, 0, "\x02\xff\x7f\x02\x00"}
|
||||
};
|
||||
size_t sz;
|
||||
krb5uint32 values[] = {0, 127, 128, 256, 512,
|
||||
TESTuint32 values[] = {0, 127, 128, 256, 512,
|
||||
0, 127, 128, 256, 512 };
|
||||
krb5uint32 u;
|
||||
TESTuint32 u;
|
||||
int i, ret, failed = 0;
|
||||
void *buf;
|
||||
|
||||
@@ -501,7 +729,7 @@ check_tag_length(void)
|
||||
|
||||
buf = map_alloc(OVERRUN, td[i].data, td[i].len, &page);
|
||||
|
||||
ret = decode_krb5uint32(buf, td[i].len, &u, &sz);
|
||||
ret = decode_TESTuint32(buf, td[i].len, &u, &sz);
|
||||
if (ret) {
|
||||
if (td[i].ok) {
|
||||
printf("failed with tag len test %d\n", i);
|
||||
@@ -560,7 +788,8 @@ test_choice (void)
|
||||
(generic_length)length_TESTChoice1,
|
||||
(generic_decode)decode_TESTChoice1,
|
||||
(generic_free)free_TESTChoice1,
|
||||
cmp_TESTChoice);
|
||||
cmp_TESTChoice,
|
||||
(generic_copy)copy_TESTChoice1);
|
||||
|
||||
memset(&c2_2, 0, sizeof(c2_2));
|
||||
c2_2.element = choice_TESTChoice2_asn1_ellipsis;
|
||||
@@ -573,7 +802,8 @@ test_choice (void)
|
||||
(generic_length)length_TESTChoice2,
|
||||
(generic_decode)decode_TESTChoice2,
|
||||
(generic_free)free_TESTChoice2,
|
||||
cmp_TESTChoice);
|
||||
cmp_TESTChoice,
|
||||
(generic_copy)copy_TESTChoice2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -623,7 +853,8 @@ test_implicit (void)
|
||||
(generic_length)length_TESTImplicit,
|
||||
(generic_decode)decode_TESTImplicit,
|
||||
(generic_free)free_TESTImplicit,
|
||||
cmp_TESTImplicit);
|
||||
cmp_TESTImplicit,
|
||||
(generic_copy)copy_TESTImplicit);
|
||||
|
||||
#ifdef IMPLICIT_TAGGING_WORKS
|
||||
ret += generic_test (tests, ntests, sizeof(TESTImplicit2),
|
||||
@@ -631,7 +862,8 @@ test_implicit (void)
|
||||
(generic_length)length_TESTImplicit2,
|
||||
(generic_decode)decode_TESTImplicit2,
|
||||
(generic_free)free_TESTImplicit2,
|
||||
cmp_TESTImplicit);
|
||||
cmp_TESTImplicit,
|
||||
NULL);
|
||||
|
||||
#endif /* IMPLICIT_TAGGING_WORKS */
|
||||
return ret;
|
||||
@@ -718,13 +950,95 @@ test_taglessalloc (void)
|
||||
(generic_length)length_TESTAlloc,
|
||||
(generic_decode)decode_TESTAlloc,
|
||||
(generic_free)free_TESTAlloc,
|
||||
cmp_TESTAlloc);
|
||||
cmp_TESTAlloc,
|
||||
(generic_copy)copy_TESTAlloc);
|
||||
|
||||
free(c1.tagless);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_TESTOptional (void *a, void *b)
|
||||
{
|
||||
TESTOptional *aa = a;
|
||||
TESTOptional *ab = b;
|
||||
|
||||
IF_OPT_COMPARE(aa,ab,zero) {
|
||||
COMPARE_OPT_INTEGER(aa,ab,zero);
|
||||
}
|
||||
IF_OPT_COMPARE(aa,ab,one) {
|
||||
COMPARE_OPT_INTEGER(aa,ab,one);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
UNIV CONS Sequence 5
|
||||
CONTEXT CONS 0 3
|
||||
UNIV PRIM Integer 1 00
|
||||
|
||||
UNIV CONS Sequence 5
|
||||
CONTEXT CONS 1 3
|
||||
UNIV PRIM Integer 1 03
|
||||
|
||||
UNIV CONS Sequence 10
|
||||
CONTEXT CONS 0 3
|
||||
UNIV PRIM Integer 1 00
|
||||
CONTEXT CONS 1 3
|
||||
UNIV PRIM Integer 1 01
|
||||
|
||||
*/
|
||||
|
||||
static int
|
||||
test_optional (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 2,
|
||||
"\x30\x00",
|
||||
"optional 0" },
|
||||
{ NULL, 7,
|
||||
"\x30\x05\xa0\x03\x02\x01\x00",
|
||||
"optional 1" },
|
||||
{ NULL, 7,
|
||||
"\x30\x05\xa1\x03\x02\x01\x01",
|
||||
"optional 2" },
|
||||
{ NULL, 12,
|
||||
"\x30\x0a\xa0\x03\x02\x01\x00\xa1\x03\x02\x01\x01",
|
||||
"optional 3" }
|
||||
};
|
||||
|
||||
int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
|
||||
TESTOptional c0, c1, c2, c3;
|
||||
int zero = 0;
|
||||
int one = 1;
|
||||
|
||||
c0.zero = NULL;
|
||||
c0.one = NULL;
|
||||
tests[0].val = &c0;
|
||||
|
||||
c1.zero = &zero;
|
||||
c1.one = NULL;
|
||||
tests[1].val = &c1;
|
||||
|
||||
c2.zero = NULL;
|
||||
c2.one = &one;
|
||||
tests[2].val = &c2;
|
||||
|
||||
c3.zero = &zero;
|
||||
c3.one = &one;
|
||||
tests[3].val = &c3;
|
||||
|
||||
ret += generic_test (tests, ntests, sizeof(TESTOptional),
|
||||
(generic_encode)encode_TESTOptional,
|
||||
(generic_length)length_TESTOptional,
|
||||
(generic_decode)decode_TESTOptional,
|
||||
(generic_free)free_TESTOptional,
|
||||
cmp_TESTOptional,
|
||||
(generic_copy)copy_TESTOptional);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_largetag(void)
|
||||
@@ -793,10 +1107,10 @@ check_fail_choice(void)
|
||||
struct test_case tests[] = {
|
||||
{NULL, 6,
|
||||
"\xa1\x02\x02\x01\x01",
|
||||
"one too short"},
|
||||
"choice one too short"},
|
||||
{NULL, 6,
|
||||
"\xa1\x03\x02\x02\x01",
|
||||
"one too short inner"}
|
||||
"choice one too short inner"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
@@ -877,6 +1191,7 @@ out:
|
||||
static int
|
||||
check_seq_of_size(void)
|
||||
{
|
||||
#if 0 /* template */
|
||||
TESTInteger integers[4] = { 1, 2, 3, 4 };
|
||||
int ret;
|
||||
|
||||
@@ -920,12 +1235,10 @@ check_seq_of_size(void)
|
||||
test_seq_of(TESTSeqSizeOf4, 1, &ssof4ok3);
|
||||
test_seq_of(TESTSeqSizeOf4, 0, &ssof4f1);
|
||||
}
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -936,6 +1249,9 @@ main(int argc, char **argv)
|
||||
ret += test_krb_error();
|
||||
ret += test_Name();
|
||||
ret += test_bit_string();
|
||||
ret += test_bit_string_rfc1510();
|
||||
ret += test_time();
|
||||
ret += test_cert();
|
||||
|
||||
ret += check_tag_length();
|
||||
ret += test_large_tag();
|
||||
@@ -943,6 +1259,7 @@ main(int argc, char **argv)
|
||||
|
||||
ret += test_implicit();
|
||||
ret += test_taglessalloc();
|
||||
ret += test_optional();
|
||||
|
||||
ret += check_fail_largetag();
|
||||
ret += check_fail_sequence();
|
||||
|
255
lib/asn1/check-template.c
Normal file
255
lib/asn1/check-template.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. 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.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <roken.h>
|
||||
|
||||
#include <asn1-common.h>
|
||||
#include <asn1_err.h>
|
||||
#include <der.h>
|
||||
#include <test_asn1.h>
|
||||
|
||||
#include "check-common.h"
|
||||
|
||||
static int
|
||||
cmp_dummy (void *a, void *b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_seqofseq(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 2,
|
||||
"\x30\x00",
|
||||
"seqofseq 0" },
|
||||
{ NULL, 9,
|
||||
"\x30\x07\x30\x05\xa0\x03\x02\x01\x00",
|
||||
"seqofseq 1" },
|
||||
{ NULL, 16,
|
||||
"\x30\x0e\x30\x05\xa0\x03\x02\x01\x00\x30\x05\xa0\x03\x02\x01\x01",
|
||||
"seqofseq 2" }
|
||||
};
|
||||
|
||||
int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
|
||||
TESTSeqOfSeq c0, c1, c2;
|
||||
struct TESTSeqOfSeq_val i[2];
|
||||
|
||||
i[0].zero = 0;
|
||||
i[1].zero = 1;
|
||||
|
||||
c0.len = 0;
|
||||
c0.val = NULL;
|
||||
tests[0].val = &c0;
|
||||
|
||||
c1.len = 1;
|
||||
c1.val = i;
|
||||
tests[1].val = &c1;
|
||||
|
||||
c2.len = 2;
|
||||
c2.val = i;
|
||||
tests[2].val = &c2;
|
||||
|
||||
ret += generic_test (tests, ntests, sizeof(TESTSeqOfSeq),
|
||||
(generic_encode)encode_TESTSeqOfSeq,
|
||||
(generic_length)length_TESTSeqOfSeq,
|
||||
(generic_decode)decode_TESTSeqOfSeq,
|
||||
(generic_free)free_TESTSeqOfSeq,
|
||||
cmp_dummy,
|
||||
NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
test_seqofseq2(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 2,
|
||||
"\x30\x00",
|
||||
"seqofseq2 0" },
|
||||
{ NULL, 11,
|
||||
"\x30\x09\x30\x07\xa0\x05\x1b\x03\x65\x74\x74",
|
||||
"seqofseq2 1" },
|
||||
{ NULL, 21,
|
||||
"\x30\x13\x30\x07\xa0\x05\x1b\x03\x65\x74\x74\x30\x08\xa0"
|
||||
"\x06\x1b\x04\x74\x76\x61\x61",
|
||||
"seqofseq2 2" }
|
||||
};
|
||||
|
||||
int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
|
||||
TESTSeqOfSeq2 c0, c1, c2;
|
||||
struct TESTSeqOfSeq2_val i[2];
|
||||
|
||||
i[0].string = "ett";
|
||||
i[1].string = "tvaa";
|
||||
|
||||
c0.len = 0;
|
||||
c0.val = NULL;
|
||||
tests[0].val = &c0;
|
||||
|
||||
c1.len = 1;
|
||||
c1.val = i;
|
||||
tests[1].val = &c1;
|
||||
|
||||
c2.len = 2;
|
||||
c2.val = i;
|
||||
tests[2].val = &c2;
|
||||
|
||||
ret += generic_test (tests, ntests, sizeof(TESTSeqOfSeq2),
|
||||
(generic_encode)encode_TESTSeqOfSeq2,
|
||||
(generic_length)length_TESTSeqOfSeq2,
|
||||
(generic_decode)decode_TESTSeqOfSeq2,
|
||||
(generic_free)free_TESTSeqOfSeq2,
|
||||
cmp_dummy,
|
||||
NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
test_seqof2(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 4,
|
||||
"\x30\x02\x30\x00",
|
||||
"seqof2 1" },
|
||||
{ NULL, 9,
|
||||
"\x30\x07\x30\x05\x1b\x03\x66\x6f\x6f",
|
||||
"seqof2 2" },
|
||||
{ NULL, 14,
|
||||
"\x30\x0c\x30\x0a\x1b\x03\x66\x6f\x6f\x1b\x03\x62\x61\x72",
|
||||
"seqof2 3" }
|
||||
};
|
||||
|
||||
int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
|
||||
TESTSeqOf2 c0, c1, c2;
|
||||
heim_general_string i[2];
|
||||
|
||||
i[0] = "foo";
|
||||
i[1] = "bar";
|
||||
|
||||
c0.strings.val = NULL;
|
||||
c0.strings.len = 0;
|
||||
tests[0].val = &c0;
|
||||
|
||||
c1.strings.len = 1;
|
||||
c1.strings.val = i;
|
||||
tests[1].val = &c1;
|
||||
|
||||
c2.strings.len = 2;
|
||||
c2.strings.val = i;
|
||||
tests[2].val = &c2;
|
||||
|
||||
ret += generic_test (tests, ntests, sizeof(TESTSeqOf2),
|
||||
(generic_encode)encode_TESTSeqOf2,
|
||||
(generic_length)length_TESTSeqOf2,
|
||||
(generic_decode)decode_TESTSeqOf2,
|
||||
(generic_free)free_TESTSeqOf2,
|
||||
cmp_dummy,
|
||||
NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
test_seqof3(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 2,
|
||||
"\x30\x00",
|
||||
"seqof3 0" },
|
||||
{ NULL, 4,
|
||||
"\x30\x02\x30\x00",
|
||||
"seqof3 1" },
|
||||
{ NULL, 9,
|
||||
"\x30\x07\x30\x05\x1b\x03\x66\x6f\x6f",
|
||||
"seqof3 2" },
|
||||
{ NULL, 14,
|
||||
"\x30\x0c\x30\x0a\x1b\x03\x66\x6f\x6f\x1b\x03\x62\x61\x72",
|
||||
"seqof3 3" }
|
||||
};
|
||||
|
||||
int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
|
||||
TESTSeqOf3 c0, c1, c2, c3;
|
||||
struct TESTSeqOf3_strings s1, s2, s3;
|
||||
heim_general_string i[2];
|
||||
|
||||
i[0] = "foo";
|
||||
i[1] = "bar";
|
||||
|
||||
c0.strings = NULL;
|
||||
tests[0].val = &c0;
|
||||
|
||||
s1.val = NULL;
|
||||
s1.len = 0;
|
||||
c1.strings = &s1;
|
||||
tests[1].val = &c1;
|
||||
|
||||
s2.len = 1;
|
||||
s2.val = i;
|
||||
c2.strings = &s2;
|
||||
tests[2].val = &c2;
|
||||
|
||||
s3.len = 2;
|
||||
s3.val = i;
|
||||
c3.strings = &s3;
|
||||
tests[3].val = &c3;
|
||||
|
||||
ret += generic_test (tests, ntests, sizeof(TESTSeqOf3),
|
||||
(generic_encode)encode_TESTSeqOf3,
|
||||
(generic_length)length_TESTSeqOf3,
|
||||
(generic_decode)decode_TESTSeqOf3,
|
||||
(generic_free)free_TESTSeqOf3,
|
||||
cmp_dummy,
|
||||
NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret += test_seqofseq();
|
||||
ret += test_seqofseq2();
|
||||
ret += test_seqof2();
|
||||
ret += test_seqof3();
|
||||
|
||||
return ret;
|
||||
}
|
@@ -4,7 +4,7 @@
|
||||
CMS DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS CertificateSerialNumber, AlgorithmIdentifier, Name,
|
||||
Attribute, Certificate, Name, SubjectKeyIdentifier FROM rfc2459
|
||||
Attribute, Certificate, SubjectKeyIdentifier FROM rfc2459
|
||||
heim_any, heim_any_set FROM heim;
|
||||
|
||||
id-pkcs7 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
|
@@ -94,6 +94,8 @@ typedef struct heim_ber_time_t {
|
||||
int bt_zone;
|
||||
} heim_ber_time_t;
|
||||
|
||||
struct asn1_template;
|
||||
|
||||
#include <der-protos.h>
|
||||
|
||||
int _heim_fix_dce(size_t reallen, size_t *len);
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -45,6 +47,34 @@ der_copy_general_string (const heim_general_string *from,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_integer (const int *from, int *to)
|
||||
{
|
||||
*to = *from;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_unsigned (const unsigned *from, unsigned *to)
|
||||
{
|
||||
*to = *from;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_generalized_time (const time_t *from, time_t *to)
|
||||
{
|
||||
*to = *from;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_utctime (const time_t *from, time_t *to)
|
||||
{
|
||||
*to = *from;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
|
||||
{
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -42,6 +44,31 @@ der_free_general_string (heim_general_string *str)
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_integer (int *i)
|
||||
{
|
||||
*i = 0;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_unsigned (unsigned *u)
|
||||
{
|
||||
*u = 0;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_generalized_time(time_t *t)
|
||||
{
|
||||
*t = 0;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_utctime(time_t *t)
|
||||
{
|
||||
*t = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
der_free_utf8string (heim_utf8_string *str)
|
||||
{
|
||||
|
@@ -305,7 +305,7 @@ der_get_octet_string_ber (const unsigned char *p, size_t len,
|
||||
void *ptr;
|
||||
|
||||
ptr = realloc(data->data, data->length + datalen);
|
||||
if (ptr == NULL && data->length + datalen != 0) {
|
||||
if (ptr == NULL) {
|
||||
e = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -354,23 +354,21 @@ der_get_heim_integer (const unsigned char *p, size_t len,
|
||||
p++;
|
||||
data->length--;
|
||||
}
|
||||
if (data->length) {
|
||||
data->data = malloc(data->length);
|
||||
if (data->data == NULL) {
|
||||
data->length = 0;
|
||||
if (size)
|
||||
*size = 0;
|
||||
return ENOMEM;
|
||||
}
|
||||
q = &((unsigned char*)data->data)[data->length - 1];
|
||||
p += data->length - 1;
|
||||
while (q >= (unsigned char*)data->data) {
|
||||
*q = *p ^ 0xff;
|
||||
if (carry)
|
||||
carry = !++*q;
|
||||
p--;
|
||||
q--;
|
||||
}
|
||||
data->data = malloc(data->length);
|
||||
if (data->data == NULL) {
|
||||
data->length = 0;
|
||||
if (size)
|
||||
*size = 0;
|
||||
return ENOMEM;
|
||||
}
|
||||
q = &((unsigned char*)data->data)[data->length - 1];
|
||||
p += data->length - 1;
|
||||
while (q >= (unsigned char*)data->data) {
|
||||
*q = *p ^ 0xff;
|
||||
if (carry)
|
||||
carry = !++*q;
|
||||
p--;
|
||||
q--;
|
||||
}
|
||||
} else {
|
||||
data->negative = 0;
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -112,6 +114,20 @@ der_length_len (size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_tag(unsigned int tag)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
if(tag <= 30)
|
||||
return 1;
|
||||
while(tag) {
|
||||
tag /= 128;
|
||||
len++;
|
||||
}
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_integer (const int *data)
|
||||
{
|
||||
|
@@ -52,6 +52,8 @@
|
||||
#include <asn1-common.h>
|
||||
#include <asn1_err.h>
|
||||
#include <der.h>
|
||||
#include <der-private.h>
|
||||
#include "asn1-template.h"
|
||||
|
||||
time_t _der_timegm (struct tm *);
|
||||
size_t _heim_len_unsigned (unsigned);
|
||||
|
@@ -100,6 +100,21 @@ NTLMResponse ::= SEQUENCE {
|
||||
tickets [3] SEQUENCE OF OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
NTLMRequest2 ::= SEQUENCE {
|
||||
loginUserName [0] UTF8String,
|
||||
loginDomainName [1] UTF8String,
|
||||
flags [2] INTEGER (0..4294967295),
|
||||
lmchallenge [3] OCTET STRING SIZE (8),
|
||||
ntChallengeResponce [4] OCTET STRING,
|
||||
lmChallengeResponce [5] OCTET STRING
|
||||
}
|
||||
|
||||
NTLMReply ::= SEQUENCE {
|
||||
success [0] BOOLEAN,
|
||||
flags [1] INTEGER (0..4294967295),
|
||||
sessionkey [2] OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
DigestReqInner ::= CHOICE {
|
||||
init [0] DigestInit,
|
||||
digestRequest [1] DigestRequest,
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -40,13 +42,7 @@ int
|
||||
encode_heim_any(unsigned char *p, size_t len,
|
||||
const heim_any *data, size_t *size)
|
||||
{
|
||||
if (data->length > len)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= data->length;
|
||||
len -= data->length;
|
||||
memcpy (p+1, data->data, data->length);
|
||||
*size = data->length;
|
||||
return 0;
|
||||
return der_put_octet_string (p, len, data, size);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -91,8 +87,7 @@ decode_heim_any(const unsigned char *p, size_t len,
|
||||
void
|
||||
free_heim_any(heim_any *data)
|
||||
{
|
||||
free(data->data);
|
||||
data->data = NULL;
|
||||
der_free_octet_string(data);
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -104,58 +99,43 @@ length_heim_any(const heim_any *data)
|
||||
int
|
||||
copy_heim_any(const heim_any *from, heim_any *to)
|
||||
{
|
||||
to->data = malloc(from->length);
|
||||
if (to->data == NULL && from->length != 0)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, from->length);
|
||||
to->length = from->length;
|
||||
return 0;
|
||||
return der_copy_octet_string(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
encode_heim_any_set(unsigned char *p, size_t len,
|
||||
const heim_any_set *data, size_t *size)
|
||||
{
|
||||
return encode_heim_any(p, len, data, size);
|
||||
return der_put_octet_string (p, len, data, size);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
decode_heim_any_set(const unsigned char *p, size_t len,
|
||||
heim_any_set *data, size_t *size)
|
||||
{
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->data = malloc(len);
|
||||
if (data->data == NULL && len != 0)
|
||||
return ENOMEM;
|
||||
data->length = len;
|
||||
memcpy(data->data, p, len);
|
||||
if (size) *size = len;
|
||||
return 0;
|
||||
return der_get_octet_string(p, len, data, size);
|
||||
}
|
||||
|
||||
void
|
||||
free_heim_any_set(heim_any_set *data)
|
||||
{
|
||||
free_heim_any(data);
|
||||
der_free_octet_string(data);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_heim_any_set(const heim_any *data)
|
||||
{
|
||||
return length_heim_any(data);
|
||||
return data->length;
|
||||
}
|
||||
|
||||
int
|
||||
copy_heim_any_set(const heim_any_set *from, heim_any_set *to)
|
||||
{
|
||||
return copy_heim_any(from, to);
|
||||
return der_copy_octet_string(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
heim_any_cmp(const heim_any_set *p, const heim_any_set *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, p->length);
|
||||
return der_heim_octet_string_cmp(p, q);
|
||||
}
|
||||
|
257
lib/asn1/gen.c
257
lib/asn1/gen.c
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -35,12 +37,12 @@
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
FILE *headerfile, *codefile, *logfile;
|
||||
FILE *privheaderfile, *headerfile, *codefile, *logfile, *templatefile;
|
||||
|
||||
#define STEM "asn1"
|
||||
|
||||
static const char *orig_filename;
|
||||
static char *header;
|
||||
static char *privheader, *header, *template;
|
||||
static const char *headerbase = STEM;
|
||||
|
||||
/*
|
||||
@@ -66,6 +68,45 @@ add_import (const char *module)
|
||||
fprintf (headerfile, "#include <%s_asn1.h>\n", module);
|
||||
}
|
||||
|
||||
/*
|
||||
* List of all exported symbols
|
||||
*/
|
||||
|
||||
struct sexport {
|
||||
const char *name;
|
||||
int defined;
|
||||
struct sexport *next;
|
||||
};
|
||||
|
||||
static struct sexport *exports = NULL;
|
||||
|
||||
void
|
||||
add_export (const char *name)
|
||||
{
|
||||
struct sexport *tmp = emalloc (sizeof(*tmp));
|
||||
|
||||
tmp->name = name;
|
||||
tmp->next = exports;
|
||||
exports = tmp;
|
||||
}
|
||||
|
||||
int
|
||||
is_export(const char *name)
|
||||
{
|
||||
struct sexport *tmp;
|
||||
|
||||
if (exports == NULL) /* no export list, all exported */
|
||||
return 1;
|
||||
|
||||
for (tmp = exports; tmp != NULL; tmp = tmp->next) {
|
||||
if (strcmp(tmp->name, name) == 0) {
|
||||
tmp->defined = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
get_filename (void)
|
||||
{
|
||||
@@ -96,6 +137,23 @@ init_generate (const char *filename, const char *base)
|
||||
err (1, "open %s", fn);
|
||||
free(fn);
|
||||
|
||||
/* private header file */
|
||||
asprintf(&privheader, "%s-priv.h", headerbase);
|
||||
if (privheader == NULL)
|
||||
errx(1, "malloc");
|
||||
asprintf(&fn, "%s-priv.hx", headerbase);
|
||||
if (fn == NULL)
|
||||
errx(1, "malloc");
|
||||
privheaderfile = fopen (fn, "w");
|
||||
if (privheaderfile == NULL)
|
||||
err (1, "open %s", fn);
|
||||
free(fn);
|
||||
|
||||
/* template file */
|
||||
asprintf(&template, "%s-template.c", headerbase);
|
||||
if (template == NULL)
|
||||
errx(1, "malloc");
|
||||
|
||||
fprintf (headerfile,
|
||||
"/* Generated from %s */\n"
|
||||
"/* Do not edit */\n\n",
|
||||
@@ -182,6 +240,36 @@ init_generate (const char *filename, const char *base)
|
||||
logfile = fopen(fn, "w");
|
||||
if (logfile == NULL)
|
||||
err (1, "open %s", fn);
|
||||
|
||||
/* if one code file, write into the one codefile */
|
||||
if (one_code_file)
|
||||
return;
|
||||
|
||||
templatefile = fopen (template, "w");
|
||||
if (templatefile == NULL)
|
||||
err (1, "open %s", template);
|
||||
|
||||
fprintf (templatefile,
|
||||
"/* Generated from %s */\n"
|
||||
"/* Do not edit */\n\n"
|
||||
"#include <stdio.h>\n"
|
||||
"#include <stdlib.h>\n"
|
||||
"#include <time.h>\n"
|
||||
"#include <string.h>\n"
|
||||
"#include <errno.h>\n"
|
||||
"#include <limits.h>\n"
|
||||
"#include <krb5-types.h>\n",
|
||||
filename);
|
||||
|
||||
fprintf (templatefile,
|
||||
"#include <%s>\n"
|
||||
"#include <%s>\n"
|
||||
"#include <der.h>\n"
|
||||
"#include <der-private.h>\n"
|
||||
"#include <asn1-template.h>\n",
|
||||
header, privheader);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -190,6 +278,8 @@ close_generate (void)
|
||||
fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase);
|
||||
|
||||
fclose (headerfile);
|
||||
fclose (privheaderfile);
|
||||
fclose (templatefile);
|
||||
fprintf (logfile, "\n");
|
||||
fclose (logfile);
|
||||
}
|
||||
@@ -265,11 +355,14 @@ generate_header_of_codefile(const char *name)
|
||||
orig_filename);
|
||||
|
||||
fprintf (codefile,
|
||||
"#include <%s.h>\n",
|
||||
headerbase);
|
||||
"#include <%s>\n"
|
||||
"#include <%s>\n",
|
||||
header, privheader);
|
||||
fprintf (codefile,
|
||||
"#include <asn1_err.h>\n"
|
||||
"#include <der.h>\n"
|
||||
"#include <der-private.h>\n"
|
||||
"#include <asn1-template.h>\n"
|
||||
"#include <parse_units.h>\n\n");
|
||||
|
||||
}
|
||||
@@ -328,8 +421,6 @@ generate_constant (const Symbol *s)
|
||||
}
|
||||
|
||||
fprintf (headerfile, "} */\n");
|
||||
fprintf (headerfile, "const heim_oid *oid_%s(void);\n",
|
||||
s->gen_name);
|
||||
fprintf (headerfile,
|
||||
"extern const heim_oid asn1_oid_%s;\n\n",
|
||||
s->gen_name);
|
||||
@@ -346,12 +437,6 @@ generate_constant (const Symbol *s)
|
||||
"{ %d, oid_%s_variable_num };\n\n",
|
||||
s->gen_name, len, s->gen_name);
|
||||
|
||||
fprintf (codefile, "const heim_oid *oid_%s(void)\n"
|
||||
"{\n"
|
||||
"return &asn1_oid_%s;\n"
|
||||
"}\n\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
free(list);
|
||||
|
||||
if (!one_code_file)
|
||||
@@ -364,6 +449,33 @@ generate_constant (const Symbol *s)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
is_primitive_type(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case TInteger:
|
||||
case TBoolean:
|
||||
case TOctetString:
|
||||
case TBitString:
|
||||
case TEnumerated:
|
||||
case TGeneralizedTime:
|
||||
case TGeneralString:
|
||||
case TTeletexString:
|
||||
case TOID:
|
||||
case TUTCTime:
|
||||
case TUTF8String:
|
||||
case TPrintableString:
|
||||
case TIA5String:
|
||||
case TBMPString:
|
||||
case TUniversalString:
|
||||
case TVisibleString:
|
||||
case TNull:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
space(int level)
|
||||
{
|
||||
@@ -550,8 +662,24 @@ define_asn1 (int level, Type *t)
|
||||
}
|
||||
|
||||
static void
|
||||
define_type (int level, const char *name, Type *t, int typedefp, int preservep)
|
||||
getnewbasename(char **newbasename, int typedefp, const char *basename, const char *name)
|
||||
{
|
||||
if (typedefp)
|
||||
*newbasename = strdup(name);
|
||||
else {
|
||||
if (name[0] == '*')
|
||||
name++;
|
||||
asprintf(newbasename, "%s_%s", basename, name);
|
||||
}
|
||||
if (*newbasename == NULL)
|
||||
err(1, "malloc");
|
||||
}
|
||||
|
||||
static void
|
||||
define_type (int level, const char *name, const char *basename, Type *t, int typedefp, int preservep)
|
||||
{
|
||||
char *newbasename = NULL;
|
||||
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
space(level);
|
||||
@@ -602,16 +730,37 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
|
||||
if(ASN1_TAILQ_EMPTY(t->members))
|
||||
fprintf (headerfile, "heim_bit_string %s;\n", name);
|
||||
else {
|
||||
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
|
||||
int pos = 0;
|
||||
getnewbasename(&newbasename, typedefp, basename, name);
|
||||
|
||||
fprintf (headerfile, "struct %s {\n", newbasename);
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *n;
|
||||
|
||||
/* pad unused */
|
||||
while (pos < m->val) {
|
||||
asprintf (&n, "_unused%d:1;", pos);
|
||||
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
|
||||
free(n);
|
||||
pos++;
|
||||
}
|
||||
|
||||
asprintf (&n, "%s:1", m->gen_name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
define_type (level + 1, n, &i, FALSE, FALSE);
|
||||
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
|
||||
free (n);
|
||||
pos++;
|
||||
}
|
||||
/* pad to 32 elements */
|
||||
while (pos < 32) {
|
||||
char *n;
|
||||
asprintf (&n, "_unused%d:1;", pos);
|
||||
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
|
||||
free(n);
|
||||
pos++;
|
||||
}
|
||||
|
||||
space(level);
|
||||
fprintf (headerfile, "} %s;\n\n", name);
|
||||
}
|
||||
@@ -638,8 +787,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
|
||||
getnewbasename(&newbasename, typedefp, basename, name);
|
||||
|
||||
space(level);
|
||||
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
|
||||
fprintf (headerfile, "struct %s {\n", newbasename);
|
||||
if (t->type == TSequence && preservep) {
|
||||
space(level + 1);
|
||||
fprintf(headerfile, "heim_octet_string _save;\n");
|
||||
@@ -653,10 +804,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
|
||||
asprintf (&n, "*%s", m->gen_name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
define_type (level + 1, n, m->type, FALSE, FALSE);
|
||||
define_type (level + 1, n, newbasename, m->type, FALSE, FALSE);
|
||||
free (n);
|
||||
} else
|
||||
define_type (level + 1, m->gen_name, m->type, FALSE, FALSE);
|
||||
define_type (level + 1, m->gen_name, newbasename, m->type, FALSE, FALSE);
|
||||
}
|
||||
space(level);
|
||||
fprintf (headerfile, "} %s;\n", name);
|
||||
@@ -667,15 +818,17 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
|
||||
Type i;
|
||||
struct range range = { 0, INT_MAX };
|
||||
|
||||
getnewbasename(&newbasename, typedefp, basename, name);
|
||||
|
||||
i.type = TInteger;
|
||||
i.range = ⦥
|
||||
i.members = NULL;
|
||||
i.constraint = NULL;
|
||||
|
||||
space(level);
|
||||
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
|
||||
define_type (level + 1, "len", &i, FALSE, FALSE);
|
||||
define_type (level + 1, "*val", t->subtype, FALSE, FALSE);
|
||||
fprintf (headerfile, "struct %s {\n", newbasename);
|
||||
define_type (level + 1, "len", newbasename, &i, FALSE, FALSE);
|
||||
define_type (level + 1, "*val", newbasename, t->subtype, FALSE, FALSE);
|
||||
space(level);
|
||||
fprintf (headerfile, "} %s;\n", name);
|
||||
break;
|
||||
@@ -693,14 +846,16 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
|
||||
fprintf (headerfile, "heim_general_string %s;\n", name);
|
||||
break;
|
||||
case TTag:
|
||||
define_type (level, name, t->subtype, typedefp, preservep);
|
||||
define_type (level, name, basename, t->subtype, typedefp, preservep);
|
||||
break;
|
||||
case TChoice: {
|
||||
int first = 1;
|
||||
Member *m;
|
||||
|
||||
getnewbasename(&newbasename, typedefp, basename, name);
|
||||
|
||||
space(level);
|
||||
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
|
||||
fprintf (headerfile, "struct %s {\n", newbasename);
|
||||
if (preservep) {
|
||||
space(level + 1);
|
||||
fprintf(headerfile, "heim_octet_string _save;\n");
|
||||
@@ -737,10 +892,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
|
||||
asprintf (&n, "*%s", m->gen_name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
define_type (level + 2, n, m->type, FALSE, FALSE);
|
||||
define_type (level + 2, n, newbasename, m->type, FALSE, FALSE);
|
||||
free (n);
|
||||
} else
|
||||
define_type (level + 2, m->gen_name, m->type, FALSE, FALSE);
|
||||
define_type (level + 2, m->gen_name, newbasename, m->type, FALSE, FALSE);
|
||||
}
|
||||
space(level + 1);
|
||||
fprintf (headerfile, "} u;\n");
|
||||
@@ -787,6 +942,8 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
if (newbasename)
|
||||
free(newbasename);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -800,27 +957,61 @@ generate_type_header (const Symbol *s)
|
||||
fprintf (headerfile, "\n*/\n\n");
|
||||
|
||||
fprintf (headerfile, "typedef ");
|
||||
define_type (0, s->gen_name, s->type, TRUE, preservep);
|
||||
define_type (0, s->gen_name, s->gen_name, s->type, TRUE, preservep);
|
||||
|
||||
fprintf (headerfile, "\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
generate_type (const Symbol *s)
|
||||
{
|
||||
FILE *h;
|
||||
|
||||
if (!one_code_file)
|
||||
generate_header_of_codefile(s->gen_name);
|
||||
|
||||
generate_type_header (s);
|
||||
generate_type_encode (s);
|
||||
generate_type_decode (s);
|
||||
generate_type_free (s);
|
||||
generate_type_length (s);
|
||||
generate_type_copy (s);
|
||||
|
||||
if (template_flag)
|
||||
generate_template(s);
|
||||
|
||||
if (template_flag == 0 || is_template_compat(s) == 0) {
|
||||
generate_type_encode (s);
|
||||
generate_type_decode (s);
|
||||
generate_type_free (s);
|
||||
generate_type_length (s);
|
||||
generate_type_copy (s);
|
||||
}
|
||||
generate_type_seq (s);
|
||||
generate_glue (s->type, s->gen_name);
|
||||
fprintf(headerfile, "\n\n");
|
||||
|
||||
/* generate prototypes */
|
||||
|
||||
if (is_export(s->name))
|
||||
h = headerfile;
|
||||
else
|
||||
h = privheaderfile;
|
||||
|
||||
fprintf (h,
|
||||
"int "
|
||||
"decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
fprintf (h,
|
||||
"int "
|
||||
"encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
fprintf (h,
|
||||
"size_t length_%s(const %s *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
fprintf (h,
|
||||
"int copy_%s (const %s *, %s *);\n",
|
||||
s->gen_name, s->gen_name, s->gen_name);
|
||||
fprintf (h,
|
||||
"void free_%s (%s *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
|
||||
fprintf(h, "\n\n");
|
||||
|
||||
if (!one_code_file) {
|
||||
fprintf(codefile, "\n\n");
|
||||
|
@@ -228,10 +228,6 @@ generate_type_copy (const Symbol *s)
|
||||
|
||||
used_fail = 0;
|
||||
|
||||
fprintf (headerfile,
|
||||
"int copy_%s (const %s *, %s *);\n",
|
||||
s->gen_name, s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"copy_%s(const %s *from, %s *to)\n"
|
||||
"{\n"
|
||||
|
@@ -56,33 +56,6 @@ decode_primitive (const char *typename, const char *name, const char *forwstr)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
is_primitive_type(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case TInteger:
|
||||
case TBoolean:
|
||||
case TOctetString:
|
||||
case TBitString:
|
||||
case TEnumerated:
|
||||
case TGeneralizedTime:
|
||||
case TGeneralString:
|
||||
case TTeletexString:
|
||||
case TOID:
|
||||
case TUTCTime:
|
||||
case TUTF8String:
|
||||
case TPrintableString:
|
||||
case TIA5String:
|
||||
case TBMPString:
|
||||
case TUniversalString:
|
||||
case TVisibleString:
|
||||
case TNull:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
find_tag (const Type *t,
|
||||
Der_class *cl, Der_type *ty, unsigned *tag)
|
||||
@@ -630,7 +603,7 @@ decode_type (const char *name, const Type *t, int optional,
|
||||
fprintf(codefile,
|
||||
"else {\n"
|
||||
"(%s)->u.%s.data = calloc(1, len);\n"
|
||||
"if ((%s)->u.%s.data == NULL && len != 0) {\n"
|
||||
"if ((%s)->u.%s.data == NULL) {\n"
|
||||
"e = ENOMEM; %s;\n"
|
||||
"}\n"
|
||||
"(%s)->u.%s.length = len;\n"
|
||||
@@ -694,11 +667,6 @@ generate_type_decode (const Symbol *s)
|
||||
{
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
fprintf (headerfile,
|
||||
"int "
|
||||
"decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"decode_%s(const unsigned char *p,"
|
||||
" size_t len, %s *data, size_t *size)\n"
|
||||
@@ -744,7 +712,7 @@ generate_type_decode (const Symbol *s)
|
||||
if (preserve)
|
||||
fprintf (codefile,
|
||||
"data->_save.data = calloc(1, ret);\n"
|
||||
"if (data->_save.data == NULL && ret != 0) { \n"
|
||||
"if (data->_save.data == NULL) { \n"
|
||||
"e = ENOMEM; goto fail; \n"
|
||||
"}\n"
|
||||
"data->_save.length = ret;\n"
|
||||
|
@@ -508,11 +508,6 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
|
||||
void
|
||||
generate_type_encode (const Symbol *s)
|
||||
{
|
||||
fprintf (headerfile,
|
||||
"int "
|
||||
"encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"encode_%s(unsigned char *p, size_t len,"
|
||||
" const %s *data, size_t *size)\n"
|
||||
|
@@ -180,18 +180,14 @@ free_type (const char *name, const Type *t, int preserve)
|
||||
void
|
||||
generate_type_free (const Symbol *s)
|
||||
{
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
fprintf (headerfile,
|
||||
"void free_%s (%s *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "void\n"
|
||||
"free_%s(%s *data)\n"
|
||||
"{\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
free_type ("data", s->type, preserve);
|
||||
fprintf (codefile, "}\n\n");
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
fprintf (codefile, "void\n"
|
||||
"free_%s(%s *data)\n"
|
||||
"{\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
free_type ("data", s->type, preserve);
|
||||
fprintf (codefile, "}\n\n");
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,8 @@
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -70,7 +72,8 @@ generate_int2 (const Type *t, const char *gen_name)
|
||||
fprintf (codefile,
|
||||
"%s int2%s(unsigned n)\n"
|
||||
"{\n"
|
||||
"\t%s flags;\n\n",
|
||||
"\t%s flags;\n\n"
|
||||
"\tmemset(&flags, 0, sizeof(flags));\n\n",
|
||||
gen_name, gen_name, gen_name);
|
||||
|
||||
if(t->members) {
|
||||
@@ -92,9 +95,17 @@ generate_units (const Type *t, const char *gen_name)
|
||||
{
|
||||
Member *m;
|
||||
|
||||
fprintf (headerfile,
|
||||
"const struct units * asn1_%s_units(void);",
|
||||
gen_name);
|
||||
if (template_flag) {
|
||||
fprintf (headerfile,
|
||||
"extern const struct units *asn1_%s_table_units;\n",
|
||||
gen_name);
|
||||
fprintf (headerfile, "#define asn1_%s_units() (asn1_%s_table_units)\n",
|
||||
gen_name, gen_name);
|
||||
} else {
|
||||
fprintf (headerfile,
|
||||
"const struct units * asn1_%s_units(void);",
|
||||
gen_name);
|
||||
}
|
||||
|
||||
fprintf (codefile,
|
||||
"static struct units %s_units[] = {\n",
|
||||
@@ -111,11 +122,16 @@ generate_units (const Type *t, const char *gen_name)
|
||||
"\t{NULL,\t0}\n"
|
||||
"};\n\n");
|
||||
|
||||
fprintf (codefile,
|
||||
"const struct units * asn1_%s_units(void){\n"
|
||||
"return %s_units;\n"
|
||||
"}\n\n",
|
||||
gen_name, gen_name);
|
||||
if (template_flag)
|
||||
fprintf (codefile,
|
||||
"const struct units * asn1_%s_table_units = %s_units;\n",
|
||||
gen_name, gen_name);
|
||||
else
|
||||
fprintf (codefile,
|
||||
"const struct units * asn1_%s_units(void){\n"
|
||||
"return %s_units;\n"
|
||||
"}\n\n",
|
||||
gen_name, gen_name);
|
||||
|
||||
|
||||
}
|
||||
|
@@ -43,6 +43,7 @@ length_primitive (const char *typename,
|
||||
fprintf (codefile, "%s += der_length_%s(%s);\n", variable, typename, name);
|
||||
}
|
||||
|
||||
/* XXX same as der_length_tag */
|
||||
static size_t
|
||||
length_tag(unsigned int tag)
|
||||
{
|
||||
@@ -269,10 +270,6 @@ length_type (const char *name, const Type *t,
|
||||
void
|
||||
generate_type_length (const Symbol *s)
|
||||
{
|
||||
fprintf (headerfile,
|
||||
"size_t length_%s(const %s *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"size_t\n"
|
||||
"length_%s(const %s *data)\n"
|
||||
|
@@ -52,6 +52,7 @@
|
||||
#include "symbol.h"
|
||||
#include "asn1-common.h"
|
||||
#include "der.h"
|
||||
#include "der-private.h"
|
||||
|
||||
void generate_type (const Symbol *);
|
||||
void generate_constant (const Symbol *);
|
||||
@@ -74,7 +75,10 @@ void init_generate (const char *, const char *);
|
||||
const char *get_filename (void);
|
||||
void close_generate(void);
|
||||
void add_import(const char *);
|
||||
void add_export(const char *);
|
||||
int is_export(const char *);
|
||||
int yyparse(void);
|
||||
int is_primitive_type(int);
|
||||
|
||||
int preserve_type(const char *);
|
||||
int seq_type(const char *);
|
||||
@@ -82,9 +86,14 @@ int seq_type(const char *);
|
||||
void generate_header_of_codefile(const char *);
|
||||
void close_codefile(void);
|
||||
|
||||
int is_template_compat (const Symbol *);
|
||||
void generate_template(const Symbol *);
|
||||
void gen_template_import(const Symbol *);
|
||||
|
||||
extern FILE *headerfile, *codefile, *logfile;
|
||||
|
||||
extern FILE *privheaderfile, *headerfile, *codefile, *logfile, *templatefile;
|
||||
extern int support_ber;
|
||||
extern int template_flag;
|
||||
extern int rfc1510_bitstring;
|
||||
extern int one_code_file;
|
||||
|
||||
|
894
lib/asn1/gen_template.c
Normal file
894
lib/asn1/gen_template.c
Normal file
@@ -0,0 +1,894 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. 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.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
|
||||
static const char *symbol_name(const char *, const Type *);
|
||||
static void generate_template_type(const char *, const char **, const char *, const char *, const char *,
|
||||
Type *, int, int, int);
|
||||
|
||||
static const char *
|
||||
ttype_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return t->symbol->gen_name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
integer_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
if (t->members)
|
||||
return "int"; /* XXX enum foo */
|
||||
else if (t->range == NULL)
|
||||
return "heim_integer";
|
||||
else if (t->range->min == INT_MIN && t->range->max == INT_MAX)
|
||||
return "int";
|
||||
else if (t->range->min == 0 && t->range->max == UINT_MAX)
|
||||
return "unsigned";
|
||||
else if (t->range->min == 0 && t->range->max == INT_MAX)
|
||||
return "unsigned";
|
||||
else
|
||||
abort();
|
||||
}
|
||||
|
||||
static const char *
|
||||
boolean_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "int";
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
octetstring_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "heim_octet_string";
|
||||
}
|
||||
|
||||
static const char *
|
||||
sequence_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return basename;
|
||||
}
|
||||
|
||||
static const char *
|
||||
time_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "time_t";
|
||||
}
|
||||
|
||||
static const char *
|
||||
tag_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return symbol_name(basename, t->subtype);
|
||||
}
|
||||
|
||||
static const char *
|
||||
generalstring_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "heim_general_string";
|
||||
}
|
||||
|
||||
static const char *
|
||||
printablestring_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "heim_printable_string";
|
||||
}
|
||||
|
||||
static const char *
|
||||
ia5string_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "heim_ia5_string";
|
||||
}
|
||||
|
||||
static const char *
|
||||
visiblestring_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "heim_visible_string";
|
||||
}
|
||||
|
||||
static const char *
|
||||
utf8string_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "heim_utf8_string";
|
||||
}
|
||||
|
||||
static const char *
|
||||
bmpstring_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "heim_bmp_string";
|
||||
}
|
||||
|
||||
static const char *
|
||||
universalstring_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "heim_universal_string";
|
||||
}
|
||||
|
||||
static const char *
|
||||
oid_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
return "heim_oid";
|
||||
}
|
||||
|
||||
static const char *
|
||||
bitstring_symbol(const char *basename, const Type *t)
|
||||
{
|
||||
if (t->members)
|
||||
return basename;
|
||||
return "heim_bit_string";
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct {
|
||||
enum typetype type;
|
||||
const char *(*symbol_name)(const char *, const Type *);
|
||||
int is_struct;
|
||||
} types[] = {
|
||||
{ TBMPString, bmpstring_symbol, 0 },
|
||||
{ TBitString, bitstring_symbol, 0 },
|
||||
{ TBoolean, boolean_symbol, 0 },
|
||||
{ TGeneralString, generalstring_symbol, 0 },
|
||||
{ TGeneralizedTime, time_symbol, 0 },
|
||||
{ TIA5String, ia5string_symbol, 0 },
|
||||
{ TInteger, integer_symbol, 0 },
|
||||
{ TOID, oid_symbol, 0 },
|
||||
{ TOctetString, octetstring_symbol, 0 },
|
||||
{ TPrintableString, printablestring_symbol, 0 },
|
||||
{ TSequence, sequence_symbol, 1 },
|
||||
{ TSequenceOf, tag_symbol, 1 },
|
||||
{ TSetOf, tag_symbol, 1 },
|
||||
{ TTag, tag_symbol, 1 },
|
||||
{ TType, ttype_symbol, 1 },
|
||||
{ TUTCTime, time_symbol, 0 },
|
||||
{ TUniversalString, universalstring_symbol, 0 },
|
||||
{ TVisibleString, visiblestring_symbol, 0 },
|
||||
{ TUTF8String, utf8string_symbol, 0 },
|
||||
{ TChoice, sequence_symbol, 1 },
|
||||
{ TNull, integer_symbol, 1 }
|
||||
};
|
||||
|
||||
static FILE *
|
||||
get_code_file(void)
|
||||
{
|
||||
if (!one_code_file)
|
||||
return templatefile;
|
||||
return codefile;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
is_supported_type_p(const Type *t)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(types)/sizeof(types[0]); i++)
|
||||
if (t->type == types[i].type)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
is_template_compat (const Symbol *s)
|
||||
{
|
||||
return is_supported_type_p(s->type);
|
||||
}
|
||||
|
||||
static const char *
|
||||
symbol_name(const char *basename, const Type *t)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(types)/sizeof(types[0]); i++)
|
||||
if (t->type == types[i].type)
|
||||
return (types[i].symbol_name)(basename, t);
|
||||
printf("unknown der type: %d\n", t->type);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
partial_offset(const char *basetype, const char *name, int need_offset)
|
||||
{
|
||||
char *str;
|
||||
if (name == NULL || need_offset == 0)
|
||||
return strdup("0");
|
||||
asprintf(&str, "offsetof(struct %s, %s)", basetype, name);
|
||||
return str;
|
||||
}
|
||||
|
||||
struct template {
|
||||
char *line;
|
||||
char *tt;
|
||||
char *offset;
|
||||
char *ptr;
|
||||
ASN1_TAILQ_ENTRY(template) members;
|
||||
};
|
||||
|
||||
ASN1_TAILQ_HEAD(templatehead, template);
|
||||
|
||||
struct tlist {
|
||||
char *name;
|
||||
char *header;
|
||||
struct templatehead template;
|
||||
ASN1_TAILQ_ENTRY(tlist) tmembers;
|
||||
};
|
||||
|
||||
ASN1_TAILQ_HEAD(tlisthead, tlist);
|
||||
|
||||
static void tlist_header(struct tlist *, const char *, ...) __attribute__((__format__(__printf__, 2, 3)));
|
||||
static struct template *
|
||||
add_line(struct templatehead *, const char *, ...) __attribute__((__format__(__printf__, 2, 3)));
|
||||
static int tlist_cmp(const struct tlist *, const struct tlist *);
|
||||
|
||||
static void add_line_pointer(struct templatehead *, const char *, const char *, const char *, ...)
|
||||
__attribute__((__format__(__printf__, 4, 5)));
|
||||
|
||||
|
||||
static struct tlisthead tlistmaster = ASN1_TAILQ_HEAD_INITIALIZER(tlistmaster);
|
||||
static unsigned long numdups = 0;
|
||||
|
||||
static struct tlist *
|
||||
tlist_new(const char *name)
|
||||
{
|
||||
struct tlist *tl = calloc(1, sizeof(*tl));
|
||||
tl->name = strdup(name);
|
||||
ASN1_TAILQ_INIT(&tl->template);
|
||||
return tl;
|
||||
}
|
||||
|
||||
static void
|
||||
tlist_header(struct tlist *t, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vasprintf(&t->header, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
tlist_count(struct tlist *tl)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
struct template *q;
|
||||
|
||||
ASN1_TAILQ_FOREACH(q, &tl->template, members) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
tlist_add(struct tlist *tl)
|
||||
{
|
||||
ASN1_TAILQ_INSERT_TAIL(&tlistmaster, tl, tmembers);
|
||||
}
|
||||
|
||||
static void
|
||||
tlist_print(struct tlist *tl)
|
||||
{
|
||||
struct template *q;
|
||||
unsigned int i = 1;
|
||||
FILE *f = get_code_file();
|
||||
|
||||
fprintf(f, "static const struct asn1_template asn1_%s[] = {\n", tl->name);
|
||||
fprintf(f, "/* 0 */ %s,\n", tl->header);
|
||||
ASN1_TAILQ_FOREACH(q, &tl->template, members) {
|
||||
int last = (ASN1_TAILQ_LAST(&tl->template, templatehead) == q);
|
||||
fprintf(f, "/* %lu */ %s%s\n", (unsigned long)i++, q->line, last ? "" : ",");
|
||||
}
|
||||
fprintf(f, "};\n");
|
||||
}
|
||||
|
||||
static struct tlist *
|
||||
tlist_find_by_name(const char *name)
|
||||
{
|
||||
struct tlist *ql;
|
||||
ASN1_TAILQ_FOREACH(ql, &tlistmaster, tmembers) {
|
||||
if (strcmp(ql->name, name) == 0)
|
||||
return ql;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
tlist_cmp_name(const char *tname, const char *qname)
|
||||
{
|
||||
struct tlist *tl = tlist_find_by_name(tname);
|
||||
struct tlist *ql = tlist_find_by_name(qname);
|
||||
return tlist_cmp(tl, ql);
|
||||
}
|
||||
|
||||
static int
|
||||
tlist_cmp(const struct tlist *tl, const struct tlist *ql)
|
||||
{
|
||||
int ret;
|
||||
struct template *t, *q;
|
||||
|
||||
ret = strcmp(tl->header, ql->header);
|
||||
if (ret) return ret;
|
||||
|
||||
q = ASN1_TAILQ_FIRST(&ql->template);
|
||||
ASN1_TAILQ_FOREACH(t, &tl->template, members) {
|
||||
if (q == NULL) return 1;
|
||||
|
||||
if (t->ptr == NULL || q->ptr == NULL) {
|
||||
ret = strcmp(t->line, q->line);
|
||||
if (ret) return ret;
|
||||
} else {
|
||||
ret = strcmp(t->tt, q->tt);
|
||||
if (ret) return ret;
|
||||
|
||||
ret = strcmp(t->offset, q->offset);
|
||||
if (ret) return ret;
|
||||
|
||||
if ((ret = strcmp(t->ptr, q->ptr)) != 0 ||
|
||||
(ret = tlist_cmp_name(t->ptr, q->ptr)) != 0)
|
||||
return ret;
|
||||
}
|
||||
q = ASN1_TAILQ_NEXT(q, members);
|
||||
}
|
||||
if (q != NULL) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
tlist_find_dup(const struct tlist *tl)
|
||||
{
|
||||
struct tlist *ql;
|
||||
|
||||
ASN1_TAILQ_FOREACH(ql, &tlistmaster, tmembers) {
|
||||
if (tlist_cmp(ql, tl) == 0) {
|
||||
numdups++;
|
||||
return ql->name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static struct template *
|
||||
add_line(struct templatehead *t, const char *fmt, ...)
|
||||
{
|
||||
struct template *q = calloc(1, sizeof(*q));
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vasprintf(&q->line, fmt, ap);
|
||||
va_end(ap);
|
||||
ASN1_TAILQ_INSERT_TAIL(t, q, members);
|
||||
return q;
|
||||
}
|
||||
|
||||
static void
|
||||
add_line_pointer(struct templatehead *t,
|
||||
const char *ptr,
|
||||
const char *offset,
|
||||
const char *ttfmt,
|
||||
...)
|
||||
{
|
||||
struct template *q;
|
||||
va_list ap;
|
||||
char *tt;
|
||||
|
||||
va_start(ap, ttfmt);
|
||||
vasprintf(&tt, ttfmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
q = add_line(t, "{ %s, %s, asn1_%s }", tt, offset, ptr);
|
||||
q->tt = tt;
|
||||
q->offset = strdup(offset);
|
||||
q->ptr = strdup(ptr);
|
||||
}
|
||||
|
||||
static int
|
||||
use_extern(const Symbol *s)
|
||||
{
|
||||
if (s->type == NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
is_struct(Type *t, int isstruct)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (t->type == TType)
|
||||
return 0;
|
||||
if (t->type == TSequence || t->type == TSet || t->type == TChoice)
|
||||
return 1;
|
||||
if (t->type == TTag)
|
||||
return is_struct(t->subtype, isstruct);
|
||||
|
||||
for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) {
|
||||
if (t->type == types[i].type) {
|
||||
if (types[i].is_struct == 0)
|
||||
return 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return isstruct;
|
||||
}
|
||||
|
||||
static const Type *
|
||||
compact_tag(const Type *t)
|
||||
{
|
||||
while (t->type == TTag)
|
||||
t = t->subtype;
|
||||
return t;
|
||||
}
|
||||
|
||||
static void
|
||||
template_members(struct templatehead *temp, const char *basetype, const char *name, const Type *t, int optional, int isstruct, int need_offset)
|
||||
{
|
||||
char *poffset = NULL;
|
||||
|
||||
if (optional && t->type != TTag && t->type != TType)
|
||||
errx(1, "%s...%s is optional and not a (TTag or TType)", basetype, name);
|
||||
|
||||
poffset = partial_offset(basetype, name, need_offset);
|
||||
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
if (use_extern(t->symbol)) {
|
||||
add_line(temp, "{ A1_OP_TYPE_EXTERN %s, %s, &asn1_extern_%s}",
|
||||
optional ? "|A1_FLAG_OPTIONAL" : "",
|
||||
poffset, t->symbol->gen_name);
|
||||
} else {
|
||||
add_line_pointer(temp, t->symbol->gen_name, poffset,
|
||||
"A1_OP_TYPE %s", optional ? "|A1_FLAG_OPTIONAL" : "");
|
||||
}
|
||||
break;
|
||||
case TInteger: {
|
||||
char *itype;
|
||||
|
||||
if (t->members)
|
||||
itype = "IMEMBER";
|
||||
else if (t->range == NULL)
|
||||
itype = "HEIM_INTEGER";
|
||||
else if (t->range->min == INT_MIN && t->range->max == INT_MAX)
|
||||
itype = "INTEGER";
|
||||
else if (t->range->min == 0 && t->range->max == UINT_MAX)
|
||||
itype = "UNSIGNED";
|
||||
else if (t->range->min == 0 && t->range->max == INT_MAX)
|
||||
itype = "UNSIGNED";
|
||||
else
|
||||
errx(1, "%s: unsupported range %d -> %d",
|
||||
name, t->range->min, t->range->max);
|
||||
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_%s), %s, NULL }", itype, poffset);
|
||||
break;
|
||||
}
|
||||
case TGeneralString:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_GENERAL_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
case TTeletexString:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_TELETEX_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
case TPrintableString:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_PRINTABLE_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
case TOctetString:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_OCTET_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
case TIA5String:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_IA5_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
case TBMPString:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_BMP_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
case TUniversalString:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_UNIVERSAL_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
case TVisibleString:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_VISIBLE_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
case TUTF8String:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_UTF8_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
case TGeneralizedTime:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_GENERALIZED_TIME), %s, NULL }", poffset);
|
||||
break;
|
||||
case TUTCTime:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_UTC_TIME), %s, NULL }", poffset);
|
||||
break;
|
||||
case TBoolean:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_BOOLEAN), %s, NULL }", poffset);
|
||||
break;
|
||||
case TOID:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_OID), %s, NULL }", poffset);
|
||||
break;
|
||||
case TNull:
|
||||
break;
|
||||
case TBitString: {
|
||||
struct templatehead template = ASN1_TAILQ_HEAD_INITIALIZER(template);
|
||||
struct template *q;
|
||||
Member *m;
|
||||
size_t count = 0, i;
|
||||
char *bname;
|
||||
FILE *f = get_code_file();
|
||||
|
||||
if (ASN1_TAILQ_EMPTY(t->members)) {
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_HEIM_BIT_STRING), %s, NULL }", poffset);
|
||||
break;
|
||||
}
|
||||
|
||||
asprintf(&bname, "bmember_%s_%lu", name ? name : "", (unsigned long)t);
|
||||
output_name(bname);
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
add_line(&template, "{ 0, %d, 0 } /* %s */", m->val, m->gen_name);
|
||||
}
|
||||
|
||||
ASN1_TAILQ_FOREACH(q, &template, members) {
|
||||
count++;
|
||||
}
|
||||
|
||||
fprintf(f, "static const struct asn1_template asn1_%s_%s[] = {\n", basetype, bname);
|
||||
fprintf(f, "/* 0 */ { 0%s, sizeof(%s), ((void *)%lu) },\n",
|
||||
rfc1510_bitstring ? "|A1_HBF_RFC1510" : "",
|
||||
basetype, (unsigned long)count);
|
||||
i = 1;
|
||||
ASN1_TAILQ_FOREACH(q, &template, members) {
|
||||
int last = (ASN1_TAILQ_LAST(&template, templatehead) == q);
|
||||
fprintf(f, "/* %lu */ %s%s\n", (unsigned long)i++, q->line, last ? "" : ",");
|
||||
}
|
||||
fprintf(f, "};\n");
|
||||
|
||||
add_line(temp, "{ A1_OP_BMEMBER, %s, asn1_%s_%s }", poffset, basetype, bname);
|
||||
|
||||
free(bname);
|
||||
|
||||
break;
|
||||
}
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *newbasename;
|
||||
|
||||
if (m->ellipsis)
|
||||
continue;
|
||||
|
||||
if (name)
|
||||
asprintf(&newbasename, "%s_%s", basetype, name);
|
||||
else
|
||||
newbasename = strdup(basetype);
|
||||
|
||||
template_members(temp, newbasename, m->gen_name, m->type, m->optional, isstruct, 1);
|
||||
|
||||
free(newbasename);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TTag: {
|
||||
char *tname, *elname;
|
||||
const char *sename, *dupname;
|
||||
int subtype_is_struct = is_struct(t->subtype, isstruct);
|
||||
|
||||
if (subtype_is_struct)
|
||||
sename = basetype;
|
||||
else
|
||||
sename = symbol_name(basetype, t->subtype);
|
||||
|
||||
asprintf(&tname, "tag_%s_%lu", name ? name : "", (unsigned long)t);
|
||||
output_name(tname);
|
||||
|
||||
asprintf(&elname, "%s_%s", basetype, tname);
|
||||
|
||||
generate_template_type(elname, &dupname, NULL, sename, name,
|
||||
t->subtype, 0, subtype_is_struct, 0);
|
||||
|
||||
add_line_pointer(temp, dupname, poffset,
|
||||
"A1_TAG_T(%s,%s,%s)%s",
|
||||
classname(t->tag.tagclass),
|
||||
is_primitive_type(t->subtype->type) ? "PRIM" : "CONS",
|
||||
valuename(t->tag.tagclass, t->tag.tagvalue),
|
||||
optional ? "|A1_FLAG_OPTIONAL" : "");
|
||||
|
||||
free(tname);
|
||||
free(elname);
|
||||
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
const char *type, *tname, *dupname;
|
||||
char *sename, *elname;
|
||||
int subtype_is_struct = is_struct(t->subtype, 0);
|
||||
|
||||
if (name && subtype_is_struct) {
|
||||
tname = "seofTstruct";
|
||||
asprintf(&sename, "%s_%s_val",
|
||||
basetype, name);
|
||||
} else if (subtype_is_struct) {
|
||||
tname = "seofTstruct";
|
||||
asprintf(&sename, "%s_val", symbol_name(basetype, t->subtype));
|
||||
} else {
|
||||
if (name)
|
||||
tname = name;
|
||||
else
|
||||
tname = "seofTstruct";
|
||||
sename = strdup(symbol_name(basetype, t->subtype));
|
||||
}
|
||||
|
||||
if (t->type == TSetOf) type = "A1_OP_SETOF";
|
||||
else if (t->type == TSequenceOf) type = "A1_OP_SEQOF";
|
||||
else abort();
|
||||
|
||||
asprintf(&elname, "%s_%s_%lu", basetype, tname, (unsigned long)t);
|
||||
|
||||
generate_template_type(elname, &dupname, NULL, sename, NULL, t->subtype,
|
||||
0, subtype_is_struct, need_offset);
|
||||
|
||||
add_line(temp, "{ %s, %s, asn1_%s }", type, poffset, dupname);
|
||||
free(sename);
|
||||
break;
|
||||
}
|
||||
case TChoice: {
|
||||
struct templatehead template = ASN1_TAILQ_HEAD_INITIALIZER(template);
|
||||
struct template *q;
|
||||
size_t count = 0, i;
|
||||
char *tname;
|
||||
FILE *f = get_code_file();
|
||||
Member *m;
|
||||
int ellipsis = 0;
|
||||
char *e;
|
||||
|
||||
asprintf(&tname, "asn1_choice_%s_%s%x",
|
||||
basetype, name ? name : "", (unsigned int)(uintptr_t)t);
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
const char *dupname;
|
||||
char *elname;
|
||||
char *newbasename;
|
||||
int subtype_is_struct;
|
||||
|
||||
if (m->ellipsis) {
|
||||
ellipsis = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
subtype_is_struct = is_struct(m->type, 0);
|
||||
|
||||
asprintf(&elname, "%s_choice_%s", basetype, m->gen_name);
|
||||
|
||||
if (subtype_is_struct)
|
||||
asprintf(&newbasename, "%s_%s", basetype, m->gen_name);
|
||||
else
|
||||
newbasename = strdup(basetype);
|
||||
|
||||
generate_template_type(elname, &dupname, NULL,
|
||||
symbol_name(newbasename, m->type),
|
||||
NULL, m->type, 0, subtype_is_struct, 1);
|
||||
|
||||
add_line(&template, "{ %s, offsetof(%s%s, u.%s), asn1_%s }",
|
||||
m->label, isstruct ? "struct " : "",
|
||||
basetype, m->gen_name,
|
||||
dupname);
|
||||
|
||||
free(elname);
|
||||
free(newbasename);
|
||||
}
|
||||
|
||||
if (ellipsis) {
|
||||
asprintf(&e, "offsetof(%s%s, u.asn1_ellipsis)", isstruct ? "struct " : "", basetype);
|
||||
} else
|
||||
e = NULL;
|
||||
|
||||
ASN1_TAILQ_FOREACH(q, &template, members) {
|
||||
count++;
|
||||
}
|
||||
|
||||
fprintf(f, "static const struct asn1_template %s[] = {\n", tname);
|
||||
fprintf(f, "/* 0 */ { %s, offsetof(%s%s, element), ((void *)%lu) },\n",
|
||||
e ? e : "0", isstruct ? "struct " : "", basetype, (unsigned long)count);
|
||||
i = 1;
|
||||
ASN1_TAILQ_FOREACH(q, &template, members) {
|
||||
int last = (ASN1_TAILQ_LAST(&template, templatehead) == q);
|
||||
fprintf(f, "/* %lu */ %s%s\n", (unsigned long)i++, q->line, last ? "" : ",");
|
||||
}
|
||||
fprintf(f, "};\n");
|
||||
|
||||
add_line(temp, "{ A1_OP_CHOICE, %s, %s }", poffset, tname);
|
||||
|
||||
free(e);
|
||||
free(tname);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
if (poffset)
|
||||
free(poffset);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_extern_stubs(FILE *f, const char *name)
|
||||
{
|
||||
fprintf(f,
|
||||
"static const struct asn1_type_func asn1_extern_%s = {\n"
|
||||
"\t(asn1_type_encode)encode_%s,\n"
|
||||
"\t(asn1_type_decode)decode_%s,\n"
|
||||
"\t(asn1_type_length)length_%s,\n"
|
||||
"\t(asn1_type_copy)copy_%s,\n"
|
||||
"\t(asn1_type_release)free_%s,\n"
|
||||
"\tsizeof(%s)\n"
|
||||
"};\n",
|
||||
name, name, name, name,
|
||||
name, name, name);
|
||||
}
|
||||
|
||||
void
|
||||
gen_template_import(const Symbol *s)
|
||||
{
|
||||
FILE *f = get_code_file();
|
||||
|
||||
if (template_flag == 0)
|
||||
return;
|
||||
|
||||
gen_extern_stubs(f, s->gen_name);
|
||||
}
|
||||
|
||||
static void
|
||||
generate_template_type(const char *varname,
|
||||
const char **dupname,
|
||||
const char *symname,
|
||||
const char *basetype,
|
||||
const char *name,
|
||||
Type *type,
|
||||
int optional, int isstruct, int need_offset)
|
||||
{
|
||||
struct tlist *tl;
|
||||
const char *dup;
|
||||
int have_ellipsis = 0;
|
||||
|
||||
tl = tlist_new(varname);
|
||||
|
||||
template_members(&tl->template, basetype, name, type, optional, isstruct, need_offset);
|
||||
|
||||
/* if its a sequence or set type, check if there is a ellipsis */
|
||||
if (type->type == TSequence || type->type == TSet) {
|
||||
Member *m;
|
||||
ASN1_TAILQ_FOREACH(m, type->members, members) {
|
||||
if (m->ellipsis)
|
||||
have_ellipsis = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ASN1_TAILQ_EMPTY(&tl->template) && compact_tag(type)->type != TNull)
|
||||
errx(1, "Tag %s...%s with no content ?", basetype, name ? name : "");
|
||||
|
||||
tlist_header(tl, "{ 0%s%s, sizeof(%s%s), ((void *)%lu) }",
|
||||
(symname && preserve_type(symname)) ? "|A1_HF_PRESERVE" : "",
|
||||
have_ellipsis ? "|A1_HF_ELLIPSIS" : "",
|
||||
isstruct ? "struct " : "", basetype, tlist_count(tl));
|
||||
|
||||
dup = tlist_find_dup(tl);
|
||||
if (dup) {
|
||||
if (strcmp(dup, tl->name) == 0)
|
||||
errx(1, "found dup of ourself");
|
||||
*dupname = dup;
|
||||
} else {
|
||||
*dupname = tl->name;
|
||||
tlist_print(tl);
|
||||
tlist_add(tl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
generate_template(const Symbol *s)
|
||||
{
|
||||
FILE *f = get_code_file();
|
||||
const char *dupname;
|
||||
|
||||
if (use_extern(s)) {
|
||||
gen_extern_stubs(f, s->gen_name);
|
||||
return;
|
||||
}
|
||||
|
||||
generate_template_type(s->gen_name, &dupname, s->name, s->gen_name, NULL, s->type, 0, 0, 1);
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"int\n"
|
||||
"decode_%s(const unsigned char *p, size_t len, %s *data, size_t *size)\n"
|
||||
"{\n"
|
||||
" return _asn1_decode_top(asn1_%s, 0|%s, p, len, data, size);\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
s->gen_name,
|
||||
s->gen_name,
|
||||
dupname,
|
||||
support_ber ? "A1_PF_ALLOW_BER" : "0");
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"int\n"
|
||||
"encode_%s(unsigned char *p, size_t len, const %s *data, size_t *size)\n"
|
||||
"{\n"
|
||||
" return _asn1_encode(asn1_%s, p, len, data, size);\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
s->gen_name,
|
||||
s->gen_name,
|
||||
dupname);
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"size_t\n"
|
||||
"length_%s(const %s *data)\n"
|
||||
"{\n"
|
||||
" return _asn1_length(asn1_%s, data);\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
s->gen_name,
|
||||
s->gen_name,
|
||||
dupname);
|
||||
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"void\n"
|
||||
"free_%s(%s *data)\n"
|
||||
"{\n"
|
||||
" _asn1_free(asn1_%s, data);\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
s->gen_name,
|
||||
s->gen_name,
|
||||
dupname);
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"int\n"
|
||||
"copy_%s(const %s *from, %s *to)\n"
|
||||
"{\n"
|
||||
" return _asn1_copy_top(asn1_%s, from, to);\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
s->gen_name,
|
||||
s->gen_name,
|
||||
s->gen_name,
|
||||
dupname);
|
||||
}
|
@@ -2,6 +2,78 @@
|
||||
|
||||
KERBEROS5 DEFINITIONS ::=
|
||||
BEGIN
|
||||
EXPORTS
|
||||
AD-AND-OR,
|
||||
AD-IF-RELEVANT,
|
||||
AD-KDCIssued,
|
||||
AD-LoginAlias,
|
||||
AP-REP,
|
||||
AP-REQ,
|
||||
AS-REP,
|
||||
AS-REQ,
|
||||
AUTHDATA-TYPE,
|
||||
Authenticator,
|
||||
AuthorizationData,
|
||||
AuthorizationDataElement,
|
||||
CKSUMTYPE,
|
||||
ChangePasswdDataMS,
|
||||
Checksum,
|
||||
ENCTYPE,
|
||||
ETYPE-INFO,
|
||||
ETYPE-INFO-ENTRY,
|
||||
ETYPE-INFO2,
|
||||
ETYPE-INFO2-ENTRY,
|
||||
EncAPRepPart,
|
||||
EncASRepPart,
|
||||
EncKDCRepPart,
|
||||
EncKrbCredPart,
|
||||
EncKrbPrivPart,
|
||||
EncTGSRepPart,
|
||||
EncTicketPart,
|
||||
EncryptedData,
|
||||
EncryptionKey,
|
||||
EtypeList,
|
||||
HostAddress,
|
||||
HostAddresses,
|
||||
KDC-REQ-BODY,
|
||||
KDCOptions,
|
||||
KDC-REP,
|
||||
KRB-CRED,
|
||||
KRB-ERROR,
|
||||
KRB-PRIV,
|
||||
KRB-SAFE,
|
||||
KRB-SAFE-BODY,
|
||||
KRB5SignedPath,
|
||||
KRB5SignedPathData,
|
||||
KRB5SignedPathPrincipals,
|
||||
KerberosString,
|
||||
KerberosTime,
|
||||
KrbCredInfo,
|
||||
LR-TYPE,
|
||||
LastReq,
|
||||
METHOD-DATA,
|
||||
NAME-TYPE,
|
||||
PA-ClientCanonicalized,
|
||||
PA-ClientCanonicalizedNames,
|
||||
PA-DATA,
|
||||
PA-ENC-TS-ENC,
|
||||
PA-PAC-REQUEST,
|
||||
PA-S4U2Self,
|
||||
PA-SERVER-REFERRAL-DATA,
|
||||
PA-ServerReferralData,
|
||||
PA-SvrReferralData,
|
||||
PADATA-TYPE,
|
||||
Principal,
|
||||
PrincipalName,
|
||||
Principals,
|
||||
Realm,
|
||||
TGS-REP,
|
||||
TGS-REQ,
|
||||
Ticket,
|
||||
TicketFlags,
|
||||
TransitedEncoding,
|
||||
TypedData
|
||||
;
|
||||
|
||||
NAME-TYPE ::= INTEGER {
|
||||
KRB5_NT_UNKNOWN(0), -- Name type not known
|
||||
@@ -256,11 +328,7 @@ KDCOptions ::= BIT STRING {
|
||||
proxy(4),
|
||||
allow-postdate(5),
|
||||
postdated(6),
|
||||
unused7(7),
|
||||
renewable(8),
|
||||
unused9(9),
|
||||
unused10(10),
|
||||
unused11(11),
|
||||
request-anonymous(14),
|
||||
canonicalize(15),
|
||||
constrained-delegation(16), -- ms extension
|
||||
|
@@ -63,12 +63,14 @@ seq_type(const char *p)
|
||||
}
|
||||
|
||||
int support_ber;
|
||||
int template_flag;
|
||||
int rfc1510_bitstring;
|
||||
int one_code_file;
|
||||
char *option_file;
|
||||
int version_flag;
|
||||
int help_flag;
|
||||
struct getargs args[] = {
|
||||
{ "template", 0, arg_flag, &template_flag },
|
||||
{ "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
|
||||
{ "decode-dce-ber", 0, arg_flag, &support_ber },
|
||||
{ "support-ber", 0, arg_flag, &support_ber },
|
||||
|
6
lib/asn1/rfc2459.opt
Normal file
6
lib/asn1/rfc2459.opt
Normal file
@@ -0,0 +1,6 @@
|
||||
--preserve-binary=TBSCertificate
|
||||
--preserve-binary=TBSCRLCertList
|
||||
--preserve-binary=Name
|
||||
--sequence=GeneralNames
|
||||
--sequence=Extensions
|
||||
--sequence=CRLDistributionPoints
|
@@ -34,8 +34,6 @@
|
||||
#include "gen_locl.h"
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
static Hashtab *htab;
|
||||
|
||||
static int
|
||||
@@ -68,7 +66,7 @@ output_name(char *s)
|
||||
char *p;
|
||||
|
||||
for (p = s; *p; ++p)
|
||||
if (*p == '-')
|
||||
if (*p == '-' || *p == '.')
|
||||
*p = '_';
|
||||
}
|
||||
|
||||
|
1119
lib/asn1/template.c
Normal file
1119
lib/asn1/template.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,11 @@ BEGIN
|
||||
|
||||
IMPORTS heim_any FROM heim;
|
||||
|
||||
TESTuint32 ::= INTEGER (0..4294967295)
|
||||
|
||||
TESTLargeTag ::= SEQUENCE {
|
||||
foo[127] INTEGER (-2147483648..2147483647)
|
||||
foo[127] INTEGER (-2147483648..2147483647),
|
||||
bar[128] INTEGER (-2147483648..2147483647)
|
||||
}
|
||||
|
||||
TESTSeq ::= SEQUENCE {
|
||||
@@ -57,6 +60,11 @@ TESTAlloc ::= SEQUENCE {
|
||||
tagless2 heim_any OPTIONAL
|
||||
}
|
||||
|
||||
TESTOptional ::= SEQUENCE {
|
||||
zero [0] INTEGER (-2147483648..2147483647) OPTIONAL,
|
||||
one [1] INTEGER (-2147483648..2147483647) OPTIONAL
|
||||
}
|
||||
|
||||
|
||||
TESTCONTAINING ::= OCTET STRING ( CONTAINING INTEGER )
|
||||
TESTENCODEDBY ::= OCTET STRING ( ENCODED BY
|
||||
@@ -92,4 +100,36 @@ TESTSeqSizeOf4 ::= SEQUENCE SIZE (MIN..2) OF TESTInteger
|
||||
|
||||
TESTOSSize1 ::= OCTET STRING SIZE (1..2)
|
||||
|
||||
TESTSeqOfSeq ::= SEQUENCE OF SEQUENCE {
|
||||
zero [0] TESTInteger
|
||||
}
|
||||
|
||||
TESTSeqOfSeq2 ::= SEQUENCE OF SEQUENCE {
|
||||
string [0] GeneralString
|
||||
}
|
||||
|
||||
TESTSeqOfSeq3 ::= SEQUENCE OF SEQUENCE {
|
||||
zero [0] TESTInteger,
|
||||
string [0] GeneralString
|
||||
}
|
||||
|
||||
TESTSeqOf2 ::= SEQUENCE {
|
||||
strings SEQUENCE OF GeneralString
|
||||
}
|
||||
|
||||
TESTSeqOf3 ::= SEQUENCE {
|
||||
strings SEQUENCE OF GeneralString OPTIONAL
|
||||
}
|
||||
|
||||
TESTPreserve ::= SEQUENCE {
|
||||
zero [0] TESTInteger,
|
||||
one [1] TESTInteger
|
||||
}
|
||||
|
||||
TESTBitString ::= BIT STRING {
|
||||
zero(0),
|
||||
eight(8),
|
||||
thirtyone(31)
|
||||
}
|
||||
|
||||
END
|
||||
|
Reference in New Issue
Block a user