first stange of asn1 table driven compiler

This commit is contained in:
Love Hornquist Astrand
2009-11-21 10:24:56 -08:00
parent ae56d6eede
commit b939943b07
35 changed files with 3572 additions and 240 deletions

View File

@@ -7,34 +7,44 @@ YFLAGS = -d -t
lib_LTLIBRARIES = libasn1.la lib_LTLIBRARIES = libasn1.la
libasn1_la_LDFLAGS = -version-info 8:0:0 libasn1_la_LDFLAGS = -version-info 8:0:0
noinst_LTLIBRARIES = libasn1base.la
if versionscript if versionscript
libasn1_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map libasn1_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map
endif endif
libasn1_la_LIBADD = \ libasn1_la_LIBADD = \
libasn1base.la \
@LIB_com_err@ \ @LIB_com_err@ \
$(LIBADD_roken) $(LIBADD_roken)
BUILT_SOURCES = \ BUILT_SOURCES = \
$(gen_files_rfc2459:.x=.c) \ $(gen_files_rfc2459:.x=.c) \
rfc2459_asn1-template.c \
$(gen_files_cms:.x=.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) \ $(gen_files_pkinit:.x=.c) \
pkinit_asn1-template.c \
$(gen_files_pkcs8:.x=.c) \ $(gen_files_pkcs8:.x=.c) \
pkcs8_asn1-template.c \
$(gen_files_pkcs9:.x=.c) \ $(gen_files_pkcs9:.x=.c) \
pkcs9_asn1-template.c \
$(gen_files_pkcs12:.x=.c) \ $(gen_files_pkcs12:.x=.c) \
pkcs12_asn1-template.c \
$(gen_files_digest:.x=.c) \ $(gen_files_digest:.x=.c) \
digest_asn1-template.c \
$(gen_files_kx509:.x=.c) \ $(gen_files_kx509:.x=.c) \
asn1_err.h \ kx509_asn1-template.c
asn1_err.c
gen_files_k5 = \ gen_files_krb5 = \
asn1_AD_AND_OR.x \ asn1_AD_AND_OR.x \
asn1_AD_IF_RELEVANT.x \ asn1_AD_IF_RELEVANT.x \
asn1_AD_KDCIssued.x \ asn1_AD_KDCIssued.x \
asn1_AD_MANDATORY_FOR_KDC.x \
asn1_AD_LoginAlias.x \ asn1_AD_LoginAlias.x \
asn1_AD_MANDATORY_FOR_KDC.x \
asn1_APOptions.x \ asn1_APOptions.x \
asn1_AP_REP.x \ asn1_AP_REP.x \
asn1_AP_REQ.x \ asn1_AP_REQ.x \
@@ -62,12 +72,15 @@ gen_files_k5 = \
asn1_EncryptedData.x \ asn1_EncryptedData.x \
asn1_EncryptionKey.x \ asn1_EncryptionKey.x \
asn1_EtypeList.x \ asn1_EtypeList.x \
asn1_FastOptions.x \
asn1_HostAddress.x \ asn1_HostAddress.x \
asn1_HostAddresses.x \ asn1_HostAddresses.x \
asn1_KDCOptions.x \ asn1_KDCOptions.x \
asn1_KDC_REP.x \ asn1_KDC_REP.x \
asn1_KDC_REQ.x \ asn1_KDC_REQ.x \
asn1_KDC_REQ_BODY.x \ asn1_KDC_REQ_BODY.x \
asn1_KRB5SignedPath.x \
asn1_KRB5SignedPathData.x \
asn1_KRB_CRED.x \ asn1_KRB_CRED.x \
asn1_KRB_ERROR.x \ asn1_KRB_ERROR.x \
asn1_KRB_PRIV.x \ asn1_KRB_PRIV.x \
@@ -76,12 +89,22 @@ gen_files_k5 = \
asn1_KerberosString.x \ asn1_KerberosString.x \
asn1_KerberosTime.x \ asn1_KerberosTime.x \
asn1_KrbCredInfo.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_LR_TYPE.x \
asn1_LastReq.x \ asn1_LastReq.x \
asn1_MESSAGE_TYPE.x \ asn1_MESSAGE_TYPE.x \
asn1_METHOD_DATA.x \ asn1_METHOD_DATA.x \
asn1_NAME_TYPE.x \ asn1_NAME_TYPE.x \
asn1_PA_FX_FAST_REPLY.x \
asn1_PA_FX_FAST_REQUEST.x \
asn1_PADATA_TYPE.x \ asn1_PADATA_TYPE.x \
asn1_PA_ClientCanonicalized.x \
asn1_PA_ClientCanonicalizedNames.x \
asn1_PA_DATA.x \ asn1_PA_DATA.x \
asn1_PA_ENC_SAM_RESPONSE_ENC.x \ asn1_PA_ENC_SAM_RESPONSE_ENC.x \
asn1_PA_ENC_TS_ENC.x \ asn1_PA_ENC_TS_ENC.x \
@@ -92,11 +115,9 @@ gen_files_k5 = \
asn1_PA_SAM_REDIRECT.x \ asn1_PA_SAM_REDIRECT.x \
asn1_PA_SAM_RESPONSE_2.x \ asn1_PA_SAM_RESPONSE_2.x \
asn1_PA_SAM_TYPE.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_SERVER_REFERRAL_DATA.x \
asn1_PA_ServerReferralData.x \
asn1_PA_SvrReferralData.x \
asn1_PROV_SRV_LOCATION.x \ asn1_PROV_SRV_LOCATION.x \
asn1_Principal.x \ asn1_Principal.x \
asn1_PrincipalName.x \ asn1_PrincipalName.x \
@@ -111,18 +132,7 @@ gen_files_k5 = \
asn1_TransitedEncoding.x \ asn1_TransitedEncoding.x \
asn1_TypedData.x \ asn1_TypedData.x \
asn1_krb5int32.x \ asn1_krb5int32.x \
asn1_krb5uint32.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
gen_files_cms = \ gen_files_cms = \
asn1_CMSAttributes.x \ asn1_CMSAttributes.x \
@@ -430,8 +440,10 @@ gen_files_pkcs9 = \
asn1_PKCS9_friendlyName.x asn1_PKCS9_friendlyName.x
gen_files_test = \ gen_files_test = \
asn1_TESTOptional.x \
asn1_TESTAlloc.x \ asn1_TESTAlloc.x \
asn1_TESTAllocInner.x \ asn1_TESTAllocInner.x \
asn1_TESTBitString.x \
asn1_TESTCONTAINING.x \ asn1_TESTCONTAINING.x \
asn1_TESTCONTAININGENCODEDBY.x \ asn1_TESTCONTAININGENCODEDBY.x \
asn1_TESTCONTAININGENCODEDBY2.x \ asn1_TESTCONTAININGENCODEDBY2.x \
@@ -445,14 +457,21 @@ gen_files_test = \
asn1_TESTInteger2.x \ asn1_TESTInteger2.x \
asn1_TESTInteger3.x \ asn1_TESTInteger3.x \
asn1_TESTLargeTag.x \ asn1_TESTLargeTag.x \
asn1_TESTSeq.x \
asn1_TESTUSERCONSTRAINED.x \
asn1_TESTSeqOf.x \
asn1_TESTOSSize1.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_TESTSeqSizeOf1.x \
asn1_TESTSeqSizeOf2.x \ asn1_TESTSeqSizeOf2.x \
asn1_TESTSeqSizeOf3.x \ asn1_TESTSeqSizeOf3.x \
asn1_TESTSeqSizeOf4.x asn1_TESTSeqSizeOf4.x \
asn1_TESTUSERCONSTRAINED.x \
asn1_TESTuint32.x
gen_files_digest = \ gen_files_digest = \
asn1_DigestError.x \ asn1_DigestError.x \
@@ -479,15 +498,20 @@ noinst_PROGRAMS = asn1_gen
libexec_heimdal_PROGRAMS = asn1_compile asn1_print 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) check_PROGRAMS = $(TESTS)
asn1_gen_SOURCES = asn1_gen.c asn1_gen_SOURCES = asn1_gen.c
asn1_print_SOURCES = asn1_print.c asn1_print_SOURCES = asn1_print.c
check_der_SOURCES = check-der.c check-common.c check-common.h 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 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_compile_SOURCES = \
asn1-common.h \ asn1-common.h \
@@ -503,16 +527,17 @@ asn1_compile_SOURCES = \
gen_length.c \ gen_length.c \
gen_locl.h \ gen_locl.h \
gen_seq.c \ gen_seq.c \
gen_template.c \
hash.c \ hash.c \
hash.h \ hash.h \
lex.l \ lex.l \
lex.h \ lex.h \
main.c \ main.c \
asn1-template.h \
symbol.c \ symbol.c \
symbol.h symbol.h
dist_libasn1_la_SOURCES = \ dist_libasn1base_la_SOURCES = \
der-protos.h \
der_locl.h \ der_locl.h \
der.c \ der.c \
der.h \ der.h \
@@ -525,28 +550,38 @@ dist_libasn1_la_SOURCES = \
der_format.c \ der_format.c \
heim_asn1.h \ heim_asn1.h \
extra.c \ extra.c \
template.c \
timegm.c timegm.c
nodist_libasn1base_la_SOURCES = \
asn1_err.h \
asn1_err.c
nodist_libasn1_la_SOURCES = $(BUILT_SOURCES) nodist_libasn1_la_SOURCES = $(BUILT_SOURCES)
asn1_compile_LDADD = \ asn1_compile_LDADD = \
$(LIB_roken) $(LEXLIB) $(LIB_roken) $(LEXLIB)
check_der_LDADD = \ 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 \ libasn1.la \
$(LIB_roken) $(LIB_roken)
check_gen_LDADD = $(check_der_LDADD) check_ber_LDADD = $(check_gen_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)
CLEANFILES = \ CLEANFILES = \
$(BUILT_SOURCES) \ $(BUILT_SOURCES) \
$(gen_files_rfc2459) \ $(gen_files_rfc2459) \
$(gen_files_cms) \ $(gen_files_cms) \
$(gen_files_k5) \ $(gen_files_krb5) \
$(gen_files_pkinit) \ $(gen_files_pkinit) \
$(gen_files_pkcs8) \ $(gen_files_pkcs8) \
$(gen_files_pkcs9) \ $(gen_files_pkcs9) \
@@ -554,6 +589,7 @@ CLEANFILES = \
$(gen_files_digest) \ $(gen_files_digest) \
$(gen_files_kx509) \ $(gen_files_kx509) \
$(gen_files_test) $(nodist_check_gen_SOURCES) \ $(gen_files_test) $(nodist_check_gen_SOURCES) \
test_asn1-template.c \
rfc2459_asn1_files rfc2459_asn1.h* \ rfc2459_asn1_files rfc2459_asn1.h* \
cms_asn1_files cms_asn1.h* \ cms_asn1_files cms_asn1.h* \
krb5_asn1_files krb5_asn1.h* \ krb5_asn1_files krb5_asn1.h* \
@@ -565,7 +601,7 @@ CLEANFILES = \
kx509_asn1_files kx509_asn1.h* \ kx509_asn1_files kx509_asn1.h* \
test_asn1_files test_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 = asn1_err.h
nodist_include_HEADERS += krb5_asn1.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 += digest_asn1.h
nodist_include_HEADERS += kx509_asn1.h nodist_include_HEADERS += kx509_asn1.h
$(asn1_compile_OBJECTS): asn1parse.h asn1parse.c $(srcdir)/der-protos.h priv_headers = krb5_asn1-priv.h
$(libasn1_la_OBJECTS): $(nodist_include_HEADERS) $(srcdir)/der-protos.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_gen_OBJECTS): test_asn1.h
$(check_template_OBJECTS): test_asn1_files
$(asn1_print_OBJECTS): krb5_asn1.h $(asn1_print_OBJECTS): krb5_asn1.h
asn1parse.h: asn1parse.c 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_pkinit) pkinit_asn1.hx: pkinit_asn1_files
$(gen_files_pkcs8) pkcs8_asn1.hx: pkcs8_asn1_files $(gen_files_pkcs8) pkcs8_asn1.hx: pkcs8_asn1_files
$(gen_files_pkcs9) pkcs9_asn1.hx: pkcs9_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 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) $(ASN1_COMPILE) --sequence=TESTSeqOf $(srcdir)/test.asn1 test_asn1 || (rm -f test_asn1_files ; exit 1)
EXTRA_DIST = \ EXTRA_DIST = \
cms.asn1 \ cms.asn1 \
cms.opt \ cms.opt \
@@ -646,4 +697,7 @@ EXTRA_DIST = \
version-script.map version-script.map
$(srcdir)/der-protos.h: $(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
View 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
View 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

View File

@@ -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 EXACT_CONSTRAINT, "ASN.1 wrong number of elements"
error_code INDEF_OVERRUN, "ASN.1 BER indefinte encoding overrun" error_code INDEF_OVERRUN, "ASN.1 BER indefinte encoding overrun"
error_code INDEF_UNDERRUN, "ASN.1 BER indefinte encoding underun" 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 end

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -182,7 +184,9 @@ loop (unsigned char *buf, size_t len, int indent)
case UT_GeneralizedTime : case UT_GeneralizedTime :
case UT_GeneralString : case UT_GeneralString :
case UT_PrintableString : case UT_PrintableString :
case UT_VisibleString : { case UT_VisibleString :
case UT_IA5String :
case UT_UTF8String : {
heim_general_string str; heim_general_string str;
ret = der_get_general_string (buf, length, &str, NULL); ret = der_get_general_string (buf, length, &str, NULL);

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -250,7 +252,7 @@ ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
| /* empty */ | /* empty */
; ;
ModuleBody : /* Exports */ Imports AssignmentList ModuleBody : Exports Imports AssignmentList
| /* empty */ | /* empty */
; ;
@@ -272,11 +274,22 @@ SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
for(sl = $1; sl != NULL; sl = sl->next) { for(sl = $1; sl != NULL; sl = sl->next) {
Symbol *s = addsym(sl->string); Symbol *s = addsym(sl->string);
s->stype = Stype; s->stype = Stype;
gen_template_import(s);
} }
add_import($3); 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 AssignmentList : Assignment
| Assignment AssignmentList | Assignment AssignmentList
; ;

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -197,7 +199,8 @@ generic_test (const struct test_case *tests,
int (*length)(void *), int (*length)(void *),
int (*decode)(unsigned char *, size_t, void *, size_t *), int (*decode)(unsigned char *, size_t, void *, size_t *),
int (*free_data)(void *), 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; unsigned char *buf, *buf2;
int i; int i;
@@ -210,6 +213,7 @@ generic_test (const struct test_case *tests,
for (i = 0; i < ntests; ++i) { for (i = 0; i < ntests; ++i) {
int ret; int ret;
size_t sz, consumed_sz, length_sz, buf_sz; size_t sz, consumed_sz, length_sz, buf_sz;
void *to = NULL;
current_test = tests[i].name; current_test = tests[i].name;
@@ -261,6 +265,11 @@ generic_test (const struct test_case *tests,
printf ("\nactual: "); printf ("\nactual: ");
print_bytes (buf, sz); print_bytes (buf, sz);
printf ("\n"); printf ("\n");
#if 0
rk_dumpdata("correct", tests[i].bytes, tests[i].byte_len);
rk_dumpdata("actual", buf, sz);
exit (1);
#endif
++failures; ++failures;
continue; continue;
} }
@@ -287,9 +296,33 @@ generic_test (const struct test_case *tests,
++failures; ++failures;
continue; 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"; current_state = "free";
if (free_data) if (free_data) {
(*free_data)(data); (*free_data)(data);
if (to) {
(*free_data)(to);
free(to);
}
}
current_state = "free"; current_state = "free";
map_free(buf_map, tests[i].name, "encode"); map_free(buf_map, tests[i].name, "encode");

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * 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_length)(void *);
typedef int (*generic_decode)(unsigned char *, size_t, void *, size_t *); typedef int (*generic_decode)(unsigned char *, size_t, void *, size_t *);
typedef int (*generic_free)(void *); typedef int (*generic_free)(void *);
typedef int (*generic_copy)(const void *, void *);
int int
generic_test (const struct test_case *tests, generic_test (const struct test_case *tests,
@@ -51,7 +54,8 @@ generic_test (const struct test_case *tests,
int (*length)(void *), int (*length)(void *),
int (*decode)(unsigned char *, size_t, void *, size_t *), int (*decode)(unsigned char *, size_t, void *, size_t *),
int (*free_data)(void *), int (*free_data)(void *),
int (*cmp)(void *a, void *b)); int (*cmp)(void *a, void *b),
int (*copy)(const void *a, void *b));
int int
generic_decode_fail(const struct test_case *tests, generic_decode_fail(const struct test_case *tests,

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -82,10 +84,11 @@ test_integer (void)
ret = generic_test (tests, ntests, sizeof(int), ret = generic_test (tests, ntests, sizeof(int),
(generic_encode)der_put_integer, (generic_encode)der_put_integer,
(generic_length) der_length_integer, (generic_length) der_length_integer,
(generic_decode)der_get_integer, (generic_decode)der_get_integer,
(generic_free)NULL, (generic_free)NULL,
cmp_integer); cmp_integer,
NULL);
for (i = 0; i < ntests; ++i) for (i = 0; i < ntests; ++i)
free (tests[i].name); free (tests[i].name);
@@ -207,7 +210,8 @@ test_unsigned (void)
(generic_length)der_length_unsigned, (generic_length)der_length_unsigned,
(generic_decode)der_get_unsigned, (generic_decode)der_get_unsigned,
(generic_free)NULL, (generic_free)NULL,
cmp_unsigned); cmp_unsigned,
NULL);
for (i = 0; i < ntests; ++i) for (i = 0; i < ntests; ++i)
free (tests[i].name); free (tests[i].name);
return ret; return ret;
@@ -246,7 +250,8 @@ test_octet_string (void)
(generic_length)der_length_octet_string, (generic_length)der_length_octet_string,
(generic_decode)der_get_octet_string, (generic_decode)der_get_octet_string,
(generic_free)der_free_octet_string, (generic_free)der_free_octet_string,
cmp_octet_string); cmp_octet_string,
NULL);
free(tests[0].name); free(tests[0].name);
return ret; return ret;
} }
@@ -290,7 +295,8 @@ test_bmp_string (void)
(generic_length)der_length_bmp_string, (generic_length)der_length_bmp_string,
(generic_decode)der_get_bmp_string, (generic_decode)der_get_bmp_string,
(generic_free)der_free_bmp_string, (generic_free)der_free_bmp_string,
cmp_bmp_string); cmp_bmp_string,
NULL);
free(tests[0].name); free(tests[0].name);
free(tests[1].name); free(tests[1].name);
return ret; return ret;
@@ -335,7 +341,8 @@ test_universal_string (void)
(generic_length)der_length_universal_string, (generic_length)der_length_universal_string,
(generic_decode)der_get_universal_string, (generic_decode)der_get_universal_string,
(generic_free)der_free_universal_string, (generic_free)der_free_universal_string,
cmp_universal_string); cmp_universal_string,
NULL);
free(tests[0].name); free(tests[0].name);
free(tests[1].name); free(tests[1].name);
return ret; return ret;
@@ -370,7 +377,8 @@ test_general_string (void)
(generic_length)der_length_general_string, (generic_length)der_length_general_string,
(generic_decode)der_get_general_string, (generic_decode)der_get_general_string,
(generic_free)der_free_general_string, (generic_free)der_free_general_string,
cmp_general_string); cmp_general_string,
NULL);
free(tests[0].name); free(tests[0].name);
return ret; return ret;
} }
@@ -407,7 +415,8 @@ test_generalized_time (void)
(generic_length)der_length_generalized_time, (generic_length)der_length_generalized_time,
(generic_decode)der_get_generalized_time, (generic_decode)der_get_generalized_time,
(generic_free)NULL, (generic_free)NULL,
cmp_generalized_time); cmp_generalized_time,
NULL);
for (i = 0; i < ntests; ++i) for (i = 0; i < ntests; ++i)
free(tests[i].name); free(tests[i].name);
return ret; return ret;
@@ -454,7 +463,8 @@ test_oid (void)
(generic_length)der_length_oid, (generic_length)der_length_oid,
(generic_decode)der_get_oid, (generic_decode)der_get_oid,
(generic_free)der_free_oid, (generic_free)der_free_oid,
test_cmp_oid); test_cmp_oid,
NULL);
for (i = 0; i < ntests; ++i) for (i = 0; i < ntests; ++i)
free(tests[i].name); free(tests[i].name);
return ret; return ret;
@@ -490,7 +500,8 @@ test_bit_string (void)
(generic_length)der_length_bit_string, (generic_length)der_length_bit_string,
(generic_decode)der_get_bit_string, (generic_decode)der_get_bit_string,
(generic_free)der_free_bit_string, (generic_free)der_free_bit_string,
test_cmp_bit_string); test_cmp_bit_string,
NULL);
for (i = 0; i < ntests; ++i) for (i = 0; i < ntests; ++i)
free(tests[i].name); free(tests[i].name);
return ret; return ret;
@@ -541,7 +552,8 @@ test_heim_integer (void)
(generic_length)der_length_heim_integer, (generic_length)der_length_heim_integer,
(generic_decode)der_get_heim_integer, (generic_decode)der_get_heim_integer,
(generic_free)der_free_heim_integer, (generic_free)der_free_heim_integer,
test_cmp_heim_integer); test_cmp_heim_integer,
NULL);
for (i = 0; i < ntests; ++i) for (i = 0; i < ntests; ++i)
free (tests[i].name); free (tests[i].name);
if (ret) if (ret)
@@ -590,7 +602,8 @@ test_boolean (void)
(generic_length)der_length_boolean, (generic_length)der_length_boolean,
(generic_decode)der_get_boolean, (generic_decode)der_get_boolean,
(generic_free)NULL, (generic_free)NULL,
test_cmp_boolean); test_cmp_boolean,
NULL);
for (i = 0; i < ntests; ++i) for (i = 0; i < ntests; ++i)
free (tests[i].name); free (tests[i].name);
if (ret) if (ret)

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * 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) do { if (strcmp((ac)->e, (bc)->e) != 0) return 1; } while(0)
#define COMPARE_INTEGER(ac,bc,e) \ #define COMPARE_INTEGER(ac,bc,e) \
do { if ((ac)->e != (bc)->e) return 1; } while(0) 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) \ #define COMPARE_MEM(ac,bc,e,len) \
do { if (memcmp((ac)->e, (bc)->e,len) != 0) return 1; } while(0) 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_length)length_Principal,
(generic_decode)decode_Principal, (generic_decode)decode_Principal,
(generic_free)free_Principal, (generic_free)free_Principal,
cmp_principal); cmp_principal,
NULL);
for (i = 0; i < ntests; ++i) for (i = 0; i < ntests; ++i)
free (tests[i].name); free (tests[i].name);
@@ -194,7 +199,8 @@ test_authenticator (void)
(generic_length)length_Authenticator, (generic_length)length_Authenticator,
(generic_decode)decode_Authenticator, (generic_decode)decode_Authenticator,
(generic_free)free_Authenticator, (generic_free)free_Authenticator,
cmp_authenticator); cmp_authenticator,
(generic_copy)copy_Authenticator);
for (i = 0; i < ntests; ++i) for (i = 0; i < ntests; ++i)
free(tests[i].name); free(tests[i].name);
@@ -288,7 +294,8 @@ test_krb_error (void)
(generic_length)length_KRB_ERROR, (generic_length)length_KRB_ERROR,
(generic_decode)decode_KRB_ERROR, (generic_decode)decode_KRB_ERROR,
(generic_free)free_KRB_ERROR, (generic_free)free_KRB_ERROR,
cmp_KRB_ERROR); cmp_KRB_ERROR,
(generic_copy)copy_KRB_ERROR);
} }
static int static int
@@ -372,7 +379,8 @@ test_Name (void)
(generic_length)length_Name, (generic_length)length_Name,
(generic_decode)decode_Name, (generic_decode)decode_Name,
(generic_free)free_Name, (generic_free)free_Name,
cmp_Name); cmp_Name,
(generic_copy)copy_Name);
} }
static int static int
@@ -431,9 +439,226 @@ test_bit_string (void)
(generic_length)length_KeyUsage, (generic_length)length_KeyUsage,
(generic_decode)decode_KeyUsage, (generic_decode)decode_KeyUsage,
(generic_free)free_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 = &times[0];
tests[1].val = &times[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 static int
cmp_TESTLargeTag (void *a, void *b) cmp_TESTLargeTag (void *a, void *b)
{ {
@@ -441,6 +666,7 @@ cmp_TESTLargeTag (void *a, void *b)
TESTLargeTag *ab = b; TESTLargeTag *ab = b;
COMPARE_INTEGER(aa,ab,foo); COMPARE_INTEGER(aa,ab,foo);
COMPARE_INTEGER(aa,ab,bar);
return 0; return 0;
} }
@@ -448,7 +674,7 @@ static int
test_large_tag (void) test_large_tag (void)
{ {
struct test_case tests[] = { 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); int ntests = sizeof(tests) / sizeof(*tests);
@@ -456,6 +682,7 @@ test_large_tag (void)
memset(&lt1, 0, sizeof(lt1)); memset(&lt1, 0, sizeof(lt1));
lt1.foo = 1; lt1.foo = 1;
lt1.bar = 2;
tests[0].val = &lt1; tests[0].val = &lt1;
@@ -464,7 +691,8 @@ test_large_tag (void)
(generic_length)length_TESTLargeTag, (generic_length)length_TESTLargeTag,
(generic_decode)decode_TESTLargeTag, (generic_decode)decode_TESTLargeTag,
(generic_free)free_TESTLargeTag, (generic_free)free_TESTLargeTag,
cmp_TESTLargeTag); cmp_TESTLargeTag,
(generic_copy)copy_TESTLargeTag);
} }
struct test_data { struct test_data {
@@ -490,9 +718,9 @@ check_tag_length(void)
{ 0, 5, 0, "\x02\xff\x7f\x02\x00"} { 0, 5, 0, "\x02\xff\x7f\x02\x00"}
}; };
size_t sz; size_t sz;
krb5uint32 values[] = {0, 127, 128, 256, 512, TESTuint32 values[] = {0, 127, 128, 256, 512,
0, 127, 128, 256, 512 }; 0, 127, 128, 256, 512 };
krb5uint32 u; TESTuint32 u;
int i, ret, failed = 0; int i, ret, failed = 0;
void *buf; void *buf;
@@ -501,7 +729,7 @@ check_tag_length(void)
buf = map_alloc(OVERRUN, td[i].data, td[i].len, &page); 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 (ret) {
if (td[i].ok) { if (td[i].ok) {
printf("failed with tag len test %d\n", i); printf("failed with tag len test %d\n", i);
@@ -560,7 +788,8 @@ test_choice (void)
(generic_length)length_TESTChoice1, (generic_length)length_TESTChoice1,
(generic_decode)decode_TESTChoice1, (generic_decode)decode_TESTChoice1,
(generic_free)free_TESTChoice1, (generic_free)free_TESTChoice1,
cmp_TESTChoice); cmp_TESTChoice,
(generic_copy)copy_TESTChoice1);
memset(&c2_2, 0, sizeof(c2_2)); memset(&c2_2, 0, sizeof(c2_2));
c2_2.element = choice_TESTChoice2_asn1_ellipsis; c2_2.element = choice_TESTChoice2_asn1_ellipsis;
@@ -573,7 +802,8 @@ test_choice (void)
(generic_length)length_TESTChoice2, (generic_length)length_TESTChoice2,
(generic_decode)decode_TESTChoice2, (generic_decode)decode_TESTChoice2,
(generic_free)free_TESTChoice2, (generic_free)free_TESTChoice2,
cmp_TESTChoice); cmp_TESTChoice,
(generic_copy)copy_TESTChoice2);
return ret; return ret;
} }
@@ -623,7 +853,8 @@ test_implicit (void)
(generic_length)length_TESTImplicit, (generic_length)length_TESTImplicit,
(generic_decode)decode_TESTImplicit, (generic_decode)decode_TESTImplicit,
(generic_free)free_TESTImplicit, (generic_free)free_TESTImplicit,
cmp_TESTImplicit); cmp_TESTImplicit,
(generic_copy)copy_TESTImplicit);
#ifdef IMPLICIT_TAGGING_WORKS #ifdef IMPLICIT_TAGGING_WORKS
ret += generic_test (tests, ntests, sizeof(TESTImplicit2), ret += generic_test (tests, ntests, sizeof(TESTImplicit2),
@@ -631,7 +862,8 @@ test_implicit (void)
(generic_length)length_TESTImplicit2, (generic_length)length_TESTImplicit2,
(generic_decode)decode_TESTImplicit2, (generic_decode)decode_TESTImplicit2,
(generic_free)free_TESTImplicit2, (generic_free)free_TESTImplicit2,
cmp_TESTImplicit); cmp_TESTImplicit,
NULL);
#endif /* IMPLICIT_TAGGING_WORKS */ #endif /* IMPLICIT_TAGGING_WORKS */
return ret; return ret;
@@ -718,13 +950,95 @@ test_taglessalloc (void)
(generic_length)length_TESTAlloc, (generic_length)length_TESTAlloc,
(generic_decode)decode_TESTAlloc, (generic_decode)decode_TESTAlloc,
(generic_free)free_TESTAlloc, (generic_free)free_TESTAlloc,
cmp_TESTAlloc); cmp_TESTAlloc,
(generic_copy)copy_TESTAlloc);
free(c1.tagless); free(c1.tagless);
return ret; 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 static int
check_fail_largetag(void) check_fail_largetag(void)
@@ -793,10 +1107,10 @@ check_fail_choice(void)
struct test_case tests[] = { struct test_case tests[] = {
{NULL, 6, {NULL, 6,
"\xa1\x02\x02\x01\x01", "\xa1\x02\x02\x01\x01",
"one too short"}, "choice one too short"},
{NULL, 6, {NULL, 6,
"\xa1\x03\x02\x02\x01", "\xa1\x03\x02\x02\x01",
"one too short inner"} "choice one too short inner"}
}; };
int ntests = sizeof(tests) / sizeof(*tests); int ntests = sizeof(tests) / sizeof(*tests);
@@ -877,6 +1191,7 @@ out:
static int static int
check_seq_of_size(void) check_seq_of_size(void)
{ {
#if 0 /* template */
TESTInteger integers[4] = { 1, 2, 3, 4 }; TESTInteger integers[4] = { 1, 2, 3, 4 };
int ret; int ret;
@@ -920,12 +1235,10 @@ check_seq_of_size(void)
test_seq_of(TESTSeqSizeOf4, 1, &ssof4ok3); test_seq_of(TESTSeqSizeOf4, 1, &ssof4ok3);
test_seq_of(TESTSeqSizeOf4, 0, &ssof4f1); test_seq_of(TESTSeqSizeOf4, 0, &ssof4f1);
} }
#endif
return 0; return 0;
} }
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@@ -936,6 +1249,9 @@ main(int argc, char **argv)
ret += test_krb_error(); ret += test_krb_error();
ret += test_Name(); ret += test_Name();
ret += test_bit_string(); ret += test_bit_string();
ret += test_bit_string_rfc1510();
ret += test_time();
ret += test_cert();
ret += check_tag_length(); ret += check_tag_length();
ret += test_large_tag(); ret += test_large_tag();
@@ -943,6 +1259,7 @@ main(int argc, char **argv)
ret += test_implicit(); ret += test_implicit();
ret += test_taglessalloc(); ret += test_taglessalloc();
ret += test_optional();
ret += check_fail_largetag(); ret += check_fail_largetag();
ret += check_fail_sequence(); ret += check_fail_sequence();

255
lib/asn1/check-template.c Normal file
View 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;
}

View File

@@ -4,7 +4,7 @@
CMS DEFINITIONS ::= BEGIN CMS DEFINITIONS ::= BEGIN
IMPORTS CertificateSerialNumber, AlgorithmIdentifier, Name, IMPORTS CertificateSerialNumber, AlgorithmIdentifier, Name,
Attribute, Certificate, Name, SubjectKeyIdentifier FROM rfc2459 Attribute, Certificate, SubjectKeyIdentifier FROM rfc2459
heim_any, heim_any_set FROM heim; heim_any, heim_any_set FROM heim;
id-pkcs7 OBJECT IDENTIFIER ::= { iso(1) member-body(2) id-pkcs7 OBJECT IDENTIFIER ::= { iso(1) member-body(2)

View File

@@ -94,6 +94,8 @@ typedef struct heim_ber_time_t {
int bt_zone; int bt_zone;
} heim_ber_time_t; } heim_ber_time_t;
struct asn1_template;
#include <der-protos.h> #include <der-protos.h>
int _heim_fix_dce(size_t reallen, size_t *len); int _heim_fix_dce(size_t reallen, size_t *len);

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -45,6 +47,34 @@ der_copy_general_string (const heim_general_string *from,
return 0; 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 int
der_copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to) der_copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
{ {

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -42,6 +44,31 @@ der_free_general_string (heim_general_string *str)
*str = NULL; *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 void
der_free_utf8string (heim_utf8_string *str) der_free_utf8string (heim_utf8_string *str)
{ {

View File

@@ -305,7 +305,7 @@ der_get_octet_string_ber (const unsigned char *p, size_t len,
void *ptr; void *ptr;
ptr = realloc(data->data, data->length + datalen); ptr = realloc(data->data, data->length + datalen);
if (ptr == NULL && data->length + datalen != 0) { if (ptr == NULL) {
e = ENOMEM; e = ENOMEM;
goto out; goto out;
} }
@@ -354,23 +354,21 @@ der_get_heim_integer (const unsigned char *p, size_t len,
p++; p++;
data->length--; data->length--;
} }
if (data->length) { data->data = malloc(data->length);
data->data = malloc(data->length); if (data->data == NULL) {
if (data->data == NULL) { data->length = 0;
data->length = 0; if (size)
if (size) *size = 0;
*size = 0; return ENOMEM;
return ENOMEM; }
} q = &((unsigned char*)data->data)[data->length - 1];
q = &((unsigned char*)data->data)[data->length - 1]; p += data->length - 1;
p += data->length - 1; while (q >= (unsigned char*)data->data) {
while (q >= (unsigned char*)data->data) { *q = *p ^ 0xff;
*q = *p ^ 0xff; if (carry)
if (carry) carry = !++*q;
carry = !++*q; p--;
p--; q--;
q--;
}
} }
} else { } else {
data->negative = 0; data->negative = 0;

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * 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 size_t
der_length_integer (const int *data) der_length_integer (const int *data)
{ {

View File

@@ -52,6 +52,8 @@
#include <asn1-common.h> #include <asn1-common.h>
#include <asn1_err.h> #include <asn1_err.h>
#include <der.h> #include <der.h>
#include <der-private.h>
#include "asn1-template.h"
time_t _der_timegm (struct tm *); time_t _der_timegm (struct tm *);
size_t _heim_len_unsigned (unsigned); size_t _heim_len_unsigned (unsigned);

View File

@@ -100,6 +100,21 @@ NTLMResponse ::= SEQUENCE {
tickets [3] SEQUENCE OF OCTET STRING OPTIONAL 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 { DigestReqInner ::= CHOICE {
init [0] DigestInit, init [0] DigestInit,
digestRequest [1] DigestRequest, digestRequest [1] DigestRequest,

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -40,13 +42,7 @@ int
encode_heim_any(unsigned char *p, size_t len, encode_heim_any(unsigned char *p, size_t len,
const heim_any *data, size_t *size) const heim_any *data, size_t *size)
{ {
if (data->length > len) return der_put_octet_string (p, len, data, size);
return ASN1_OVERFLOW;
p -= data->length;
len -= data->length;
memcpy (p+1, data->data, data->length);
*size = data->length;
return 0;
} }
int int
@@ -91,8 +87,7 @@ decode_heim_any(const unsigned char *p, size_t len,
void void
free_heim_any(heim_any *data) free_heim_any(heim_any *data)
{ {
free(data->data); der_free_octet_string(data);
data->data = NULL;
} }
size_t size_t
@@ -104,58 +99,43 @@ length_heim_any(const heim_any *data)
int int
copy_heim_any(const heim_any *from, heim_any *to) copy_heim_any(const heim_any *from, heim_any *to)
{ {
to->data = malloc(from->length); return der_copy_octet_string(from, to);
if (to->data == NULL && from->length != 0)
return ENOMEM;
memcpy(to->data, from->data, from->length);
to->length = from->length;
return 0;
} }
int int
encode_heim_any_set(unsigned char *p, size_t len, encode_heim_any_set(unsigned char *p, size_t len,
const heim_any_set *data, size_t *size) 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 int
decode_heim_any_set(const unsigned char *p, size_t len, decode_heim_any_set(const unsigned char *p, size_t len,
heim_any_set *data, size_t *size) heim_any_set *data, size_t *size)
{ {
memset(data, 0, sizeof(*data)); return der_get_octet_string(p, len, data, size);
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;
} }
void void
free_heim_any_set(heim_any_set *data) free_heim_any_set(heim_any_set *data)
{ {
free_heim_any(data); der_free_octet_string(data);
} }
size_t size_t
length_heim_any_set(const heim_any *data) length_heim_any_set(const heim_any *data)
{ {
return length_heim_any(data); return data->length;
} }
int int
copy_heim_any_set(const heim_any_set *from, heim_any_set *to) 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 int
heim_any_cmp(const heim_any_set *p, const heim_any_set *q) heim_any_cmp(const heim_any_set *p, const heim_any_set *q)
{ {
if (p->length != q->length) return der_heim_octet_string_cmp(p, q);
return p->length - q->length;
return memcmp(p->data, q->data, p->length);
} }

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -35,12 +37,12 @@
RCSID("$Id$"); RCSID("$Id$");
FILE *headerfile, *codefile, *logfile; FILE *privheaderfile, *headerfile, *codefile, *logfile, *templatefile;
#define STEM "asn1" #define STEM "asn1"
static const char *orig_filename; static const char *orig_filename;
static char *header; static char *privheader, *header, *template;
static const char *headerbase = STEM; static const char *headerbase = STEM;
/* /*
@@ -66,6 +68,45 @@ add_import (const char *module)
fprintf (headerfile, "#include <%s_asn1.h>\n", 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 * const char *
get_filename (void) get_filename (void)
{ {
@@ -96,6 +137,23 @@ init_generate (const char *filename, const char *base)
err (1, "open %s", fn); err (1, "open %s", fn);
free(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, fprintf (headerfile,
"/* Generated from %s */\n" "/* Generated from %s */\n"
"/* Do not edit */\n\n", "/* Do not edit */\n\n",
@@ -182,6 +240,36 @@ init_generate (const char *filename, const char *base)
logfile = fopen(fn, "w"); logfile = fopen(fn, "w");
if (logfile == NULL) if (logfile == NULL)
err (1, "open %s", fn); 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 void
@@ -190,6 +278,8 @@ close_generate (void)
fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase); fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase);
fclose (headerfile); fclose (headerfile);
fclose (privheaderfile);
fclose (templatefile);
fprintf (logfile, "\n"); fprintf (logfile, "\n");
fclose (logfile); fclose (logfile);
} }
@@ -265,11 +355,14 @@ generate_header_of_codefile(const char *name)
orig_filename); orig_filename);
fprintf (codefile, fprintf (codefile,
"#include <%s.h>\n", "#include <%s>\n"
headerbase); "#include <%s>\n",
header, privheader);
fprintf (codefile, fprintf (codefile,
"#include <asn1_err.h>\n" "#include <asn1_err.h>\n"
"#include <der.h>\n" "#include <der.h>\n"
"#include <der-private.h>\n"
"#include <asn1-template.h>\n"
"#include <parse_units.h>\n\n"); "#include <parse_units.h>\n\n");
} }
@@ -328,8 +421,6 @@ generate_constant (const Symbol *s)
} }
fprintf (headerfile, "} */\n"); fprintf (headerfile, "} */\n");
fprintf (headerfile, "const heim_oid *oid_%s(void);\n",
s->gen_name);
fprintf (headerfile, fprintf (headerfile,
"extern const heim_oid asn1_oid_%s;\n\n", "extern const heim_oid asn1_oid_%s;\n\n",
s->gen_name); s->gen_name);
@@ -346,12 +437,6 @@ generate_constant (const Symbol *s)
"{ %d, oid_%s_variable_num };\n\n", "{ %d, oid_%s_variable_num };\n\n",
s->gen_name, len, s->gen_name); 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); free(list);
if (!one_code_file) 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 static void
space(int level) space(int level)
{ {
@@ -550,8 +662,24 @@ define_asn1 (int level, Type *t)
} }
static void 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) { switch (t->type) {
case TType: case TType:
space(level); 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)) if(ASN1_TAILQ_EMPTY(t->members))
fprintf (headerfile, "heim_bit_string %s;\n", name); fprintf (headerfile, "heim_bit_string %s;\n", name);
else { 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) { ASN1_TAILQ_FOREACH(m, t->members, members) {
char *n; 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); asprintf (&n, "%s:1", m->gen_name);
if (n == NULL) if (n == NULL)
errx(1, "malloc"); errx(1, "malloc");
define_type (level + 1, n, &i, FALSE, FALSE); define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
free (n); 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); space(level);
fprintf (headerfile, "} %s;\n\n", name); 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: { case TSequence: {
Member *m; Member *m;
getnewbasename(&newbasename, typedefp, basename, name);
space(level); space(level);
fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); fprintf (headerfile, "struct %s {\n", newbasename);
if (t->type == TSequence && preservep) { if (t->type == TSequence && preservep) {
space(level + 1); space(level + 1);
fprintf(headerfile, "heim_octet_string _save;\n"); 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); asprintf (&n, "*%s", m->gen_name);
if (n == NULL) if (n == NULL)
errx(1, "malloc"); errx(1, "malloc");
define_type (level + 1, n, m->type, FALSE, FALSE); define_type (level + 1, n, newbasename, m->type, FALSE, FALSE);
free (n); free (n);
} else } 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); space(level);
fprintf (headerfile, "} %s;\n", name); fprintf (headerfile, "} %s;\n", name);
@@ -667,15 +818,17 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
Type i; Type i;
struct range range = { 0, INT_MAX }; struct range range = { 0, INT_MAX };
getnewbasename(&newbasename, typedefp, basename, name);
i.type = TInteger; i.type = TInteger;
i.range = &range; i.range = &range;
i.members = NULL; i.members = NULL;
i.constraint = NULL; i.constraint = NULL;
space(level); space(level);
fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); fprintf (headerfile, "struct %s {\n", newbasename);
define_type (level + 1, "len", &i, FALSE, FALSE); define_type (level + 1, "len", newbasename, &i, FALSE, FALSE);
define_type (level + 1, "*val", t->subtype, FALSE, FALSE); define_type (level + 1, "*val", newbasename, t->subtype, FALSE, FALSE);
space(level); space(level);
fprintf (headerfile, "} %s;\n", name); fprintf (headerfile, "} %s;\n", name);
break; 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); fprintf (headerfile, "heim_general_string %s;\n", name);
break; break;
case TTag: case TTag:
define_type (level, name, t->subtype, typedefp, preservep); define_type (level, name, basename, t->subtype, typedefp, preservep);
break; break;
case TChoice: { case TChoice: {
int first = 1; int first = 1;
Member *m; Member *m;
getnewbasename(&newbasename, typedefp, basename, name);
space(level); space(level);
fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); fprintf (headerfile, "struct %s {\n", newbasename);
if (preservep) { if (preservep) {
space(level + 1); space(level + 1);
fprintf(headerfile, "heim_octet_string _save;\n"); 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); asprintf (&n, "*%s", m->gen_name);
if (n == NULL) if (n == NULL)
errx(1, "malloc"); errx(1, "malloc");
define_type (level + 2, n, m->type, FALSE, FALSE); define_type (level + 2, n, newbasename, m->type, FALSE, FALSE);
free (n); free (n);
} else } 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); space(level + 1);
fprintf (headerfile, "} u;\n"); fprintf (headerfile, "} u;\n");
@@ -787,6 +942,8 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
default: default:
abort (); abort ();
} }
if (newbasename)
free(newbasename);
} }
static void static void
@@ -800,27 +957,61 @@ generate_type_header (const Symbol *s)
fprintf (headerfile, "\n*/\n\n"); fprintf (headerfile, "\n*/\n\n");
fprintf (headerfile, "typedef "); 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"); fprintf (headerfile, "\n");
} }
void void
generate_type (const Symbol *s) generate_type (const Symbol *s)
{ {
FILE *h;
if (!one_code_file) if (!one_code_file)
generate_header_of_codefile(s->gen_name); generate_header_of_codefile(s->gen_name);
generate_type_header (s); generate_type_header (s);
generate_type_encode (s);
generate_type_decode (s); if (template_flag)
generate_type_free (s); generate_template(s);
generate_type_length (s);
generate_type_copy (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_type_seq (s);
generate_glue (s->type, s->gen_name); 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) { if (!one_code_file) {
fprintf(codefile, "\n\n"); fprintf(codefile, "\n\n");

View File

@@ -228,10 +228,6 @@ generate_type_copy (const Symbol *s)
used_fail = 0; 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" fprintf (codefile, "int\n"
"copy_%s(const %s *from, %s *to)\n" "copy_%s(const %s *from, %s *to)\n"
"{\n" "{\n"

View File

@@ -56,33 +56,6 @@ decode_primitive (const char *typename, const char *name, const char *forwstr)
#endif #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 static void
find_tag (const Type *t, find_tag (const Type *t,
Der_class *cl, Der_type *ty, unsigned *tag) Der_class *cl, Der_type *ty, unsigned *tag)
@@ -630,7 +603,7 @@ decode_type (const char *name, const Type *t, int optional,
fprintf(codefile, fprintf(codefile,
"else {\n" "else {\n"
"(%s)->u.%s.data = calloc(1, len);\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" "e = ENOMEM; %s;\n"
"}\n" "}\n"
"(%s)->u.%s.length = len;\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; 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" fprintf (codefile, "int\n"
"decode_%s(const unsigned char *p," "decode_%s(const unsigned char *p,"
" size_t len, %s *data, size_t *size)\n" " size_t len, %s *data, size_t *size)\n"
@@ -744,7 +712,7 @@ generate_type_decode (const Symbol *s)
if (preserve) if (preserve)
fprintf (codefile, fprintf (codefile,
"data->_save.data = calloc(1, ret);\n" "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" "e = ENOMEM; goto fail; \n"
"}\n" "}\n"
"data->_save.length = ret;\n" "data->_save.length = ret;\n"

View File

@@ -508,11 +508,6 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
void void
generate_type_encode (const Symbol *s) 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" fprintf (codefile, "int\n"
"encode_%s(unsigned char *p, size_t len," "encode_%s(unsigned char *p, size_t len,"
" const %s *data, size_t *size)\n" " const %s *data, size_t *size)\n"

View File

@@ -180,18 +180,14 @@ free_type (const char *name, const Type *t, int preserve)
void void
generate_type_free (const Symbol *s) generate_type_free (const Symbol *s)
{ {
int preserve = preserve_type(s->name) ? TRUE : FALSE; int preserve = preserve_type(s->name) ? TRUE : FALSE;
fprintf (headerfile, fprintf (codefile, "void\n"
"void free_%s (%s *);\n", "free_%s(%s *data)\n"
s->gen_name, s->gen_name); "{\n",
s->gen_name, s->gen_name);
fprintf (codefile, "void\n"
"free_%s(%s *data)\n" free_type ("data", s->type, preserve);
"{\n", fprintf (codefile, "}\n\n");
s->gen_name, s->gen_name);
free_type ("data", s->type, preserve);
fprintf (codefile, "}\n\n");
} }

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -70,7 +72,8 @@ generate_int2 (const Type *t, const char *gen_name)
fprintf (codefile, fprintf (codefile,
"%s int2%s(unsigned n)\n" "%s int2%s(unsigned n)\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); gen_name, gen_name, gen_name);
if(t->members) { if(t->members) {
@@ -92,9 +95,17 @@ generate_units (const Type *t, const char *gen_name)
{ {
Member *m; Member *m;
fprintf (headerfile, if (template_flag) {
"const struct units * asn1_%s_units(void);", fprintf (headerfile,
gen_name); "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, fprintf (codefile,
"static struct units %s_units[] = {\n", "static struct units %s_units[] = {\n",
@@ -111,11 +122,16 @@ generate_units (const Type *t, const char *gen_name)
"\t{NULL,\t0}\n" "\t{NULL,\t0}\n"
"};\n\n"); "};\n\n");
fprintf (codefile, if (template_flag)
"const struct units * asn1_%s_units(void){\n" fprintf (codefile,
"return %s_units;\n" "const struct units * asn1_%s_table_units = %s_units;\n",
"}\n\n", gen_name, gen_name);
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);
} }

View File

@@ -43,6 +43,7 @@ length_primitive (const char *typename,
fprintf (codefile, "%s += der_length_%s(%s);\n", variable, typename, name); fprintf (codefile, "%s += der_length_%s(%s);\n", variable, typename, name);
} }
/* XXX same as der_length_tag */
static size_t static size_t
length_tag(unsigned int tag) length_tag(unsigned int tag)
{ {
@@ -269,10 +270,6 @@ length_type (const char *name, const Type *t,
void void
generate_type_length (const Symbol *s) generate_type_length (const Symbol *s)
{ {
fprintf (headerfile,
"size_t length_%s(const %s *);\n",
s->gen_name, s->gen_name);
fprintf (codefile, fprintf (codefile,
"size_t\n" "size_t\n"
"length_%s(const %s *data)\n" "length_%s(const %s *data)\n"

View File

@@ -52,6 +52,7 @@
#include "symbol.h" #include "symbol.h"
#include "asn1-common.h" #include "asn1-common.h"
#include "der.h" #include "der.h"
#include "der-private.h"
void generate_type (const Symbol *); void generate_type (const Symbol *);
void generate_constant (const Symbol *); void generate_constant (const Symbol *);
@@ -74,7 +75,10 @@ void init_generate (const char *, const char *);
const char *get_filename (void); const char *get_filename (void);
void close_generate(void); void close_generate(void);
void add_import(const char *); void add_import(const char *);
void add_export(const char *);
int is_export(const char *);
int yyparse(void); int yyparse(void);
int is_primitive_type(int);
int preserve_type(const char *); int preserve_type(const char *);
int seq_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 generate_header_of_codefile(const char *);
void close_codefile(void); 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 support_ber;
extern int template_flag;
extern int rfc1510_bitstring; extern int rfc1510_bitstring;
extern int one_code_file; extern int one_code_file;

894
lib/asn1/gen_template.c Normal file
View 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);
}

View File

@@ -2,6 +2,78 @@
KERBEROS5 DEFINITIONS ::= KERBEROS5 DEFINITIONS ::=
BEGIN 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 { NAME-TYPE ::= INTEGER {
KRB5_NT_UNKNOWN(0), -- Name type not known KRB5_NT_UNKNOWN(0), -- Name type not known
@@ -256,11 +328,7 @@ KDCOptions ::= BIT STRING {
proxy(4), proxy(4),
allow-postdate(5), allow-postdate(5),
postdated(6), postdated(6),
unused7(7),
renewable(8), renewable(8),
unused9(9),
unused10(10),
unused11(11),
request-anonymous(14), request-anonymous(14),
canonicalize(15), canonicalize(15),
constrained-delegation(16), -- ms extension constrained-delegation(16), -- ms extension

View File

@@ -63,12 +63,14 @@ seq_type(const char *p)
} }
int support_ber; int support_ber;
int template_flag;
int rfc1510_bitstring; int rfc1510_bitstring;
int one_code_file; int one_code_file;
char *option_file; char *option_file;
int version_flag; int version_flag;
int help_flag; int help_flag;
struct getargs args[] = { struct getargs args[] = {
{ "template", 0, arg_flag, &template_flag },
{ "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring }, { "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
{ "decode-dce-ber", 0, arg_flag, &support_ber }, { "decode-dce-ber", 0, arg_flag, &support_ber },
{ "support-ber", 0, arg_flag, &support_ber }, { "support-ber", 0, arg_flag, &support_ber },

6
lib/asn1/rfc2459.opt Normal file
View File

@@ -0,0 +1,6 @@
--preserve-binary=TBSCertificate
--preserve-binary=TBSCRLCertList
--preserve-binary=Name
--sequence=GeneralNames
--sequence=Extensions
--sequence=CRLDistributionPoints

View File

@@ -34,8 +34,6 @@
#include "gen_locl.h" #include "gen_locl.h"
#include "lex.h" #include "lex.h"
RCSID("$Id$");
static Hashtab *htab; static Hashtab *htab;
static int static int
@@ -68,7 +66,7 @@ output_name(char *s)
char *p; char *p;
for (p = s; *p; ++p) for (p = s; *p; ++p)
if (*p == '-') if (*p == '-' || *p == '.')
*p = '_'; *p = '_';
} }

1119
lib/asn1/template.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,8 +6,11 @@ BEGIN
IMPORTS heim_any FROM heim; IMPORTS heim_any FROM heim;
TESTuint32 ::= INTEGER (0..4294967295)
TESTLargeTag ::= SEQUENCE { TESTLargeTag ::= SEQUENCE {
foo[127] INTEGER (-2147483648..2147483647) foo[127] INTEGER (-2147483648..2147483647),
bar[128] INTEGER (-2147483648..2147483647)
} }
TESTSeq ::= SEQUENCE { TESTSeq ::= SEQUENCE {
@@ -57,6 +60,11 @@ TESTAlloc ::= SEQUENCE {
tagless2 heim_any OPTIONAL tagless2 heim_any OPTIONAL
} }
TESTOptional ::= SEQUENCE {
zero [0] INTEGER (-2147483648..2147483647) OPTIONAL,
one [1] INTEGER (-2147483648..2147483647) OPTIONAL
}
TESTCONTAINING ::= OCTET STRING ( CONTAINING INTEGER ) TESTCONTAINING ::= OCTET STRING ( CONTAINING INTEGER )
TESTENCODEDBY ::= OCTET STRING ( ENCODED BY TESTENCODEDBY ::= OCTET STRING ( ENCODED BY
@@ -92,4 +100,36 @@ TESTSeqSizeOf4 ::= SEQUENCE SIZE (MIN..2) OF TESTInteger
TESTOSSize1 ::= OCTET STRING SIZE (1..2) 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 END